This commit is contained in:
2026-02-14 13:00:13 +03:30
parent 92e2347ad1
commit ec828717b5
2 changed files with 19 additions and 10 deletions
+3 -3
View File
@@ -20,13 +20,13 @@ import { NotificationsModule } from '../notifications/notifications.module';
forwardRef(() => UserModule), forwardRef(() => UserModule),
JwtModule.registerAsync({ JwtModule.registerAsync({
useFactory: (configService: ConfigService) => { useFactory: (configService: ConfigService) => {
const expiresIn = configService.getOrThrow<number>('JWT_EXPIRATION_TIME'); const raw = configService.get<string>('JWT_EXPIRATION_TIME');
const expiresIn = Math.max(60, parseInt(String(raw ?? 3600), 10) || 3600);
return { return {
global: true, global: true,
secret: configService.getOrThrow<string>('JWT_SECRET'), secret: configService.getOrThrow<string>('JWT_SECRET'),
signOptions: { signOptions: {
// Use string format with time unit for explicit expiration (value should be in seconds) expiresIn,
expiresIn: `${expiresIn}s`,
}, },
}; };
}, },
+16 -7
View File
@@ -27,8 +27,8 @@ export class TokensService {
slug: string, slug: string,
em?: EntityManager, em?: EntityManager,
) { ) {
const refreshExpire = this.configService.getOrThrow<number>('REFRESH_TOKEN_EXPIRE'); const refreshExpire = this.parseRefreshExpire();
const accessExpire = this.configService.getOrThrow<number>('JWT_EXPIRATION_TIME'); const accessExpire = this.parseAccessExpire();
const payload: ITokenPayload | IAdminTokenPayload = isAdmin const payload: ITokenPayload | IAdminTokenPayload = isAdmin
? { adminId: ownerId, shopId: shopId } ? { adminId: ownerId, shopId: shopId }
@@ -48,10 +48,19 @@ export class TokensService {
} }
private generateAccessToken(payload: ITokenPayload | IAdminTokenPayload, expiresIn: number) { private generateAccessToken(payload: ITokenPayload | IAdminTokenPayload, expiresIn: number) {
// Ensure expiresIn is passed as a string with time unit for reliability return this.jwtService.signAsync(payload, { expiresIn });
// 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` }); private parseAccessExpire(): number {
const raw = this.configService.get<string>('JWT_EXPIRATION_TIME');
const parsed = parseInt(String(raw ?? 3600), 10);
return parsed > 0 ? parsed : 3600;
}
private parseRefreshExpire(): number {
const raw = this.configService.get<string>('REFRESH_TOKEN_EXPIRE');
const parsed = parseInt(String(raw ?? 15), 10);
return parsed > 0 ? parsed : 15;
} }
async storeRefreshToken( async storeRefreshToken(
@@ -62,7 +71,7 @@ export class TokensService {
em?: EntityManager, em?: EntityManager,
) { ) {
const entityManager = em || this.em; const entityManager = em || this.em;
const refreshExpire = this.configService.getOrThrow<number>('REFRESH_TOKEN_EXPIRE'); const refreshExpire = this.parseRefreshExpire();
const expiresAt = dayjs().add(refreshExpire, 'day').toDate(); const expiresAt = dayjs().add(refreshExpire, 'day').toDate();
const hashedToken = this.hashToken(refreshToken); const hashedToken = this.hashToken(refreshToken);