Skip to content

Commit c994663

Browse files
claudeenko
authored andcommitted
Address PR review comments on Epic 18
- Fix password verify snippet: replace undefined `defaultVerify` with bcrypt prefix detection ($2b$/$2a$) and proper fallback logic with try-catch around both algorithms. Add note that exact Better Auth crypto import path must be validated during spike. - Replace `npx` with `pnpm dlx` for consistency with project toolchain. https://claude.ai/code/session_015gXWpvq2YYBXJHNVfZaKGL
1 parent 2465d84 commit c994663

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

project-management/epics/epic-18-planned-better-auth-migration.md

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -112,22 +112,30 @@ Better Auth uses **scrypt** by default, not bcrypt. Our existing passwords are h
112112

113113
**Dual-algorithm strategy during parallel operation:**
114114
```typescript
115+
import { scryptAsync, timingSafeEqual } from "@noble/hashes/scrypt";
115116
import bcrypt from "bcrypt";
116117

117118
export const auth = betterAuth({
118119
emailAndPassword: {
119120
enabled: true,
120121
requireEmailVerification: false,
121122
password: {
122-
// New passwords use Better Auth's default scrypt
123-
// (omit hash to use default)
124123
verify: async ({ hash, password }) => {
125-
// Try scrypt first (new passwords)
126-
const scryptResult = await defaultVerify({ hash, password });
127-
if (scryptResult) return true;
128-
// Fall back to bcrypt (migrated passwords)
124+
// bcrypt hashes start with $2b$ (or $2a$) — detect and verify directly
125+
if (hash.startsWith("$2b$") || hash.startsWith("$2a$")) {
126+
try {
127+
return await bcrypt.compare(password, hash);
128+
} catch {
129+
return false;
130+
}
131+
}
132+
// Otherwise, assume scrypt (Better Auth default for new passwords)
133+
// Better Auth stores scrypt hashes in PHC string format
134+
// Use the same verification logic Better Auth uses internally
135+
// (exact import/method to be validated during spike)
129136
try {
130-
return await bcrypt.compare(password, hash);
137+
const { verify } = await import("better-auth/crypto");
138+
return await verify({ hash, password });
131139
} catch {
132140
return false;
133141
}
@@ -137,6 +145,10 @@ export const auth = betterAuth({
137145
});
138146
```
139147

148+
> **Note:** The exact import path for Better Auth's internal scrypt verify function
149+
> must be validated during the spike phase. The `better-auth/crypto` path is a
150+
> placeholder — check the actual exports in the pinned version.
151+
140152
This approach:
141153
- Verifies new passwords (scrypt) and legacy passwords (bcrypt) transparently
142154
- New registrations and password resets automatically use scrypt
@@ -245,7 +257,7 @@ export const auth = betterAuth({
245257
2. **Prepare database:**
246258
- Rename `auth` schema to `auth_legacy`
247259
- Create new `auth` schema
248-
- Run Better Auth CLI migration: `npx auth@latest migrate`
260+
- Run Better Auth CLI migration: `pnpm dlx auth@latest migrate`
249261
- Write and test data migration script (users → Better Auth tables)
250262

251263
3. **Install and configure:**

0 commit comments

Comments
 (0)