Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | 13x 13x 13x 13x 13x 13x 29x 29x 30x 30x 30x 30x 30x 1x 29x 147x 147x 4x 143x 143x 141x 140x 2x 138x 1x 1x | import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { ConfigService } from '@nestjs/config';
import { PrismaService } from '@app/modules/prisma/prisma.service';
import { Algorithm } from 'jsonwebtoken';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(
private prisma: PrismaService,
private config: ConfigService
) {
const publicKey = config.get<string>('JWT_PUBLIC_KEY')?.replace(/\\n/g, '\n');
const algorithm = (config.get<string>('JWT_ALGORITHM') || 'RS256') as Algorithm;
const issuer = config.get<string>('JWT_ISSUER');
const audience = config.get<string>('JWT_AUDIENCE');
if (!publicKey) {
throw new Error('JWT_PUBLIC_KEY is required for JWT strategy');
}
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
algorithms: [algorithm],
secretOrKey: publicKey,
issuer,
audience,
});
}
/** The payload becomes req.user */
async validate(payload: any) {
try {
// Validate payload structure
if (!payload || !payload.sub || (typeof payload.sub !== 'number' && typeof payload.sub !== 'string')) {
return null;
}
const userId = typeof payload.sub === 'string' ? parseInt(payload.sub, 10) : payload.sub;
if (!Number.isFinite(userId)) return null;
const user = await this.prisma.client.user.findUnique({
where: { id: userId },
select: {
id: true,
email: true,
role: true,
tokenVersion: true,
agencyId: true,
developerCompanyId: true,
}
});
if (!user || user.tokenVersion !== payload.tokenVersion) {
return null;
}
// Return complete user context for authorization
return {
id: user.id,
userId: user.id, // Backward compatibility
email: user.email,
role: user.role,
agencyId: user.agencyId,
developerCompanyId: user.developerCompanyId,
};
} catch (error) {
// Log error but return null to trigger 401 instead of 500
console.error('JWT strategy validation error:', error);
return null;
}
}
} |