37 lines
1.2 KiB
TypeScript
37 lines
1.2 KiB
TypeScript
import { ForbiddenException, Inject, Injectable } from '@nestjs/common';
|
|
import { ConfigService } from '@nestjs/config';
|
|
import { JWK, KeyLike, SignJWT, jwtVerify } from 'jose';
|
|
|
|
@Injectable()
|
|
export class JWTService {
|
|
constructor(
|
|
@Inject('APP_PRIVATE_KEY') private readonly privateKey: KeyLike,
|
|
@Inject('APP_PUBLIC_KEY') private readonly publicKey: KeyLike,
|
|
@Inject('APP_PUBLIC_KEY_JWK') private readonly publicKeyJWK: JWK,
|
|
private readonly config: ConfigService,
|
|
) {}
|
|
|
|
async sign(data: Record<string, unknown>, audience = 'urn:freeblox:service') {
|
|
const alg = this.config.get('security.algorithm');
|
|
const jwt = await new SignJWT(data)
|
|
.setProtectedHeader({ alg })
|
|
.setIssuedAt()
|
|
.setIssuer('urn:freeblox:auth')
|
|
.setAudience(audience)
|
|
.setExpirationTime('8d')
|
|
.sign(this.privateKey);
|
|
return jwt;
|
|
}
|
|
|
|
async verify(jwt: string, audience = 'urn:freeblox:service') {
|
|
const alg = this.config.get('security.algorithm');
|
|
const { payload, protectedHeader } = await jwtVerify(jwt, this.publicKey, {
|
|
issuer: 'urn:freeblox:auth',
|
|
audience,
|
|
});
|
|
if (protectedHeader.alg !== alg)
|
|
throw new ForbiddenException('Provided JWT contains invalid headers.');
|
|
return payload;
|
|
}
|
|
}
|