Initial commit after migration to gitea

This commit is contained in:
2026-01-18 11:27:43 +03:30
parent a21039410c
commit ea4b8eb543
196 changed files with 45567 additions and 9 deletions

View File

@@ -0,0 +1,63 @@
import {
ExecutionContext,
Injectable,
UnauthorizedException,
} from "@nestjs/common";
import { JwtService } from "@nestjs/jwt";
import { AuthGuard } from "@nestjs/passport";
import { ActorAuthService } from "src/auth/auth-services/actor.auth.service";
import { RoleEnum } from "src/Types&Enums/role.enum";
@Injectable()
export class LocalActorAuthGuard extends AuthGuard("actor") {
constructor(
private readonly actorAuthService: ActorAuthService,
private readonly jwtService: JwtService,
) {
super();
}
async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest();
const token = this.extractTokenFromHeader(request);
const path = request.url;
if (!token) {
if (path === "/actor/login") {
const loginData = await this.actorAuthService.loginActors(request.body);
request.user = loginData;
request.identity = request;
return true;
} else {
throw new UnauthorizedException("Token not found");
}
}
try {
const payload = await this.jwtService.verifyAsync(token, {
secret: `${process.env.SECRET}`,
});
if (
![RoleEnum.EXPERT, RoleEnum.DAMAGE_EXPERT, RoleEnum.COMPANY].includes(
payload.role,
)
) {
throw new UnauthorizedException("User role is not authorized");
}
request.user = payload;
request.identity = request.user;
} catch {
throw new UnauthorizedException("Invalid token");
}
return true;
}
private extractTokenFromHeader(request: Request): string | undefined {
//@ts-ignore
const [type, token] = request.headers.authorization?.split(" ") ?? [];
return type === "Bearer" ? token : undefined;
}
}

View File

@@ -0,0 +1,127 @@
import {
CanActivate,
ExecutionContext,
Injectable,
UnauthorizedException,
ForbiddenException,
} from "@nestjs/common";
import { JwtService } from "@nestjs/jwt";
import { RoleEnum } from "src/Types&Enums/role.enum";
import { ClaimRequestManagementDbService } from "src/claim-request-management/entites/db-service/claim-request-management.db.service";
import { Types } from "mongoose";
/**
* Guard that allows:
* - Users to access their own claim files
* - Experts to access IN_PERSON claim files they initiated
*/
@Injectable()
export class ClaimAccessGuard implements CanActivate {
constructor(
private readonly jwtService: JwtService,
private readonly claimDbService: ClaimRequestManagementDbService,
) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest();
const token = this.extractTokenFromHeader(request);
if (!token) {
throw new UnauthorizedException();
}
try {
const payload = await this.jwtService.verifyAsync(token, {
secret: `${process.env.SECRET}`,
});
// Allow users to pass through (they will be checked by service methods)
if (payload.role === RoleEnum.USER) {
request.user = payload;
request.identity = request.user;
return true;
}
// For experts, check if they're accessing an IN_PERSON claim file they initiated
if (
payload.role === RoleEnum.EXPERT ||
payload.role === RoleEnum.DAMAGE_EXPERT
) {
// Extract claimRequestId from route params
const claimRequestId =
request.params?.claimRequestId ||
request.params?.claimRequestID ||
request.params?.id;
if (!claimRequestId) {
// If no claim ID in params, allow access (e.g., for listing endpoints)
// The service will filter appropriately
request.user = payload;
request.actor = payload;
request.identity = payload;
return true;
}
// Verify expert has access to this specific claim file
const hasAccess = await this.verifyExpertClaimAccess(
claimRequestId,
payload.sub,
);
if (!hasAccess) {
throw new ForbiddenException(
"You can only access IN_PERSON claim files that you initiated",
);
}
request.user = payload;
request.actor = payload;
request.identity = payload;
return true;
}
throw new UnauthorizedException("Invalid role");
} catch (error) {
if (error instanceof ForbiddenException || error instanceof UnauthorizedException) {
throw error;
}
throw new UnauthorizedException();
}
}
private async verifyExpertClaimAccess(
claimRequestId: string,
expertId: string,
): Promise<boolean> {
try {
const claim = await this.claimDbService.findOne(claimRequestId);
if (!claim) {
return false;
}
const blameFile = claim.blameFile;
if (!blameFile) {
return false;
}
// Check if it's an expert-initiated IN_PERSON file
if (
blameFile.expertInitiated &&
blameFile.creationMethod === "IN_PERSON" &&
blameFile.initiatedBy
) {
// Verify the expert is the one who initiated it
return String(blameFile.initiatedBy) === expertId;
}
return false;
} catch (error) {
return false;
}
}
private extractTokenFromHeader(request: any): string | undefined {
const [type, token] = request.headers.authorization?.split(" ") ?? [];
return type === "Bearer" ? token : undefined;
}
}

View File

@@ -0,0 +1,44 @@
import {
CanActivate,
ExecutionContext,
Injectable,
UnauthorizedException,
} from "@nestjs/common";
import { JwtService } from "@nestjs/jwt";
import { Request } from "express";
import { RoleEnum } from "src/Types&Enums/role.enum";
@Injectable()
export class GlobalGuard implements CanActivate {
constructor(private readonly jwtService: JwtService) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest();
const token = this.extractTokenFromHeader(request);
if (!token) {
throw new UnauthorizedException();
}
try {
const payload = await this.jwtService.verifyAsync(token, {
secret: `${process.env.SECRET}`,
});
if (payload.role !== RoleEnum.USER) {
console.log(
"🚀 ~ GlobalGuard ~ canActivate ~ request.user.role:",
request.user.role,
);
throw new UnauthorizedException();
}
request.user = payload;
request.identity = request.user;
} catch {
throw new UnauthorizedException();
}
return true;
}
private extractTokenFromHeader(request: Request): string | undefined {
const [type, token] = request.headers.authorization?.split(" ") ?? [];
return type === "Bearer" ? token : undefined;
}
}

View File

@@ -0,0 +1,24 @@
import { Injectable, CanActivate, ExecutionContext } from "@nestjs/common";
import { Reflector } from "@nestjs/core";
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private readonly reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
// get the roles required
const roles = this.reflector.getAllAndOverride<string[]>("role", [
context.getHandler(),
context.getClass(),
]);
if (!roles) {
return false;
}
const request = context.switchToHttp().getRequest();
const userRoles = request.user?.role?.split(",");
return this.validateRoles(roles, userRoles);
}
validateRoles(roles: string[], userRoles: string[]) {
return roles.some((role) => userRoles.includes(role));
}
}

View File

@@ -0,0 +1,27 @@
import {
ExecutionContext,
Injectable,
NotAcceptableException,
} from "@nestjs/common";
import { AuthGuard } from "@nestjs/passport";
import { UserAuthService } from "src/auth/auth-services/user.auth.service";
@Injectable()
export class LocalUserAuthGuard extends AuthGuard("local") {
constructor(private readonly userAuthService: UserAuthService) {
super();
}
async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest();
const { username, password } = request.body;
let isValidUser = await this.userAuthService.validateUser(
username,
password,
);
if (!isValidUser) {
throw new NotAcceptableException("otp is wrong");
}
request["user"] = isValidUser;
return true;
}
}