114 lines
3.2 KiB
JavaScript
114 lines
3.2 KiB
JavaScript
const assert = require("node:assert/strict");
|
|
const fs = require("node:fs");
|
|
const path = require("node:path");
|
|
const test = require("node:test");
|
|
const vm = require("node:vm");
|
|
|
|
const root = path.resolve(__dirname, "../..");
|
|
|
|
const source = fs.readFileSync(
|
|
path.join(root, "lib/auth/email-provider.js"),
|
|
"utf8"
|
|
);
|
|
|
|
const EmailProvider = vm.runInNewContext(
|
|
source.replace("export default EmailProvider;", "") + "\nEmailProvider;",
|
|
{}
|
|
);
|
|
|
|
const OriginalEmailProvider = require("next-auth/providers/email").default;
|
|
|
|
const customSender = async () => {};
|
|
|
|
const options = {
|
|
maxAge: 2 * 60 * 60,
|
|
sendVerificationRequest: customSender
|
|
};
|
|
|
|
const normalize = (provider) => {
|
|
const { options: userOptions, ...defaults } = provider;
|
|
|
|
return {
|
|
...defaults,
|
|
...userOptions
|
|
};
|
|
};
|
|
|
|
test("local provider preserves NextAuth email provider defaults", () => {
|
|
const original = OriginalEmailProvider(options);
|
|
const replacement = EmailProvider(options);
|
|
|
|
for (const property of ["id", "type", "name", "server", "from", "maxAge"]) {
|
|
assert.deepEqual(
|
|
JSON.parse(JSON.stringify(replacement[property])),
|
|
JSON.parse(JSON.stringify(original[property])),
|
|
`Mismatch in ${property}`
|
|
);
|
|
}
|
|
});
|
|
|
|
test("local provider preserves the user options contract", () => {
|
|
const provider = EmailProvider(options);
|
|
|
|
assert.equal(provider.options.maxAge, 7200);
|
|
assert.equal(provider.options.sendVerificationRequest, customSender);
|
|
});
|
|
|
|
test("normalized provider retains two-hour token expiry", () => {
|
|
const original = normalize(OriginalEmailProvider(options));
|
|
const replacement = normalize(EmailProvider(options));
|
|
|
|
assert.equal(original.maxAge, 7200);
|
|
assert.equal(replacement.maxAge, original.maxAge);
|
|
});
|
|
|
|
test("normalized provider uses the custom verification sender", () => {
|
|
const provider = normalize(EmailProvider(options));
|
|
|
|
assert.equal(provider.sendVerificationRequest, customSender);
|
|
});
|
|
|
|
test("provider retains NextAuth email identity", () => {
|
|
const provider = normalize(EmailProvider(options));
|
|
|
|
assert.equal(provider.id, "email");
|
|
assert.equal(provider.type, "email");
|
|
assert.equal(provider.name, "Email");
|
|
});
|
|
|
|
test("default sender fails explicitly without PEDW override", async () => {
|
|
const provider = EmailProvider();
|
|
|
|
await assert.rejects(
|
|
provider.sendVerificationRequest(),
|
|
/requires a custom GOV\.UK Notify verification sender/
|
|
);
|
|
});
|
|
|
|
test("local provider does not import Nodemailer", () => {
|
|
assert.doesNotMatch(
|
|
source,
|
|
/(?:require\s*\(|from\s+|import\s*\()\s*["']nodemailer/
|
|
);
|
|
});
|
|
|
|
test("authentication handler imports the local provider", () => {
|
|
const authSource = fs.readFileSync(
|
|
path.join(root, "pages/api/auth/[...nextauth].js"),
|
|
"utf8"
|
|
);
|
|
|
|
assert.match(
|
|
authSource,
|
|
/import EmailProvider from ["']\.\.\/\.\.\/\.\.\/lib\/auth\/email-provider["']/
|
|
);
|
|
|
|
assert.doesNotMatch(authSource, /from ["']next-auth\/providers\/email["']/);
|
|
|
|
assert.match(authSource, /EmailProvider\s*\(\s*\{/);
|
|
|
|
assert.match(authSource, /async sendVerificationRequest\s*\(/);
|
|
|
|
assert.match(authSource, /notifyClient\.sendEmail\s*\(/);
|
|
});
|