feat: added auth guard and some decorators
This commit is contained in:
@@ -25,6 +25,7 @@
|
|||||||
"@nestjs/config": "^4.0.4",
|
"@nestjs/config": "^4.0.4",
|
||||||
"@nestjs/core": "^11.1.28",
|
"@nestjs/core": "^11.1.28",
|
||||||
"@nestjs/jwt": "^11.0.2",
|
"@nestjs/jwt": "^11.0.2",
|
||||||
|
"@nestjs/passport": "^11.0.5",
|
||||||
"@nestjs/platform-express": "^11.1.28",
|
"@nestjs/platform-express": "^11.1.28",
|
||||||
"@nestjs/swagger": "^11.4.6",
|
"@nestjs/swagger": "^11.4.6",
|
||||||
"@nestjs/typeorm": "^11.0.3",
|
"@nestjs/typeorm": "^11.0.3",
|
||||||
@@ -34,6 +35,7 @@
|
|||||||
"class-validator": "^0.15.1",
|
"class-validator": "^0.15.1",
|
||||||
"joi": "^18.2.3",
|
"joi": "^18.2.3",
|
||||||
"ms": "^2.1.3",
|
"ms": "^2.1.3",
|
||||||
|
"passport": "^0.7.0",
|
||||||
"passport-jwt": "^4.0.1",
|
"passport-jwt": "^4.0.1",
|
||||||
"pg": "^8.22.0",
|
"pg": "^8.22.0",
|
||||||
"reflect-metadata": "^0.2.2",
|
"reflect-metadata": "^0.2.2",
|
||||||
|
|||||||
Generated
+38
@@ -23,6 +23,9 @@ importers:
|
|||||||
'@nestjs/jwt':
|
'@nestjs/jwt':
|
||||||
specifier: ^11.0.2
|
specifier: ^11.0.2
|
||||||
version: 11.0.2(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))
|
version: 11.0.2(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))
|
||||||
|
'@nestjs/passport':
|
||||||
|
specifier: ^11.0.5
|
||||||
|
version: 11.0.5(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0)
|
||||||
'@nestjs/platform-express':
|
'@nestjs/platform-express':
|
||||||
specifier: ^11.1.28
|
specifier: ^11.1.28
|
||||||
version: 11.1.28(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)
|
version: 11.1.28(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)
|
||||||
@@ -50,6 +53,9 @@ importers:
|
|||||||
ms:
|
ms:
|
||||||
specifier: ^2.1.3
|
specifier: ^2.1.3
|
||||||
version: 2.1.3
|
version: 2.1.3
|
||||||
|
passport:
|
||||||
|
specifier: ^0.7.0
|
||||||
|
version: 0.7.0
|
||||||
passport-jwt:
|
passport-jwt:
|
||||||
specifier: ^4.0.1
|
specifier: ^4.0.1
|
||||||
version: 4.0.1
|
version: 4.0.1
|
||||||
@@ -788,6 +794,12 @@ packages:
|
|||||||
class-validator:
|
class-validator:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@nestjs/passport@11.0.5':
|
||||||
|
resolution: {integrity: sha512-ulQX6mbjlws92PIM15Naes4F4p2JoxGnIJuUsdXQPT+Oo2sqQmENEZXM7eYuimocfHnKlcfZOuyzbA33LwUlOQ==}
|
||||||
|
peerDependencies:
|
||||||
|
'@nestjs/common': ^10.0.0 || ^11.0.0
|
||||||
|
passport: ^0.5.0 || ^0.6.0 || ^0.7.0
|
||||||
|
|
||||||
'@nestjs/platform-express@11.1.28':
|
'@nestjs/platform-express@11.1.28':
|
||||||
resolution: {integrity: sha512-hU+9Sz4m+onHrR5AmelI59QKmY/Re546bPnygnpqqeQdHDiJpBgjWbL4t6Jr73CBpS60cpyng7WzjgphNB9iwA==}
|
resolution: {integrity: sha512-hU+9Sz4m+onHrR5AmelI59QKmY/Re546bPnygnpqqeQdHDiJpBgjWbL4t6Jr73CBpS60cpyng7WzjgphNB9iwA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -2650,6 +2662,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==}
|
resolution: {integrity: sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==}
|
||||||
engines: {node: '>= 0.4.0'}
|
engines: {node: '>= 0.4.0'}
|
||||||
|
|
||||||
|
passport@0.7.0:
|
||||||
|
resolution: {integrity: sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==}
|
||||||
|
engines: {node: '>= 0.4.0'}
|
||||||
|
|
||||||
path-exists@4.0.0:
|
path-exists@4.0.0:
|
||||||
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -2677,6 +2693,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
|
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
pause@0.0.1:
|
||||||
|
resolution: {integrity: sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==}
|
||||||
|
|
||||||
pg-cloudflare@1.4.0:
|
pg-cloudflare@1.4.0:
|
||||||
resolution: {integrity: sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==}
|
resolution: {integrity: sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==}
|
||||||
|
|
||||||
@@ -3303,6 +3322,10 @@ packages:
|
|||||||
util-deprecate@1.0.2:
|
util-deprecate@1.0.2:
|
||||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||||
|
|
||||||
|
utils-merge@1.0.1:
|
||||||
|
resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
|
||||||
|
engines: {node: '>= 0.4.0'}
|
||||||
|
|
||||||
v8-compile-cache-lib@3.0.1:
|
v8-compile-cache-lib@3.0.1:
|
||||||
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
|
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
|
||||||
|
|
||||||
@@ -4237,6 +4260,11 @@ snapshots:
|
|||||||
class-transformer: 0.5.1
|
class-transformer: 0.5.1
|
||||||
class-validator: 0.15.1
|
class-validator: 0.15.1
|
||||||
|
|
||||||
|
'@nestjs/passport@11.0.5(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0)':
|
||||||
|
dependencies:
|
||||||
|
'@nestjs/common': 11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
|
passport: 0.7.0
|
||||||
|
|
||||||
'@nestjs/platform-express@11.1.28(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)':
|
'@nestjs/platform-express@11.1.28(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nestjs/common': 11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
'@nestjs/common': 11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
@@ -6306,6 +6334,12 @@ snapshots:
|
|||||||
|
|
||||||
passport-strategy@1.0.0: {}
|
passport-strategy@1.0.0: {}
|
||||||
|
|
||||||
|
passport@0.7.0:
|
||||||
|
dependencies:
|
||||||
|
passport-strategy: 1.0.0
|
||||||
|
pause: 0.0.1
|
||||||
|
utils-merge: 1.0.1
|
||||||
|
|
||||||
path-exists@4.0.0: {}
|
path-exists@4.0.0: {}
|
||||||
|
|
||||||
path-is-absolute@1.0.1: {}
|
path-is-absolute@1.0.1: {}
|
||||||
@@ -6326,6 +6360,8 @@ snapshots:
|
|||||||
|
|
||||||
path-type@4.0.0: {}
|
path-type@4.0.0: {}
|
||||||
|
|
||||||
|
pause@0.0.1: {}
|
||||||
|
|
||||||
pg-cloudflare@1.4.0:
|
pg-cloudflare@1.4.0:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -6893,6 +6929,8 @@ snapshots:
|
|||||||
|
|
||||||
util-deprecate@1.0.2: {}
|
util-deprecate@1.0.2: {}
|
||||||
|
|
||||||
|
utils-merge@1.0.1: {}
|
||||||
|
|
||||||
v8-compile-cache-lib@3.0.1: {}
|
v8-compile-cache-lib@3.0.1: {}
|
||||||
|
|
||||||
v8-to-istanbul@9.3.0:
|
v8-to-istanbul@9.3.0:
|
||||||
|
|||||||
+31
-32
@@ -1,58 +1,57 @@
|
|||||||
import { Body, Controller, Post } from "@nestjs/common";
|
import { Body, Controller, Get, Post, Req, UseGuards } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger";
|
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||||
import { AuthService } from "./auth.service";
|
import { AuthService } from './auth.service';
|
||||||
import { SendOtpDto } from "./DTO/send-otp.dto";
|
import { SendOtpDto } from './DTO/send-otp.dto';
|
||||||
import { LoginCredentialDto } from "./DTO/login-credential.dto";
|
import { LoginCredentialDto } from './DTO/login-credential.dto';
|
||||||
import { VerifyOtpDto } from "./DTO/verify-otp.dto";
|
import { VerifyOtpDto } from './DTO/verify-otp.dto';
|
||||||
|
import { AuthGuard } from 'src/common/decorators/auth-guard.decorator';
|
||||||
|
import type { IRequest } from './interfaces/IRequest';
|
||||||
|
import { UserDec } from 'src/common/decorators/user.decorator';
|
||||||
|
|
||||||
@ApiTags('Authentication')
|
@ApiTags('Authentication')
|
||||||
@Controller('auth')
|
@Controller('auth')
|
||||||
export class AuthController {
|
export class AuthController {
|
||||||
constructor(
|
constructor(private readonly authService: AuthService) {}
|
||||||
private readonly authService: AuthService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
@Post('send-otp')
|
@Post('send-otp')
|
||||||
@ApiOperation({
|
@ApiOperation({
|
||||||
summary: 'Send OTP to a phone number',
|
summary: 'Send OTP to a phone number',
|
||||||
})
|
})
|
||||||
@ApiResponse({status: 200, description: 'Sent Otp Successfully!'})
|
@ApiResponse({ status: 200, description: 'Sent Otp Successfully!' })
|
||||||
@ApiResponse({status: 400, description: 'Bad Request from User!'})
|
@ApiResponse({ status: 400, description: 'Bad Request from User!' })
|
||||||
async sendOtp(
|
async sendOtp(@Body() dto: SendOtpDto) {
|
||||||
@Body() dto: SendOtpDto
|
|
||||||
) {
|
|
||||||
return this.authService.sendOTP(dto.phoneNumber);
|
return this.authService.sendOTP(dto.phoneNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('verify-otp')
|
@Post('verify-otp')
|
||||||
@ApiOperation({
|
@ApiOperation({
|
||||||
summary: 'Verify OTP.'
|
summary: 'Verify OTP.',
|
||||||
})
|
})
|
||||||
@ApiResponse({status: 200, description: 'Verified Otp Successfully!'})
|
@ApiResponse({ status: 200, description: 'Verified Otp Successfully!' })
|
||||||
@ApiResponse({status: 400, description: 'Bad Request from the user'})
|
@ApiResponse({ status: 400, description: 'Bad Request from the user' })
|
||||||
async verifyOtp(
|
async verifyOtp(@Body() dto: VerifyOtpDto) {
|
||||||
@Body() dto: VerifyOtpDto
|
|
||||||
) {
|
|
||||||
return this.authService.verifyOTP(dto);
|
return this.authService.verifyOTP(dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('check-credential')
|
@Post('check-credential')
|
||||||
@ApiOperation({summary: 'Check Login Credentials. If Valid Sends OTP'})
|
@ApiOperation({ summary: 'Check Login Credentials. If Valid Sends OTP' })
|
||||||
@ApiResponse({status: 200, description: 'Valid Credentials!'})
|
@ApiResponse({ status: 200, description: 'Valid Credentials!' })
|
||||||
@ApiResponse({status: 400, description: 'Credentials Invalid!'})
|
@ApiResponse({ status: 400, description: 'Credentials Invalid!' })
|
||||||
async checkLoginCredential(
|
async checkLoginCredential(@Body() dto: LoginCredentialDto) {
|
||||||
@Body() dto: LoginCredentialDto
|
|
||||||
) {
|
|
||||||
return this.authService.checkLoginCredentials(dto);
|
return this.authService.checkLoginCredentials(dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('verify-login')
|
@Post('verify-login')
|
||||||
@ApiOperation({summary: 'verifies OTP and then login'})
|
@ApiOperation({ summary: 'verifies OTP and then login' })
|
||||||
@ApiResponse({status: 200, description: 'User Logged in successfully!'})
|
@ApiResponse({ status: 200, description: 'User Logged in successfully!' })
|
||||||
@ApiResponse({status: 400, description: 'Bad Request From The User'})
|
@ApiResponse({ status: 400, description: 'Bad Request From The User' })
|
||||||
async verifyOtpAndLogin(
|
async verifyOtpAndLogin(@Body() verifyOtpDto: VerifyOtpDto) {
|
||||||
@Body() verifyOtpDto: VerifyOtpDto
|
|
||||||
) {
|
|
||||||
return this.authService.verifyOtpAndLogin(verifyOtpDto);
|
return this.authService.verifyOtpAndLogin(verifyOtpDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@AuthGuard()
|
||||||
|
@Get('profile')
|
||||||
|
profile(@Req() req: IRequest, @UserDec('id') userId: string) {
|
||||||
|
return req.user;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -10,15 +10,19 @@ import { OtpRepository } from './repositories/otp.repository';
|
|||||||
import { UsersModule } from 'src/users/users.module';
|
import { UsersModule } from 'src/users/users.module';
|
||||||
import { ConfigService } from '@nestjs/config';
|
import { ConfigService } from '@nestjs/config';
|
||||||
import { UserRole } from 'src/users/entities/user-role.entity';
|
import { UserRole } from 'src/users/entities/user-role.entity';
|
||||||
|
import { PassportModule } from '@nestjs/passport';
|
||||||
|
import { JwtStrategy } from './strategies/jwt.strategy';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
TypeOrmModule.forFeature([OTP]),
|
TypeOrmModule.forFeature([OTP]),
|
||||||
|
PassportModule,
|
||||||
JwtModule.register({}),
|
JwtModule.register({}),
|
||||||
UtilsModule,
|
UtilsModule,
|
||||||
UsersModule,
|
UsersModule,
|
||||||
],
|
],
|
||||||
controllers: [AuthController],
|
controllers: [AuthController],
|
||||||
providers: [AuthService, OtpRepository],
|
providers: [AuthService, OtpRepository, JwtStrategy],
|
||||||
|
exports: [JwtModule, PassportModule]
|
||||||
})
|
})
|
||||||
export class AuthModule {}
|
export class AuthModule {}
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ export class AuthService {
|
|||||||
const roles = user.roles.map((r) => r.role);
|
const roles = user.roles.map((r) => r.role);
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
sub: user.id,
|
id: user.id,
|
||||||
phone: user.phone,
|
phone: user.phone,
|
||||||
roles,
|
roles,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import { ExecutionContext, Injectable, UnauthorizedException } from '@nestjs/common';
|
||||||
|
import { Reflector } from '@nestjs/core';
|
||||||
|
import { AuthGuard } from '@nestjs/passport';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { SKIP_AUTH_KEY } from 'src/common/decorators/skip-auth.decorator';
|
||||||
|
import { AuthMessages } from 'src/common/enums/messages.enum';
|
||||||
|
import { JWT_STRATEGY_NAME } from 'src/constants';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class JwtAuthGuard extends AuthGuard(JWT_STRATEGY_NAME) {
|
||||||
|
constructor(private reflector: Reflector) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
canActivate(
|
||||||
|
context: ExecutionContext,
|
||||||
|
): boolean | Promise<boolean> | Observable<boolean> {
|
||||||
|
const skipAuth = this.reflector.getAllAndOverride<boolean>(SKIP_AUTH_KEY, [
|
||||||
|
context.getHandler(),
|
||||||
|
context.getClass(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (skipAuth) return true;
|
||||||
|
|
||||||
|
return super.canActivate(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleRequest(err: unknown, user: any, _info: unknown) {
|
||||||
|
if (err || !user)
|
||||||
|
throw new UnauthorizedException(AuthMessages.TOKEN_EXPIRED_OR_INVALID);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { ITokenPayload } from "./IToken-payload";
|
||||||
|
import { IUserIpAndHeaders } from "./IUserIpAndHeader";
|
||||||
|
|
||||||
|
export interface IRequest {
|
||||||
|
user?: ITokenPayload,
|
||||||
|
ip_header?: IUserIpAndHeaders
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { RoleType } from "src/users/enums/user-role.enum";
|
||||||
|
|
||||||
|
export interface ITokenPayload {
|
||||||
|
id: string;
|
||||||
|
phone: string;
|
||||||
|
roles: RoleType[];
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
export interface IUserIpAndHeaders {
|
||||||
|
ip: string;
|
||||||
|
headers: Record<string, string>;
|
||||||
|
userId: string;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { RoleType } from 'src/users/enums/user-role.enum';
|
||||||
|
import { PassportStrategy } from '@nestjs/passport';
|
||||||
|
import { Strategy, ExtractJwt } from 'passport-jwt';
|
||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
import { JWT_STRATEGY_NAME } from 'src/constants';
|
||||||
|
import { ITokenPayload } from '../interfaces/IToken-payload';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class JwtStrategy extends PassportStrategy(Strategy, JWT_STRATEGY_NAME) {
|
||||||
|
constructor(configService: ConfigService) {
|
||||||
|
super({
|
||||||
|
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
||||||
|
ignoreExpiration: false,
|
||||||
|
secretOrKey: configService.getOrThrow<string>('JWT_ACCESS_SECRET'),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async validate(payload: ITokenPayload) {
|
||||||
|
return {
|
||||||
|
id: payload.id,
|
||||||
|
phone: payload.phone,
|
||||||
|
roles: payload.roles
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { applyDecorators, UseGuards } from "@nestjs/common";
|
||||||
|
import { ApiBearerAuth } from "@nestjs/swagger";
|
||||||
|
import { JwtAuthGuard } from "src/auth/guards/jwt-auth.guard";
|
||||||
|
|
||||||
|
export function AuthGuard() {
|
||||||
|
return applyDecorators(
|
||||||
|
UseGuards(JwtAuthGuard),
|
||||||
|
ApiBearerAuth('authorization')
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { SetMetadata } from "@nestjs/common";
|
||||||
|
|
||||||
|
export const SKIP_AUTH_KEY = "skipAuth";
|
||||||
|
|
||||||
|
export const skipAuth = () => SetMetadata(SKIP_AUTH_KEY, true);
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
|
||||||
|
import { IRequest } from 'src/auth/interfaces/IRequest';
|
||||||
|
import { ITokenPayload } from 'src/auth/interfaces/IToken-payload';
|
||||||
|
|
||||||
|
export const UserDec = createParamDecorator(
|
||||||
|
(data: keyof ITokenPayload | undefined, ctx: ExecutionContext) => {
|
||||||
|
const req = ctx.switchToHttp().getRequest<IRequest>();
|
||||||
|
const user = req.user;
|
||||||
|
|
||||||
|
return data ? user?.[data] : user;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export const UserIpAndHeaders = createParamDecorator(
|
||||||
|
(_data: unknown, ctx: ExecutionContext) => {
|
||||||
|
const req = ctx.switchToHttp().getRequest<IRequest>();
|
||||||
|
const user = req.user;
|
||||||
|
const ip_header = req.ip_header;
|
||||||
|
|
||||||
|
return { ip: ip_header?.ip, headers: ip_header?.headers, userId: user?.id };
|
||||||
|
},
|
||||||
|
);
|
||||||
@@ -15,3 +15,7 @@ export enum OTPMessages {
|
|||||||
export enum UserRoleMessages {
|
export enum UserRoleMessages {
|
||||||
USER_ROLE_ALREADY_EXISTS = 'نقش مورد نظر برای کاربر مد نظر وجود دارد!'
|
USER_ROLE_ALREADY_EXISTS = 'نقش مورد نظر برای کاربر مد نظر وجود دارد!'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum AuthMessages {
|
||||||
|
TOKEN_EXPIRED_OR_INVALID = 'توکن منسوخ شده یا نامعتبر است!',
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export const JWT_STRATEGY_NAME = "jwt_Strategy";
|
||||||
Reference in New Issue
Block a user