Skip to content

Commit

Permalink
feat(auth): add profile, logout function
Browse files Browse the repository at this point in the history
  • Loading branch information
mannn-2274 committed Feb 27, 2024
1 parent 2e991cc commit f736760
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 4 deletions.
15 changes: 13 additions & 2 deletions nestjs-auth/src/auth-typeorm/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
UseGuards,
} from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalAuthGuard } from './guard/local-auth.guard';
import { AccessTokenAuthGuard, LocalAuthGuard } from './guard/local-auth.guard';

@Controller('')
export class AuthController {
Expand Down Expand Up @@ -46,8 +46,19 @@ export class AuthController {
);
}

@HttpCode(200)
@UseGuards(AccessTokenAuthGuard)
@Post('logout')
async logout(@Req() req: Request) {
const accessToken = this.authService.jwtExtractor()(req);
return await this.authService.userService.onAfterLogout(
accessToken,
);
}

@UseGuards(AccessTokenAuthGuard)
@Get('profile')
getProfile(req) {
getProfile(@Req() req: Request) {
return req.user;
}
}
3 changes: 2 additions & 1 deletion nestjs-auth/src/auth-typeorm/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
UserAuthServiceType,
} from './types';
import { AuthController } from './auth.controller';
import { LocalStrategy } from './strategy/local.strategy';
import { LocalStrategy, JwtAccessTokenStrategy } from './strategy/local.strategy';
import { PassportModule } from '@nestjs/passport';
import { getOptions } from './helpers';

Expand Down Expand Up @@ -60,6 +60,7 @@ export class AuthModule {
UserServiceClass,
AuthService<Entity, JwtPayload, RegisterDto>,
LocalStrategy<Entity>,
JwtAccessTokenStrategy<Entity, JwtPayload>,
],
exports: [AuthService, USER_SERVICE, AUTH_CONFIG],
controllers: opts.disableRouter ? [] : [AuthController],
Expand Down
7 changes: 7 additions & 0 deletions nestjs-auth/src/auth-typeorm/auth.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Inject, Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { DataSource, EntityTarget, ObjectLiteral, Repository } from 'typeorm';
import { ExtractJwt, JwtFromRequestFunction } from 'passport-jwt';
import {
AUTH_CONFIG,
AuthModuleConfig,
Expand Down Expand Up @@ -41,6 +42,12 @@ export class AuthService<
}
}

jwtExtractor(): JwtFromRequestFunction {
return this.opts.jwt.jwtFromRequest
? this.opts.jwt.jwtFromRequest()
: ExtractJwt.fromAuthHeaderAsBearerToken();
}

async getLoginTokens(user: Entity): Promise<any> {
const [refreshTokenPayload, accessTokenPayload] = await Promise.all([
this.userService.createJwtRefreshTokenPayload(user),
Expand Down
3 changes: 3 additions & 0 deletions nestjs-auth/src/auth-typeorm/guard/local-auth.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ import { Injectable } from '@nestjs/common';

@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}

@Injectable()
export class AccessTokenAuthGuard extends AuthGuard('jwt-access-token') {}
28 changes: 27 additions & 1 deletion nestjs-auth/src/auth-typeorm/strategy/local.strategy.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { AuthService } from '../auth.service';
import { PassportStrategy } from '@nestjs/passport';
import { ObjectLiteral } from 'typeorm';
import { Strategy as PassportJwtStrategy } from 'passport-jwt';
import { Strategy as PassportLocalStrategy } from 'passport-local';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { Inject, Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthModuleConfig, AUTH_CONFIG } from '../types';

@Injectable()
export class LocalStrategy<
Expand All @@ -23,3 +25,27 @@ export class LocalStrategy<
return user;
}
}

@Injectable()
export class JwtAccessTokenStrategy<
Entity extends ObjectLiteral,

Check failure on line 31 in nestjs-auth/src/auth-typeorm/strategy/local.strategy.ts

View workflow job for this annotation

GitHub Actions / build-and-test (20.10.0)

'Entity' is defined but never used
JwtPayload extends ObjectLiteral,
> extends PassportStrategy(PassportJwtStrategy, 'jwt-access-token') {
constructor(
private authService: AuthService,
@Inject(AUTH_CONFIG) public opts: AuthModuleConfig,
) {
const secretOrKey =
opts.jwt.secret || opts.jwt.privateKey || opts.jwt.secretOrPrivateKey;
super({
secretOrKey,
ignoreExpiration: false,
passReqToCallback: false,
jwtFromRequest: authService.jwtExtractor(),
});
}

async validate(payload: JwtPayload) {
return this.authService.userService.jwtValidator(payload);
}
}
2 changes: 2 additions & 0 deletions nestjs-auth/src/auth-typeorm/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,6 @@ export abstract class UserAuthServiceType<Entity, JwtPayloadSub, RegisterDto> {
accessTokenExpiresAt: any,
refreshTokenExpiresAt: any,
): Promise<any>;
abstract jwtValidator(payload: JwtPayloadSub): Promise<Entity>;
abstract onAfterLogout(accessToken: string): Promise<any>;
}
22 changes: 22 additions & 0 deletions nestjs-auth/src/auth-typeorm/user-auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,4 +208,26 @@ export class BaseUserAuthService<
expires_at: accessTokenExpiresAt,
};
}

async jwtValidator(payload: JwtPayloadSub) {
if (!payload.sub[this.IDField]) {
throw new Error('Invalid JWT payload');
}

const user = await this.userRepository.findOneBy({
[this.IDField]: payload.sub[this.IDField],
} as FindOptionsWhere<Entity>);

if (!user) {
throw new UnauthorizedException();
}

// delete user[this.dbPasswordField];
return user;
}

async onAfterLogout(accessToken: string) {

Check failure on line 229 in nestjs-auth/src/auth-typeorm/user-auth.service.ts

View workflow job for this annotation

GitHub Actions / build-and-test (20.10.0)

'accessToken' is defined but never used
// TODO custom your logic
return null;
}
}

0 comments on commit f736760

Please sign in to comment.