brief-08-back/src/auth/auth.guard.ts
Mathis 27f79d4e46
feat(auth): add user management endpoint and update guards
Introduce new "me" endpoints for fetching, updating, and deleting current user data. Update guards to properly inject dependent services using @Inject decorator for better DI handling.
2024-07-24 20:25:46 +02:00

85 lines
2.6 KiB
TypeScript

import { Injectable, CanActivate, ExecutionContext, UnauthorizedException, Inject } 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";
import { Reflector } from "@nestjs/core";
@Injectable()
export class UserGuard implements CanActivate {
constructor(
@Inject(CredentialsService) private readonly credentialService: CredentialsService,
@Inject(DrizzleService) 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(
@Inject(CredentialsService) private readonly credentialService: CredentialsService,
@Inject(DrizzleService) 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;
}
}