Implement auth procedures with code review fixes
Add complete auth backend (Workstream D): - Auth middleware for session/API key authentication - Signup with password or passkey (WebAuthn) - Login flow with device trust and email confirmation - Password reset and email verification - Session management and logout Utilities created: - cookies.ts: Cookie helpers and configuration - crypto.ts: Token generation and hashing - password.ts: zxcvbn validation, argon2id hashing - geo.ts: IP/location extraction from headers - email.ts: Stubbed email sending - session.ts: Session creation and device trust Code review improvements applied: - Use ORPCError instead of Error in procedures - Add ast-grep rule to enforce ORPCError usage - Remove error info leakage (generic messages) - Optimize N+1 query with JOIN in login-password - Extract signupWithPassword/signupWithPasskey for testability - Add 15-minute WebAuthn challenge expiry check - Strengthen CookieOptions type definitions Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
38
apps/api-server/src/utils/crypto.ts
Normal file
38
apps/api-server/src/utils/crypto.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { createHash, randomBytes } from "node:crypto";
|
||||
|
||||
/**
|
||||
* Hash a token with SHA-256 for storage in database
|
||||
* Never store raw tokens - always hash first
|
||||
*/
|
||||
export const hashToken = (token: string): string => {
|
||||
return createHash("sha256").update(token).digest("hex");
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a session token (UUID v4)
|
||||
*/
|
||||
export const generateSessionToken = (): string => {
|
||||
return crypto.randomUUID();
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a device fingerprint (UUID v4)
|
||||
*/
|
||||
export const generateDeviceFingerprint = (): string => {
|
||||
return crypto.randomUUID();
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a secure random token for email verification, password reset, etc.
|
||||
* Uses 32 bytes (256 bits) of entropy
|
||||
*/
|
||||
export const generateSecureToken = (): string => {
|
||||
return randomBytes(32).toString("hex");
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate expiration date
|
||||
*/
|
||||
export const generateExpiry = (seconds: number): Date => {
|
||||
return new Date(Date.now() + seconds * 1000);
|
||||
};
|
||||
Reference in New Issue
Block a user