CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history
auth.ts
Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.
| 06d5ffe | 1 | /** |
| 2 | * Authentication utilities — password hashing, session tokens. | |
| 3 | * Uses Bun's native crypto for Argon2-like password hashing. | |
| 4 | */ | |
| 5 | ||
| 6 | const SESSION_DURATION_MS = 30 * 24 * 60 * 60 * 1000; // 30 days | |
| 7 | ||
| 8 | export async function hashPassword(password: string): Promise<string> { | |
| 9 | return await Bun.password.hash(password, { algorithm: "bcrypt", cost: 10 }); | |
| 10 | } | |
| 11 | ||
| 12 | export async function verifyPassword( | |
| 13 | password: string, | |
| 14 | hash: string | |
| 15 | ): Promise<boolean> { | |
| 16 | return await Bun.password.verify(password, hash); | |
| 17 | } | |
| 18 | ||
| 19 | export function generateSessionToken(): string { | |
| 20 | const bytes = crypto.getRandomValues(new Uint8Array(32)); | |
| 21 | return Array.from(bytes) | |
| 22 | .map((b) => b.toString(16).padStart(2, "0")) | |
| 23 | .join(""); | |
| 24 | } | |
| 25 | ||
| 26 | export function sessionCookieOptions(): { | |
| 27 | httpOnly: boolean; | |
| 28 | secure: boolean; | |
| 29 | sameSite: "Lax"; | |
| 30 | path: string; | |
| 31 | maxAge: number; | |
| 32 | } { | |
| 33 | return { | |
| 34 | httpOnly: true, | |
| 35 | secure: process.env.NODE_ENV === "production", | |
| 36 | sameSite: "Lax", | |
| 37 | path: "/", | |
| 38 | maxAge: SESSION_DURATION_MS / 1000, | |
| 39 | }; | |
| 40 | } | |
| 41 | ||
| 42 | export function sessionExpiry(): Date { | |
| 43 | return new Date(Date.now() + SESSION_DURATION_MS); | |
| 44 | } |