fix: make compiled docker auth and sqlite runtime work
This commit is contained in:
@@ -4,8 +4,8 @@ import {
|
||||
UnauthorizedException,
|
||||
} from '@nestjs/common';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import * as argon2 from 'argon2';
|
||||
import { AuthResponse, UserProfile } from '@codexdash/shared-types';
|
||||
import { hashPassword, verifyPassword } from './password-hasher';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import { LoginDto } from './dto/login.dto';
|
||||
import { RegisterDto } from './dto/register.dto';
|
||||
@@ -30,7 +30,7 @@ export class AuthService {
|
||||
data: {
|
||||
email: dto.email.toLowerCase(),
|
||||
name: dto.name.trim(),
|
||||
passwordHash: await argon2.hash(dto.password),
|
||||
passwordHash: await hashPassword(dto.password),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -42,7 +42,7 @@ export class AuthService {
|
||||
where: { email: dto.email.toLowerCase() },
|
||||
});
|
||||
|
||||
if (!user || !(await argon2.verify(user.passwordHash, dto.password))) {
|
||||
if (!user || !(await verifyPassword(user.passwordHash, dto.password))) {
|
||||
throw new UnauthorizedException('Invalid email or password');
|
||||
}
|
||||
|
||||
|
||||
25
apps/api/src/auth/password-hasher.spec.ts
Normal file
25
apps/api/src/auth/password-hasher.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import * as argon2 from 'argon2';
|
||||
import { hashPassword, verifyPassword } from './password-hasher';
|
||||
|
||||
describe('password-hasher', () => {
|
||||
it('hashes passwords into an argon2id digest that can be verified', async () => {
|
||||
const digest = await hashPassword('correct horse battery staple');
|
||||
|
||||
expect(digest.startsWith('$argon2id$')).toBe(true);
|
||||
await expect(
|
||||
verifyPassword(digest, 'correct horse battery staple'),
|
||||
).resolves.toBe(true);
|
||||
await expect(verifyPassword(digest, 'wrong password')).resolves.toBe(false);
|
||||
});
|
||||
|
||||
it('verifies legacy node-argon2 digests', async () => {
|
||||
const legacyDigest = await argon2.hash('legacy secret');
|
||||
|
||||
await expect(verifyPassword(legacyDigest, 'legacy secret')).resolves.toBe(
|
||||
true,
|
||||
);
|
||||
await expect(verifyPassword(legacyDigest, 'wrong password')).resolves.toBe(
|
||||
false,
|
||||
);
|
||||
});
|
||||
});
|
||||
42
apps/api/src/auth/password-hasher.ts
Normal file
42
apps/api/src/auth/password-hasher.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
type BunPasswordApi = {
|
||||
hash(password: string, options?: { algorithm?: 'argon2id' }): Promise<string>;
|
||||
verify(password: string, digest: string): Promise<boolean>;
|
||||
};
|
||||
|
||||
function getBunPasswordApi(): BunPasswordApi | undefined {
|
||||
const runtime = globalThis as typeof globalThis & {
|
||||
Bun?: {
|
||||
password?: BunPasswordApi;
|
||||
};
|
||||
};
|
||||
|
||||
return runtime.Bun?.password;
|
||||
}
|
||||
|
||||
function loadArgon2(): typeof import('argon2') {
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
return require('argon2') as typeof import('argon2');
|
||||
}
|
||||
|
||||
export async function hashPassword(password: string): Promise<string> {
|
||||
const bunPassword = getBunPasswordApi();
|
||||
if (bunPassword) {
|
||||
return bunPassword.hash(password, { algorithm: 'argon2id' });
|
||||
}
|
||||
|
||||
const argon2 = loadArgon2();
|
||||
return argon2.hash(password);
|
||||
}
|
||||
|
||||
export async function verifyPassword(
|
||||
digest: string,
|
||||
password: string,
|
||||
): Promise<boolean> {
|
||||
const bunPassword = getBunPasswordApi();
|
||||
if (bunPassword) {
|
||||
return bunPassword.verify(password, digest);
|
||||
}
|
||||
|
||||
const argon2 = loadArgon2();
|
||||
return argon2.verify(digest, password);
|
||||
}
|
||||
Reference in New Issue
Block a user