auth module controllers carried
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import crypto from 'crypto';
|
||||
import * as crypto from 'crypto';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
interface TokenConfig {
|
||||
@@ -12,28 +12,29 @@ const tokenConfig: TokenConfig = {
|
||||
};
|
||||
|
||||
class PasswordHandlers {
|
||||
generate_random_uu_id(is_string: boolean = true): string {
|
||||
generateRandomUUID(is_string: boolean = true): string {
|
||||
return is_string ? uuidv4().toString() : uuidv4();
|
||||
}
|
||||
|
||||
create_hashed_password(
|
||||
domain: string,
|
||||
uuid: string,
|
||||
password: string,
|
||||
): string {
|
||||
const data = `${domain}:${uuid}:${password}`;
|
||||
create_hashed_password(uuid: string, password: string): string {
|
||||
const data = `${uuid}:${password}`;
|
||||
console.log(crypto.createHash('sha256').update(data).digest('hex'));
|
||||
return crypto.createHash('sha256').update(data).digest('hex');
|
||||
}
|
||||
|
||||
createSelectToken(accessToken: string, userUUID: string) {
|
||||
const data = `${accessToken}:${userUUID}`;
|
||||
return crypto.createHash('sha256').update(data).digest('hex');
|
||||
}
|
||||
|
||||
check_password(
|
||||
domain: string,
|
||||
uuid: string,
|
||||
password: string,
|
||||
hashed_password: string,
|
||||
): boolean {
|
||||
return (
|
||||
this.create_hashed_password(domain, uuid, password) === hashed_password
|
||||
);
|
||||
const created_hashed_password = this.create_hashed_password(uuid, password);
|
||||
console.log('created_hashed_password', created_hashed_password);
|
||||
return created_hashed_password === hashed_password;
|
||||
}
|
||||
|
||||
generateAccessToken(): string {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
TokenDictType,
|
||||
OccupantTokenObject,
|
||||
EmployeeTokenObject,
|
||||
TokenDictTypes,
|
||||
TokenDictInterface,
|
||||
AuthToken,
|
||||
UserType,
|
||||
} from '@/src/types/auth/token';
|
||||
import { CacheService } from '@/src/cache.service';
|
||||
@@ -15,110 +15,50 @@ export class RedisHandlers {
|
||||
constructor(
|
||||
private readonly cacheService: CacheService,
|
||||
private readonly passwordService: PasswordHandlers,
|
||||
) {
|
||||
this.cacheService = cacheService;
|
||||
this.passwordService = passwordService;
|
||||
) {}
|
||||
|
||||
generateSelectToken(accessToken: string, userUUID: string) {
|
||||
return this.passwordService.createSelectToken(accessToken, userUUID);
|
||||
}
|
||||
|
||||
async process_redis_object(redis_object: any): Promise<TokenDictType> {
|
||||
if (!redis_object) {
|
||||
throw new Error('Invalid Redis object: Object is null or undefined');
|
||||
}
|
||||
if (redis_object.user_type === UserType.employee) {
|
||||
const validateEmployeeToken = (obj: any): obj is EmployeeTokenObject => {
|
||||
return (
|
||||
typeof obj === 'object' &&
|
||||
obj !== null &&
|
||||
typeof obj.user_type === 'number' &&
|
||||
typeof obj.user_uu_id === 'string' &&
|
||||
typeof obj.user_id === 'number' &&
|
||||
typeof obj.person_id === 'number' &&
|
||||
typeof obj.person_uu_id === 'string' &&
|
||||
Array.isArray(obj.companies_id_list) &&
|
||||
Array.isArray(obj.companies_uu_id_list) &&
|
||||
Array.isArray(obj.duty_id_list) &&
|
||||
Array.isArray(obj.duty_uu_id_list)
|
||||
);
|
||||
};
|
||||
const empToken: EmployeeTokenObject = {
|
||||
...redis_object,
|
||||
is_employee: true,
|
||||
is_occupant: false,
|
||||
user_type: UserType.employee,
|
||||
credential_token: redis_object.credential_token || '',
|
||||
};
|
||||
if (!validateEmployeeToken(empToken)) {
|
||||
throw new Error(
|
||||
'Invalid Redis object: Does not match EmployeeTokenObject interface',
|
||||
);
|
||||
}
|
||||
return empToken;
|
||||
}
|
||||
|
||||
if (redis_object.user_type === UserType.occupant) {
|
||||
const validateOccupantToken = (obj: any): obj is OccupantTokenObject => {
|
||||
return (
|
||||
typeof obj === 'object' &&
|
||||
obj !== null &&
|
||||
typeof obj.user_type === 'number' &&
|
||||
typeof obj.user_uu_id === 'string' &&
|
||||
typeof obj.user_id === 'number' &&
|
||||
typeof obj.person_id === 'number' &&
|
||||
typeof obj.person_uu_id === 'string'
|
||||
);
|
||||
};
|
||||
const occToken: OccupantTokenObject = {
|
||||
...redis_object,
|
||||
is_employee: false,
|
||||
is_occupant: true,
|
||||
user_type: UserType.occupant,
|
||||
credential_token: redis_object.credential_token || '',
|
||||
available_occupants: redis_object.available_occupants || null,
|
||||
};
|
||||
if (!validateOccupantToken(occToken)) {
|
||||
throw new Error(
|
||||
'Invalid Redis object: Does not match OccupantTokenObject interface',
|
||||
);
|
||||
}
|
||||
return occToken;
|
||||
}
|
||||
throw new Error(`Invalid user_type: ${redis_object.user_type}`);
|
||||
generateAccessToken() {
|
||||
return this.passwordService.generateAccessToken();
|
||||
}
|
||||
|
||||
async get_object_from_redis(access_token: string): Promise<TokenDictType> {
|
||||
const token = await this.cacheService.get(access_token);
|
||||
return this.process_redis_object(token);
|
||||
async getLoginFromRedis(redisKey: string): Promise<AuthToken> {
|
||||
return this.cacheService.get(redisKey);
|
||||
}
|
||||
|
||||
async set_login_to_redis(user: users, token: TokenDictType): Promise<any> {
|
||||
const generated_token = this.passwordService.generateAccessToken();
|
||||
const listKeys = [this.AUTH_TOKEN, generated_token, user.uu_id];
|
||||
await this.cacheService.set_with_ttl(
|
||||
this.cacheService.createRegexPattern(listKeys),
|
||||
token,
|
||||
60 * 60 * 24,
|
||||
);
|
||||
return generated_token;
|
||||
async getSelectFromRedis(redisKey: string): Promise<TokenDictInterface> {
|
||||
return this.cacheService.get(redisKey);
|
||||
}
|
||||
|
||||
async update_token_via_token(token: string, additional: any): Promise<any> {
|
||||
const listKeys = [this.AUTH_TOKEN, token, '*'];
|
||||
const accessObject = await this.cacheService.get_with_keys(listKeys);
|
||||
if (!accessObject) throw new Error('Token not found');
|
||||
const processedObject: TokenDictType =
|
||||
await this.process_redis_object(accessObject);
|
||||
if (processedObject.is_employee) {
|
||||
processedObject.selected = additional;
|
||||
}
|
||||
if (processedObject.is_occupant) {
|
||||
processedObject.selected = additional;
|
||||
}
|
||||
const listKeysNew = [this.AUTH_TOKEN, token, processedObject.user_uu_id];
|
||||
await this.cacheService.set_with_ttl(
|
||||
this.cacheService.createRegexPattern(listKeysNew),
|
||||
processedObject,
|
||||
60 * 60 * 24,
|
||||
);
|
||||
return token;
|
||||
async renewTtlLoginFromRedis(redisKey: string): Promise<any> {
|
||||
const token = await this.getLoginFromRedis(redisKey);
|
||||
return this.cacheService.set_with_ttl(redisKey, token, 60 * 30);
|
||||
}
|
||||
|
||||
async renewTtlSelectFromRedis(redisKey: string): Promise<any> {
|
||||
const token = await this.getSelectFromRedis(redisKey);
|
||||
return this.cacheService.set_with_ttl(redisKey, token, 60 * 30);
|
||||
}
|
||||
|
||||
async setLoginToRedis(token: AuthToken, userUUID: string): Promise<any> {
|
||||
const accessToken = this.generateAccessToken();
|
||||
const redisKey = `${this.AUTH_TOKEN}:${accessToken}:${accessToken}:${userUUID}:${userUUID}`;
|
||||
await this.cacheService.set_with_ttl(redisKey, token, 60 * 30);
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
async setSelectToRedis(
|
||||
accessToken: string,
|
||||
token: TokenDictInterface,
|
||||
userUUID: string,
|
||||
livingUUID: string,
|
||||
): Promise<any> {
|
||||
const selectToken = this.generateSelectToken(accessToken, userUUID);
|
||||
const redisKey = `${this.AUTH_TOKEN}:${accessToken}:${selectToken}:${userUUID}:${livingUUID}`;
|
||||
await this.cacheService.set_with_ttl(redisKey, token, 60 * 30);
|
||||
return selectToken;
|
||||
}
|
||||
}
|
||||
|
||||
95
ServicesApi/src/utils/extract-routes.ts
Normal file
95
ServicesApi/src/utils/extract-routes.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import { INestApplication, RequestMethod } from '@nestjs/common';
|
||||
import { ModulesContainer, Reflector } from '@nestjs/core';
|
||||
import { PATH_METADATA, METHOD_METADATA } from '@nestjs/common/constants';
|
||||
import { PrismaService } from '@/src/prisma.service';
|
||||
|
||||
/**
|
||||
* Helper: Method string'i döndür
|
||||
*/
|
||||
function getMethodString(requestMethod: RequestMethod): string {
|
||||
return RequestMethod[requestMethod];
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper: Path'leri normalize et (iki tane slash varsa düzelt)
|
||||
*/
|
||||
function normalizePath(...paths: string[]): string {
|
||||
const normalized =
|
||||
'/' +
|
||||
paths
|
||||
.filter(Boolean)
|
||||
.map((p) => p.replace(/^\/|\/$/g, ''))
|
||||
.filter((p) => p.length > 0)
|
||||
.join('/');
|
||||
|
||||
return normalized === '/' ? '' : normalized; // Home route'ı dışla
|
||||
}
|
||||
|
||||
export async function extractAndPersistRoutes(
|
||||
app: INestApplication,
|
||||
prisma: PrismaService,
|
||||
): Promise<{ method: string; url: string }[]> {
|
||||
const modulesContainer = app.get(ModulesContainer);
|
||||
const reflector = app.get(Reflector);
|
||||
const routes: { method: string; url: string }[] = [];
|
||||
|
||||
modulesContainer.forEach((moduleRef) => {
|
||||
const controllers = [...moduleRef.controllers.values()];
|
||||
controllers.forEach(({ metatype }) => {
|
||||
if (!metatype || typeof metatype !== 'function') return;
|
||||
|
||||
const controllerPath =
|
||||
reflector.get<string>(PATH_METADATA, metatype) ?? '';
|
||||
const prototype = metatype.prototype;
|
||||
|
||||
const methodNames = Object.getOwnPropertyNames(prototype).filter(
|
||||
(m) => m !== 'constructor',
|
||||
);
|
||||
|
||||
methodNames.forEach((methodName) => {
|
||||
const methodRef = prototype[methodName];
|
||||
const routePath = reflector.get<string>(PATH_METADATA, methodRef);
|
||||
const requestMethod = reflector.get<RequestMethod>(
|
||||
METHOD_METADATA,
|
||||
methodRef,
|
||||
);
|
||||
|
||||
if (routePath !== undefined && requestMethod !== undefined) {
|
||||
const method = getMethodString(requestMethod);
|
||||
const fullPath = normalizePath(controllerPath, routePath);
|
||||
if (fullPath !== '') {
|
||||
routes.push({ method, url: fullPath });
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const existing = await prisma.endpoint_restriction.findMany({
|
||||
select: { endpoint_name: true, endpoint_method: true },
|
||||
});
|
||||
|
||||
const existingSet = new Set(
|
||||
existing.map((r) => `${r.endpoint_method}_${r.endpoint_name}`),
|
||||
);
|
||||
|
||||
const newOnes = routes.filter(
|
||||
(r) => !existingSet.has(`${r.method}_${r.url}`),
|
||||
);
|
||||
|
||||
// İsteğe bağlı: veritabanına kaydet
|
||||
// for (const route of newOnes) {
|
||||
// await prisma.endpoint_restriction.create({
|
||||
// data: {
|
||||
// endpoint_method: route.method,
|
||||
// endpoint_name: route.url,
|
||||
// is_active: true,
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
|
||||
console.log('🧭 Route JSON Listesi:');
|
||||
console.dir(routes, { depth: null });
|
||||
|
||||
return routes;
|
||||
}
|
||||
@@ -1,9 +1,18 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { PaginationHelper } from './pagination-helper';
|
||||
import { PrismaService } from '@/src/prisma.service';
|
||||
import { RedisHandlers } from './auth/redis_handlers';
|
||||
import { PasswordHandlers } from './auth/login_handler';
|
||||
import { CacheService } from '@/src/cache.service';
|
||||
|
||||
@Module({
|
||||
providers: [PaginationHelper, PrismaService],
|
||||
exports: [PaginationHelper],
|
||||
providers: [
|
||||
PaginationHelper,
|
||||
PrismaService,
|
||||
RedisHandlers,
|
||||
PasswordHandlers,
|
||||
CacheService,
|
||||
],
|
||||
exports: [PaginationHelper, RedisHandlers, PasswordHandlers, CacheService],
|
||||
})
|
||||
export class UtilsModule {}
|
||||
|
||||
Reference in New Issue
Block a user