@@ -7,8 +7,10 @@ import {
77 getUserById ,
88 setPasswordForExistingUser ,
99 toPublicUser ,
10+ updateUserPasswordHash ,
1011 updateUserRoleFromEmail ,
1112} from "./users.js" ;
13+ import { hashPasswordForStorage , verifyPasswordForLogin } from "./passwordHash.js" ;
1214
1315const passwordLoginLimiter = rateLimit ( {
1416 windowMs : 10 * 60 * 1000 ,
@@ -57,21 +59,6 @@ function isValidEmail(email) {
5759 return / ^ [ ^ \s @ ] + @ [ ^ \s @ ] + \. [ ^ \s @ ] + $ / . test ( email ) ;
5860}
5961
60- function hashPassword ( password ) {
61- const salt = crypto . randomBytes ( 16 ) . toString ( "hex" ) ;
62- const hash = crypto . scryptSync ( password , salt , 64 ) . toString ( "hex" ) ;
63- return `scrypt:${ salt } :${ hash } ` ;
64- }
65-
66- function verifyPassword ( password , storedHash ) {
67- const [ algorithm , salt , hash ] = String ( storedHash || "" ) . split ( ":" ) ;
68- if ( algorithm !== "scrypt" || ! salt || ! hash ) return false ;
69-
70- const submittedHash = crypto . scryptSync ( password , salt , 64 ) ;
71- const storedBuffer = Buffer . from ( hash , "hex" ) ;
72- return storedBuffer . length === submittedHash . length && crypto . timingSafeEqual ( storedBuffer , submittedHash ) ;
73- }
74-
7562function signLocalUserId ( userId ) {
7663 const payload = String ( userId ) ;
7764 const signature = crypto . createHmac ( "sha256" , localDevCookieSecret ( ) ) . update ( payload ) . digest ( "hex" ) ;
@@ -135,15 +122,19 @@ export function createAuthRouter() {
135122 let user ;
136123
137124 if ( existingUser ?. password_hash ) {
138- if ( ! verifyPassword ( password , existingUser . password_hash ) ) {
125+ const outcome = verifyPasswordForLogin ( password , existingUser . password_hash ) ;
126+ if ( ! outcome . valid ) {
139127 res . status ( 401 ) . json ( { error : "Wrong email or password." } ) ;
140128 return ;
141129 }
130+ if ( outcome . migrateToHash ) {
131+ await updateUserPasswordHash ( existingUser . id , outcome . migrateToHash ) ;
132+ }
142133 user = await updateUserRoleFromEmail ( existingUser . id , email ) ;
143134 } else if ( existingUser ) {
144- user = await setPasswordForExistingUser ( existingUser . id , email , hashPassword ( password ) ) ;
135+ user = await setPasswordForExistingUser ( existingUser . id , email , hashPasswordForStorage ( password ) ) ;
145136 } else {
146- user = await createUserFromEmailPassword ( email , hashPassword ( password ) ) ;
137+ user = await createUserFromEmailPassword ( email , hashPasswordForStorage ( password ) ) ;
147138 }
148139
149140 req . session . userId = user . id ;
0 commit comments