Skip to content

Commit

Permalink
Move jwt methodes to shared.
Browse files Browse the repository at this point in the history
  • Loading branch information
CeEv committed Jul 12, 2024
1 parent 58d4e07 commit 6e4e84c
Show file tree
Hide file tree
Showing 8 changed files with 23 additions and 38 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Inject, Injectable } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { RawAxiosRequestConfig } from 'axios';
import cookie from 'cookie';
import { Request } from 'express';
import { ExtractJwt, JwtFromRequestFunction } from 'passport-jwt';
import { extractJwtFromHeader } from '@shared/common';
import { AuthorizationApi, AuthorizationBodyParams } from './authorization-api-client';
import { AuthorizationErrorLoggableException, AuthorizationForbiddenLoggableException } from './error';

Expand All @@ -19,9 +18,9 @@ export class AuthorizationClientAdapter {
}

public async hasPermissionsByReference(params: AuthorizationBodyParams): Promise<boolean> {
const options = this.createOptionParams(params);

try {
const options = this.createOptionParams();

const response = await this.authorizationApi.authorizationReferenceControllerAuthorizeByReference(
params,
options
Expand All @@ -34,34 +33,20 @@ export class AuthorizationClientAdapter {
}
}

private createOptionParams(params: AuthorizationBodyParams): RawAxiosRequestConfig<any> {
const jwt = this.getJWT(params);
private createOptionParams(): RawAxiosRequestConfig<any> {
const jwt = this.getJwt();
const options: RawAxiosRequestConfig<any> = { headers: { authorization: `Bearer ${jwt}` } };

return options;
}

private getJWT(params: AuthorizationBodyParams): string {
const getJWT = ExtractJwt.fromExtractors([ExtractJwt.fromAuthHeaderAsBearerToken(), this.fromCookie('jwt')]);
const jwt = getJWT(this.request) || this.request.headers.authorization;
private getJwt(): string {
const jwt = extractJwtFromHeader(this.request) || this.request.headers.authorization;

if (!jwt) {
const error = new Error('Authentication is required.');
throw new AuthorizationErrorLoggableException(error, params);
throw new Error('Authentication is required.');
}

return jwt;
}

private fromCookie(name: string): JwtFromRequestFunction {
return (request: Request) => {
let token: string | null = null;
const cookies = cookie.parse(request.headers.cookie || '');
if (cookies && cookies[name]) {
token = cookies[name];
}

return token;
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import {
import { ApiBearerAuth } from '@nestjs/swagger';
import { Request } from 'express';
import { ExtractJwt } from 'passport-jwt';

Check failure on line 11 in apps/server/src/modules/authentication/decorator/auth.decorator.ts

View workflow job for this annotation

GitHub Actions / nest_lint

'ExtractJwt' is defined but never used
import { extractJwtFromHeader, JwtExtractor } from '@shared/common';

Check failure on line 12 in apps/server/src/modules/authentication/decorator/auth.decorator.ts

View workflow job for this annotation

GitHub Actions / nest_lint

'JwtExtractor' is defined but never used
import { JwtAuthGuard } from '../guard/jwt-auth.guard';
import { ICurrentUser, isICurrentUser } from '../interface/user';
import { JwtExtractor } from '../helper/jwt-extractor';

const STRATEGIES = ['jwt'] as const;
type Strategies = typeof STRATEGIES;
Expand Down Expand Up @@ -56,9 +56,8 @@ export const CurrentUser = createParamDecorator<never, never, ICurrentUser>((_,
* @requires Authenticated
*/
export const JWT = createParamDecorator<never, never, string>((_, ctx: ExecutionContext) => {
const getJWT = ExtractJwt.fromExtractors([ExtractJwt.fromAuthHeaderAsBearerToken(), JwtExtractor.fromCookie('jwt')]);
const req: Request = ctx.switchToHttp().getRequest();
const jwt = getJWT(req) || req.headers.authorization;
const jwt = extractJwtFromHeader(req) || req.headers.authorization;

if (!jwt) {
throw new UnauthorizedException('Authentication is required.');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export class AuthenticationService {
async generateJwt(user: CreateJwtPayload): Promise<LoginDto> {
const jti = randomUUID();

const result: LoginDto = new LoginDto({
const result = new LoginDto({
accessToken: this.jwtService.sign(user, {
subject: user.accountId,
jwtid: jti,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { Strategy } from 'passport-jwt';
import { extractJwtFromHeader } from '@shared/common';
import { jwtConstants } from '../constants';
import { ICurrentUser } from '../interface';
import { JwtPayload } from '../interface/jwt-payload';
import { CurrentUserMapper } from '../mapper';
import { JwtExtractor } from '../helper/jwt-extractor';
import { JwtValidationAdapter } from '../helper/jwt-validation.adapter';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private readonly jwtValidationAdapter: JwtValidationAdapter) {
super({
jwtFromRequest: ExtractJwt.fromExtractors([
ExtractJwt.fromAuthHeaderAsBearerToken(),
JwtExtractor.fromCookie('jwt'),
]),
jwtFromRequest: extractJwtFromHeader,
ignoreExpiration: false,
secretOrKey: jwtConstants.secret,
...jwtConstants.jwtOptions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { WsException } from '@nestjs/websockets';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { JwtExtractor } from '@shared/common';
import { jwtConstants } from '../constants';
import { ICurrentUser } from '../interface';
import { JwtPayload } from '../interface/jwt-payload';
import { CurrentUserMapper } from '../mapper';
import { JwtExtractor } from '../helper/jwt-extractor';
import { JwtValidationAdapter } from '../helper/jwt-validation.adapter';

@Injectable()
Expand Down
1 change: 1 addition & 0 deletions apps/server/src/shared/common/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { GuardAgainst } from './guard-against';
export { SortHelper } from './sort-helper';
export { getResolvedValues, isFulfilled } from './promise';
export { extractJwtFromHeader, JwtExtractor } from './jwt';
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createMock, DeepMocked } from '@golevelup/ts-jest';
import { Request } from 'express';
import { JwtFromRequestFunction } from 'passport-jwt';
import { JwtExtractor } from './jwt-extractor';
import { JwtExtractor } from './jwt';

describe('JwtExtractor', () => {
let request: DeepMocked<Request>;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import { Request } from 'express';
import { JwtFromRequestFunction } from 'passport-jwt';
import { ExtractJwt, JwtFromRequestFunction } from 'passport-jwt';
import cookie from 'cookie';

export class JwtExtractor {
static fromCookie(name: string): JwtFromRequestFunction {
return (request: Request) => {
let token: string | null = null;
const cookies = cookie.parse(request.headers.cookie || '');
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (cookies && cookies[name]) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
token = cookies[name];
}
return token;
};
}
}

export const extractJwtFromHeader = ExtractJwt.fromExtractors([
ExtractJwt.fromAuthHeaderAsBearerToken(),
JwtExtractor.fromCookie('jwt'),
]);

0 comments on commit 6e4e84c

Please sign in to comment.