This commit is contained in:
2026-05-20 23:56:43 +03:30
parent 3e4e9e1f77
commit 5087a3e977
11 changed files with 3789 additions and 5326 deletions
+8 -5
View File
@@ -16,14 +16,17 @@ import { BusinessModule } from '../business/business.module';
UtilsModule,
JwtModule.registerAsync({
useFactory: (configService: ConfigService) => {
const expiresIn = configService.getOrThrow<number>('JWT_EXPIRATION_TIME');
const expiresIn = parseInt(
String(configService.getOrThrow('JWT_EXPIRATION_TIME')),
10,
);
if (!Number.isFinite(expiresIn) || expiresIn <= 0) {
throw new Error('JWT_EXPIRATION_TIME must be a positive number of seconds');
}
return {
global: true,
secret: configService.getOrThrow<string>('JWT_SECRET'),
signOptions: {
// Use string format with time unit for explicit expiration (value should be in seconds)
expiresIn: `${expiresIn}s`,
},
signOptions: { expiresIn },
};
},
inject: [ConfigService],
+13 -7
View File
@@ -23,8 +23,8 @@ export class TokensService {
businessId: string,
em?: EntityManager,
) {
const refreshExpire = this.configService.getOrThrow<number>('REFRESH_TOKEN_EXPIRE');
const accessExpire = this.configService.getOrThrow<number>('JWT_EXPIRATION_TIME');
const refreshExpire = this.getEnvNumber('REFRESH_TOKEN_EXPIRE');
const accessExpire = this.getEnvNumber('JWT_EXPIRATION_TIME');
const payload: IAdminTokenPayload = { adminId, businessId }
@@ -41,10 +41,7 @@ export class TokensService {
}
private generateAccessToken(payload: IAdminTokenPayload, expiresIn: number) {
// Ensure expiresIn is passed as a string with time unit for reliability
// JWT library accepts: number (seconds) or string with unit (e.g., "3600s", "1h")
// Using string format is more explicit and prevents unit confusion
return this.jwtService.signAsync(payload, { expiresIn: `${expiresIn}s` });
return this.jwtService.signAsync(payload, { expiresIn });
}
async storeRefreshToken(
@@ -54,7 +51,7 @@ export class TokensService {
em?: EntityManager,
) {
const entityManager = em || this.em;
const refreshExpire = this.configService.getOrThrow<number>('REFRESH_TOKEN_EXPIRE');
const refreshExpire = this.getEnvNumber('REFRESH_TOKEN_EXPIRE');
const expiresAt = dayjs().add(refreshExpire, 'day').toDate();
const hashedToken = this.hashToken(refreshToken);
@@ -126,4 +123,13 @@ export class TokensService {
private hashToken(token: string): string {
return createHash('sha256').update(token).digest('hex');
}
/** Env vars are strings; parseInt tolerates stray text from Docker --env-file. */
private getEnvNumber(key: string): number {
const value = parseInt(String(this.configService.getOrThrow(key)), 10);
if (!Number.isFinite(value) || value <= 0) {
throw new Error(`${key} must be a positive number`);
}
return value;
}
}
@@ -17,7 +17,7 @@ export class CatalogueController {
// ============= Public Routes ==============
@Get('public/catalogue/slug/:slug')
@Get('public/catalogue/business/slug/:slug')
findAllAsPublic(@Param('slug') slug: string, @Query() queryDto: FindCataloguesDto) {
return this.catalogueService.findAll(slug, queryDto);
}