Files
CRM_Montzar/apps/api/src/auth/jwt.strategy.ts
T

58 lines
1.6 KiB
TypeScript

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { PrismaService } from '../prisma/prisma.service';
export type JwtPayload = {
sub: string;
organizationId: string;
role: string;
};
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(
config: ConfigService,
private readonly prisma: PrismaService,
) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: config.get<string>('JWT_SECRET') ?? 'dev-secret',
});
}
async validate(payload: JwtPayload & { typ?: string; mobile?: string }) {
if (payload.typ === 'portal' || payload.typ === 'org-select') {
throw new UnauthorizedException();
}
if (!payload.sub || !payload.organizationId) {
throw new UnauthorizedException();
}
const user = await this.prisma.user.findUnique({
where: { id: payload.sub },
select: { id: true, isActive: true },
});
if (!user || user.isActive === false) {
throw new UnauthorizedException();
}
const membership = await this.prisma.membership.findFirst({
where: {
userId: user.id,
organizationId: payload.organizationId,
isActive: true,
},
select: { organizationId: true, role: true },
});
if (!membership) {
throw new UnauthorizedException();
}
return {
userId: user.id,
organizationId: membership.organizationId,
role: membership.role,
};
}
}