feat: 实现演示验证码和令牌轮换

This commit is contained in:
root
2026-09-14 18:43:45 +08:00
parent 6b901e074e
commit 3e04197b02
24 changed files with 1486 additions and 12 deletions
+57
View File
@@ -0,0 +1,57 @@
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import {
codeHmac,
phoneHmac,
resetAuthEnvironmentForTests,
validateAuthEnvironment,
} from "./auth.config.js";
const valid = {
PHONE_ENCRYPTION_KEY: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
PHONE_HMAC_KEY: "phone-hmac-key-that-is-at-least-32-bytes",
VERIFICATION_CODE_HMAC_KEY: "code-hmac-key-that-is-at-least-32-bytes!",
REFRESH_TOKEN_HMAC_KEY: "refresh-key-that-is-at-least-thirty-two-bytes",
JWT_SECRET: "jwt-secret-that-is-at-least-thirty-two-bytes",
};
describe("auth environment", () => {
const original = { ...process.env };
beforeEach(() => {
process.env.NODE_ENV = "test";
Object.assign(process.env, valid);
resetAuthEnvironmentForTests();
});
afterEach(() => {
process.env = { ...original, NODE_ENV: "test" };
resetAuthEnvironmentForTests();
});
it.each(Object.keys(valid))("fails fast when %s is missing", (name) => {
delete process.env[name];
expect(() => validateAuthEnvironment()).toThrow(`${name} is required`);
});
it.each(Object.keys(valid))("fails fast when %s is too short", (name) => {
process.env[name] = "short";
expect(() => validateAuthEnvironment()).toThrow();
});
it("rejects duplicate keys including the verification-code key", () => {
process.env.VERIFICATION_CODE_HMAC_KEY = process.env.PHONE_HMAC_KEY;
expect(() => validateAuthEnvironment()).toThrow(
"Auth secrets must be independent",
);
});
it("uses a verification-code key independent from the phone key", () => {
validateAuthEnvironment();
const phoneDigest = phoneHmac("+8613800138000");
const first = codeHmac(phoneDigest, "123456");
resetAuthEnvironmentForTests();
process.env.VERIFICATION_CODE_HMAC_KEY =
"different-code-key-that-is-at-least-32-bytes";
validateAuthEnvironment();
expect(phoneHmac("+8613800138000")).toBe(phoneDigest);
expect(codeHmac(phoneDigest, "123456")).not.toBe(first);
});
});