update auth
This commit is contained in:
@@ -26,6 +26,10 @@ export class AuthGuard implements CanActivate {
|
|||||||
try {
|
try {
|
||||||
const secret = this.configService.getOrThrow<string>('JWT_SECRET');
|
const secret = this.configService.getOrThrow<string>('JWT_SECRET');
|
||||||
const token = this.extractTokenFromHeader(request);
|
const token = this.extractTokenFromHeader(request);
|
||||||
|
const slug = this.extractSlugFromHeader(request);
|
||||||
|
if (!slug) {
|
||||||
|
throw new UnauthorizedException('Slug is required');
|
||||||
|
}
|
||||||
if (!token) {
|
if (!token) {
|
||||||
throw new UnauthorizedException();
|
throw new UnauthorizedException();
|
||||||
}
|
}
|
||||||
@@ -38,6 +42,9 @@ export class AuthGuard implements CanActivate {
|
|||||||
this.logger.error('Invalid token payload structure', payload);
|
this.logger.error('Invalid token payload structure', payload);
|
||||||
throw new UnauthorizedException('Invalid token payload');
|
throw new UnauthorizedException('Invalid token payload');
|
||||||
}
|
}
|
||||||
|
if (payload.slug !== slug) {
|
||||||
|
throw new UnauthorizedException('Invalid slug');
|
||||||
|
}
|
||||||
request['userId'] = payload.userId;
|
request['userId'] = payload.userId;
|
||||||
request['restId'] = payload.restId;
|
request['restId'] = payload.restId;
|
||||||
} catch {
|
} catch {
|
||||||
@@ -57,4 +64,8 @@ export class AuthGuard implements CanActivate {
|
|||||||
const [type, token] = request.headers.authorization?.split(' ') ?? [];
|
const [type, token] = request.headers.authorization?.split(' ') ?? [];
|
||||||
return type === 'Bearer' ? token : undefined;
|
return type === 'Bearer' ? token : undefined;
|
||||||
}
|
}
|
||||||
|
private extractSlugFromHeader(request: Request): string | undefined {
|
||||||
|
const slug = request.headers['X-Slug'] as string;
|
||||||
|
return slug;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
export interface ITokenPayload {
|
export interface ITokenPayload {
|
||||||
userId: string;
|
userId: string;
|
||||||
restId: string;
|
restId: string;
|
||||||
|
slug: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IAdminTokenPayload {
|
export interface IAdminTokenPayload {
|
||||||
|
|||||||
@@ -28,9 +28,11 @@ export class AuthService {
|
|||||||
) {
|
) {
|
||||||
this.OTP_EXPIRATION_TIME = this.configService.get<number>('OTP_EXPIRATION_TIME') ?? 240;
|
this.OTP_EXPIRATION_TIME = this.configService.get<number>('OTP_EXPIRATION_TIME') ?? 240;
|
||||||
}
|
}
|
||||||
|
|
||||||
private userOtpKey(restaurantSlug: string, phone: string) {
|
private userOtpKey(restaurantSlug: string, phone: string) {
|
||||||
return `otp:${restaurantSlug}:${phone}`;
|
return `otp:${restaurantSlug}:${phone}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private adminOtpKey(restaurantSlug: string, phone: string) {
|
private adminOtpKey(restaurantSlug: string, phone: string) {
|
||||||
return `otp-admin:${restaurantSlug}:${phone}`;
|
return `otp-admin:${restaurantSlug}:${phone}`;
|
||||||
}
|
}
|
||||||
@@ -64,7 +66,7 @@ export class AuthService {
|
|||||||
throw new BadRequestException(RestMessage.NOT_FOUND);
|
throw new BadRequestException(RestMessage.NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
const tokens = await this.tokensService.generateAccessAndRefreshToken(user.id, rest.id, false);
|
const tokens = await this.tokensService.generateAccessAndRefreshToken(user.id, rest.id, false, slug);
|
||||||
|
|
||||||
const userResponse = UserLoginTransformer.transform(user, rest);
|
const userResponse = UserLoginTransformer.transform(user, rest);
|
||||||
|
|
||||||
@@ -93,7 +95,7 @@ export class AuthService {
|
|||||||
throw new BadRequestException(RestMessage.NOT_FOUND);
|
throw new BadRequestException(RestMessage.NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
const tokens = await this.tokensService.generateAccessAndRefreshToken(admin.id, rest.id, true);
|
const tokens = await this.tokensService.generateAccessAndRefreshToken(admin.id, rest.id, true, slug);
|
||||||
|
|
||||||
const adminResponse = await AdminLoginTransformer.transform(admin, rest);
|
const adminResponse = await AdminLoginTransformer.transform(admin, rest);
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import dayjs from 'dayjs';
|
|||||||
import { AuthMessage } from '../../../common/enums/message.enum';
|
import { AuthMessage } from '../../../common/enums/message.enum';
|
||||||
import { RefreshToken, RefreshTokenType } from '../entities/refresh-token.entity';
|
import { RefreshToken, RefreshTokenType } from '../entities/refresh-token.entity';
|
||||||
import { IAdminTokenPayload, ITokenPayload } from '../interfaces/IToken-payload';
|
import { IAdminTokenPayload, ITokenPayload } from '../interfaces/IToken-payload';
|
||||||
|
import { Restaurant } from 'src/modules/restaurants/entities/restaurant.entity';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TokensService {
|
export class TokensService {
|
||||||
@@ -18,13 +19,13 @@ export class TokensService {
|
|||||||
private readonly em: EntityManager,
|
private readonly em: EntityManager,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async generateAccessAndRefreshToken(ownerId: string, restaurantId: string, isAdmin: boolean) {
|
async generateAccessAndRefreshToken(ownerId: string, restaurantId: string, isAdmin: boolean, slug: string) {
|
||||||
const refreshExpire = this.configService.getOrThrow<number>('REFRESH_TOKEN_EXPIRE');
|
const refreshExpire = this.configService.getOrThrow<number>('REFRESH_TOKEN_EXPIRE');
|
||||||
const accessExpire = this.configService.getOrThrow<number>('JWT_EXPIRATION_TIME');
|
const accessExpire = this.configService.getOrThrow<number>('JWT_EXPIRATION_TIME');
|
||||||
|
|
||||||
const payload: ITokenPayload | IAdminTokenPayload = isAdmin
|
const payload: ITokenPayload | IAdminTokenPayload = isAdmin
|
||||||
? { adminId: ownerId, restId: restaurantId }
|
? { adminId: ownerId, restId: restaurantId }
|
||||||
: { userId: ownerId, restId: restaurantId };
|
: { userId: ownerId, restId: restaurantId, slug };
|
||||||
|
|
||||||
const accessToken = await this.generateAccessToken(payload, accessExpire);
|
const accessToken = await this.generateAccessToken(payload, accessExpire);
|
||||||
const refreshToken = this.generateRefreshToken();
|
const refreshToken = this.generateRefreshToken();
|
||||||
@@ -78,12 +79,16 @@ export class TokensService {
|
|||||||
const ownerId = token.ownerId;
|
const ownerId = token.ownerId;
|
||||||
const restId = token.restId;
|
const restId = token.restId;
|
||||||
|
|
||||||
|
const restaurant = await this.em.findOne(Restaurant, { id: restId });
|
||||||
|
if (!restaurant) {
|
||||||
|
throw new UnauthorizedException(AuthMessage.INVALID_REFRESH_TOKEN);
|
||||||
|
}
|
||||||
// Remove the old token
|
// Remove the old token
|
||||||
this.em.remove(token);
|
this.em.remove(token);
|
||||||
const isAdmin = token.type === RefreshTokenType.ADMIN;
|
const isAdmin = token.type === RefreshTokenType.ADMIN;
|
||||||
try {
|
try {
|
||||||
// Generate new tokens
|
// Generate new tokens
|
||||||
const tokens = await this.generateAccessAndRefreshToken(ownerId, restId, isAdmin);
|
const tokens = await this.generateAccessAndRefreshToken(ownerId, restId, isAdmin, restaurant.slug);
|
||||||
|
|
||||||
// Commit the transaction
|
// Commit the transaction
|
||||||
await this.em.flush();
|
await this.em.flush();
|
||||||
|
|||||||
Reference in New Issue
Block a user