fix(auth): properly map raw SQL snake_case rows to User entity camelCase fields

This commit is contained in:
hailin 2026-03-07 03:54:34 -08:00
parent 00357d855d
commit 76389a337e
1 changed files with 24 additions and 8 deletions

View File

@ -75,9 +75,8 @@ export class AuthService {
if (!fallbackRows.length) throw new UnauthorizedException('Invalid credentials');
rows.push(...fallbackRows);
}
const rawUser = rows[0];
const user = Object.assign(new User(), rawUser) as User;
if (!user || !user.isActive) {
const user = this.mapRow(rows[0]);
if (!user.isActive) {
throw new UnauthorizedException('Invalid credentials');
}
@ -86,8 +85,10 @@ export class AuthService {
throw new UnauthorizedException('Invalid credentials');
}
user.lastLoginAt = new Date();
await this.userRepository.save(user);
// Update last_login_at directly to avoid search_path issues
await this.dataSource.query(
`UPDATE public.users SET last_login_at = NOW() WHERE id = $1`, [user.id],
);
const tokens = this.generateTokens(user);
@ -484,9 +485,7 @@ export class AuthService {
if (!rows.length) {
throw new UnauthorizedException('User not found or inactive');
}
const user = Object.assign(new User(), rows[0]) as User;
return this.generateTokens(user);
return this.generateTokens(this.mapRow(rows[0]));
}
async createApiKey(
@ -539,4 +538,21 @@ export class AuthService {
return { accessToken, refreshToken };
}
/** Map raw SQL row (snake_case) to User entity (camelCase) */
private mapRow(raw: Record<string, any>): User {
const u = new User();
u.id = raw.id;
u.tenantId = raw.tenant_id;
u.email = raw.email ?? undefined;
u.phone = raw.phone ?? undefined;
u.passwordHash = raw.password_hash;
u.name = raw.name;
u.roles = raw.roles;
u.isActive = raw.is_active;
u.lastLoginAt = raw.last_login_at;
u.createdAt = raw.created_at;
u.updatedAt = raw.updated_at;
return u;
}
}