fix: 加固认证撤销与运行配置
This commit is contained in:
@@ -26,6 +26,31 @@ const REQUIRED_KEYS = [
|
||||
] as const;
|
||||
type AuthSecrets = Record<(typeof REQUIRED_KEYS)[number], Buffer>;
|
||||
let secrets: AuthSecrets | undefined;
|
||||
let configuredWebOrigin: string | undefined;
|
||||
|
||||
function parseWebOrigin(): string {
|
||||
const raw = process.env.WEB_ORIGIN;
|
||||
if (!raw) throw new Error("WEB_ORIGIN is required");
|
||||
let url: URL;
|
||||
try {
|
||||
url = new URL(raw);
|
||||
} catch {
|
||||
throw new Error("WEB_ORIGIN must be an absolute HTTP(S) origin");
|
||||
}
|
||||
if (
|
||||
!["http:", "https:"].includes(url.protocol) ||
|
||||
url.username ||
|
||||
url.password ||
|
||||
url.pathname !== "/" ||
|
||||
url.search ||
|
||||
url.hash ||
|
||||
url.origin !== raw
|
||||
)
|
||||
throw new Error(
|
||||
"WEB_ORIGIN must be one absolute HTTP(S) origin without credentials or path",
|
||||
);
|
||||
return url.origin;
|
||||
}
|
||||
|
||||
export function validateAuthEnvironment(): void {
|
||||
const loaded = Object.fromEntries(
|
||||
@@ -38,18 +63,35 @@ export function validateAuthEnvironment(): void {
|
||||
);
|
||||
if (new Set(fingerprints).size !== fingerprints.length)
|
||||
throw new Error("Auth secrets must be independent");
|
||||
const origin = parseWebOrigin();
|
||||
if (process.env.DEMO_SMS_CODE_ENABLED === "true" && !demoEnvironmentAllowed())
|
||||
throw new Error(
|
||||
"DEMO_SMS_CODE_ENABLED is forbidden outside test or local development",
|
||||
);
|
||||
secrets = loaded;
|
||||
configuredWebOrigin = origin;
|
||||
}
|
||||
export function resetAuthEnvironmentForTests(): void {
|
||||
if (process.env.NODE_ENV !== "test")
|
||||
throw new Error("Auth environment reset is test-only");
|
||||
secrets = undefined;
|
||||
configuredWebOrigin = undefined;
|
||||
}
|
||||
function authSecrets(): AuthSecrets {
|
||||
if (!secrets) validateAuthEnvironment();
|
||||
return secrets!;
|
||||
}
|
||||
export const jwtSecret = (): Buffer => authSecrets().JWT_SECRET;
|
||||
export const webOrigin = (): string => {
|
||||
if (!configuredWebOrigin) validateAuthEnvironment();
|
||||
return configuredWebOrigin!;
|
||||
};
|
||||
const demoEnvironmentAllowed = (): boolean =>
|
||||
process.env.NODE_ENV === "test" ||
|
||||
process.env.NODE_ENV === "development" ||
|
||||
process.env.APP_ENV === "local";
|
||||
export const demoSmsCodeEnabled = (): boolean =>
|
||||
process.env.DEMO_SMS_CODE_ENABLED === "true" && demoEnvironmentAllowed();
|
||||
export const phoneHmac = (phone: string): string =>
|
||||
createHmac("sha256", authSecrets().PHONE_HMAC_KEY)
|
||||
.update(phone)
|
||||
|
||||
Reference in New Issue
Block a user