feat(auth): add UserGuard and AdminGuard

This commit introduces UserGuard and AdminGuard, two new authorization guards. These guards verify the access permissions of users and admin respectively, by checking the provided token in the authorization header. Unauthorized users will receive UnauthorizedException.
This commit is contained in:
Mathis H (Avnyr) 2024-07-12 14:08:09 +02:00
parent a4096d291d
commit a157553b78
Signed by: Mathis
GPG Key ID: DD9E0666A747D126

81
src/auth/auth.guard.ts Normal file
View File

@ -0,0 +1,81 @@
import { Injectable, CanActivate, ExecutionContext, UnauthorizedException } from '@nestjs/common';
import { Request } from 'express';
import { CredentialsService } from "src/credentials/credentials.service";
import { DrizzleService } from "src/drizzle/drizzle.service";
import { UsersTable } from "src/schema";
import { eq } from "drizzle-orm";
@Injectable()
export class UserGuard implements CanActivate {
constructor(
private readonly credentialService: CredentialsService,
private readonly databaseService: DrizzleService
) {}
async canActivate(
context: ExecutionContext,
): Promise<boolean> {
const request: Request = context.switchToHttp().getRequest();
const authHeader = request.headers.authorization;
if (!authHeader)
throw new UnauthorizedException('No authorization header found.');
const token = authHeader.split(' ')[1];
const vToken = await this.credentialService.verifyAuthToken(token)
const user = await this.databaseService.use()
.select()
.from(UsersTable)
.where(eq(UsersTable.uuid, vToken.payload.sub))
if (user.length !== 1)
throw new UnauthorizedException('No such user found.');
if (user[0].emailCode)
throw new UnauthorizedException('Email not verified.');
// Inject user ID into request body
request.body.sourceUserId = vToken.payload.sub;
return true;
}
}
@Injectable()
export class AdminGuard implements CanActivate {
constructor(
private readonly credentialService: CredentialsService,
private readonly databaseService: DrizzleService
) {}
async canActivate(
context: ExecutionContext,
): Promise<boolean> {
const request: Request = context.switchToHttp().getRequest();
const authHeader = request.headers.authorization;
if (!authHeader)
throw new UnauthorizedException('No authorization header found.');
const token = authHeader.split(' ')[1];
const vToken = await this.credentialService.verifyAuthToken(token)
const user = await this.databaseService.use()
.select()
.from(UsersTable)
.where(eq(UsersTable.uuid, vToken.payload.sub))
if (user.length !== 1)
throw new UnauthorizedException('No such user found.');
if (!user[0].isAdmin) {
throw new UnauthorizedException('Administrator only..');
}
// Inject user ID into request body
request.body.sourceUserId = vToken.payload.sub;
return true;
}
}