Add password login, set-password, business images migration, and user serialization.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
import { randomBytes, scrypt, timingSafeEqual } from 'crypto';
|
||||
import { promisify } from 'util';
|
||||
|
||||
const scryptAsync = promisify(scrypt);
|
||||
const KEY_LENGTH = 64;
|
||||
|
||||
export async function hashPassword(password: string): Promise<string> {
|
||||
const salt = randomBytes(16).toString('hex');
|
||||
const derived = (await scryptAsync(password, salt, KEY_LENGTH)) as Buffer;
|
||||
return `scrypt:${salt}:${derived.toString('hex')}`;
|
||||
}
|
||||
|
||||
export async function verifyPassword(
|
||||
password: string,
|
||||
stored: string,
|
||||
): Promise<boolean> {
|
||||
const parts = stored.split(':');
|
||||
if (parts.length !== 3 || parts[0] !== 'scrypt') {
|
||||
return false;
|
||||
}
|
||||
const [, salt, hashHex] = parts;
|
||||
if (!salt || !hashHex) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const derived = (await scryptAsync(password, salt, KEY_LENGTH)) as Buffer;
|
||||
const expected = Buffer.from(hashHex, 'hex');
|
||||
if (derived.length !== expected.length) {
|
||||
return false;
|
||||
}
|
||||
return timingSafeEqual(derived, expected);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { UserEntity } from '../../entities/user.entity';
|
||||
|
||||
export type PublicUser = {
|
||||
id: string;
|
||||
mobile: string;
|
||||
fullName: string | null;
|
||||
role: string;
|
||||
isActive: boolean;
|
||||
hasPassword: boolean;
|
||||
createdAt?: Date;
|
||||
updatedAt?: Date;
|
||||
};
|
||||
|
||||
export function serializeUser(user: UserEntity): PublicUser {
|
||||
return {
|
||||
id: user.id,
|
||||
mobile: user.mobile,
|
||||
fullName: user.fullName,
|
||||
role: user.role,
|
||||
isActive: user.isActive,
|
||||
hasPassword: Boolean(user.passwordHash),
|
||||
createdAt: user.createdAt,
|
||||
updatedAt: user.updatedAt,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user