Use Cloudflare Email Send for OTP
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { describe, it } from "node:test";
|
||||
|
||||
import type { ElyEmailMessageBuilder, Env } from "../src/bindings.js";
|
||||
import { handleRequest } from "../src/index.js";
|
||||
|
||||
describe("better auth email otp", () => {
|
||||
it("sends OTP through Cloudflare Email Send", async () => {
|
||||
const sentEmails: ElyEmailMessageBuilder[] = [];
|
||||
const response = await handleRequest(otpRequest("USER@example.com"), testEnv(sentEmails));
|
||||
|
||||
assert.equal(response.status, 200);
|
||||
assert.deepEqual(await response.json(), { success: true });
|
||||
assert.equal(sentEmails.length, 1);
|
||||
|
||||
const email = sentEmails[0]!;
|
||||
assert.equal(email.to, "user@example.com");
|
||||
assert.deepEqual(email.from, { email: "auth@elydora.com", name: "ELY Browser" });
|
||||
assert.equal(email.subject, "Your ELY Browser sign-in code");
|
||||
assert.match(email.text ?? "", /Your ELY Browser sign-in code is \d{6}\./);
|
||||
assert.match(email.html ?? "", /<strong[^>]*>\d{6}<\/strong>/);
|
||||
});
|
||||
|
||||
it("fails closed when the email send binding is unavailable", async () => {
|
||||
const response = await handleRequest(otpRequest("user@example.com"), testEnv(null));
|
||||
|
||||
assert.equal(response.status, 500);
|
||||
assert.deepEqual(await response.json(), { error: "auth_unconfigured" });
|
||||
});
|
||||
});
|
||||
|
||||
function otpRequest(email: string): Request {
|
||||
return new Request("https://elydora.test/api/auth/email-otp/send-verification-otp", {
|
||||
method: "POST",
|
||||
headers: { "content-type": "application/json" },
|
||||
body: JSON.stringify({ email, type: "sign-in" }),
|
||||
});
|
||||
}
|
||||
|
||||
function testEnv(sentEmails: ElyEmailMessageBuilder[] | null): Env {
|
||||
const env: Env = {
|
||||
ELY_ENVIRONMENT: "local",
|
||||
ELY_AUTH_BASE_URL: "https://elydora.test",
|
||||
ELY_AUTH_SECRET: "8b7f1d2b0c9a4e3f91d6c0a45e72b8f3",
|
||||
ELY_DB: testD1Database(),
|
||||
ELY_KV: {
|
||||
get() {
|
||||
return Promise.resolve(null);
|
||||
},
|
||||
delete() {
|
||||
return Promise.resolve();
|
||||
},
|
||||
},
|
||||
ELY_STORAGE: {
|
||||
get() {
|
||||
return Promise.resolve(null);
|
||||
},
|
||||
put() {
|
||||
return Promise.resolve({
|
||||
arrayBuffer() {
|
||||
return Promise.resolve(new ArrayBuffer(0));
|
||||
},
|
||||
});
|
||||
},
|
||||
delete() {
|
||||
return Promise.resolve();
|
||||
},
|
||||
},
|
||||
ELY_RATE_LIMITER: {
|
||||
limit() {
|
||||
return Promise.resolve({ success: true });
|
||||
},
|
||||
},
|
||||
ELY_API_AUDIT: {
|
||||
writeDataPoint(): void {},
|
||||
},
|
||||
ELY_DIAGNOSTICS: {
|
||||
writeDataPoint(): void {},
|
||||
},
|
||||
};
|
||||
|
||||
if (sentEmails !== null) {
|
||||
env.SEND_EMAIL = {
|
||||
send(message: ElyEmailMessageBuilder) {
|
||||
sentEmails.push(message);
|
||||
return Promise.resolve({ messageId: "test-message-id" });
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
function testD1Database(): Env["ELY_DB"] {
|
||||
return {
|
||||
prepare() {
|
||||
return {
|
||||
bind() {
|
||||
return this;
|
||||
},
|
||||
first() {
|
||||
return Promise.resolve(null);
|
||||
},
|
||||
all() {
|
||||
return Promise.resolve({ results: [], meta: { changes: 1, last_row_id: 1 } });
|
||||
},
|
||||
run() {
|
||||
return Promise.resolve({});
|
||||
},
|
||||
};
|
||||
},
|
||||
batch() {
|
||||
return Promise.resolve([]);
|
||||
},
|
||||
exec() {
|
||||
return Promise.resolve({});
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user