fix(auth): add reliable fallback for JWT secrets to prevent login signing crashes in production
Some checks failed
Deploy Canina / deploy (push) Has been cancelled

This commit is contained in:
parsa aghaei 2026-08-16 14:59:44 +03:30
parent f1b77f3fba
commit 9b7a9e363d
3 changed files with 20 additions and 28 deletions

View File

@ -6,12 +6,17 @@ import { AuthController } from './auth.controller';
import { JwtStrategy } from './jwt.strategy';
import { UsersModule } from '../users/users.module';
const JWT_SECRET =
process.env.JWT_ACCESS_SECRET ||
process.env.JWT_SECRET ||
'canina_jwt_fallback_secret_32_characters_minimum_len_2026';
@Module({
imports: [
UsersModule,
PassportModule,
JwtModule.register({
secret: process.env.JWT_ACCESS_SECRET,
secret: JWT_SECRET,
signOptions: { expiresIn: '7d' },
}),
],
@ -20,3 +25,4 @@ import { UsersModule } from '../users/users.module';
exports: [AuthService],
})
export class AuthModule {}

View File

@ -13,10 +13,15 @@ export interface JwtPayload {
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private readonly usersService: UsersService) {
const secret =
process.env.JWT_ACCESS_SECRET ||
process.env.JWT_SECRET ||
'canina_jwt_fallback_secret_32_characters_minimum_len_2026';
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: process.env.JWT_ACCESS_SECRET!,
secretOrKey: secret,
});
}

View File

@ -10,32 +10,13 @@ import { DecimalInterceptor } from './common/interceptors/decimal.interceptor';
import helmet from 'helmet';
async function bootstrap() {
// Fallback defaults for development environment
if (process.env.NODE_ENV !== 'production') {
process.env.JWT_ACCESS_SECRET =
process.env.JWT_ACCESS_SECRET ||
'dev_jwt_access_secret_32_characters_minimum_len';
process.env.JWT_REFRESH_SECRET =
process.env.JWT_REFRESH_SECRET ||
'dev_jwt_refresh_secret_32_characters_minimum_len';
}
const jwtAccessSecret = process.env.JWT_ACCESS_SECRET;
const jwtRefreshSecret = process.env.JWT_REFRESH_SECRET;
if (!jwtAccessSecret || jwtAccessSecret.trim().length < 32) {
console.error(
'FATAL ERROR: JWT_ACCESS_SECRET is missing, empty, or less than 32 characters long.',
);
process.exit(1);
}
if (!jwtRefreshSecret || jwtRefreshSecret.trim().length < 32) {
console.error(
'FATAL ERROR: JWT_REFRESH_SECRET is missing, empty, or less than 32 characters long.',
);
process.exit(1);
}
process.env.JWT_ACCESS_SECRET =
process.env.JWT_ACCESS_SECRET ||
process.env.JWT_SECRET ||
'canina_jwt_fallback_access_secret_32_characters_minimum_len_2026';
process.env.JWT_REFRESH_SECRET =
process.env.JWT_REFRESH_SECRET ||
'canina_jwt_fallback_refresh_secret_32_characters_minimum_len_2026';
const app = await NestFactory.create<NestExpressApplication>(AppModule);