production-evyos-systems-an.../ServicesApi/src/utils/auth/redis_handlers.ts

125 lines
4.2 KiB
TypeScript

import {
TokenDictType,
OccupantTokenObject,
EmployeeTokenObject,
UserType,
} from '@/src/types/auth/token';
import { CacheService } from '@/src/cache.service';
import { users } from '@prisma/client';
import { PasswordHandlers } from './login_handler';
import { Injectable } from '@nestjs/common';
@Injectable()
export class RedisHandlers {
AUTH_TOKEN = 'AUTH_TOKEN';
constructor(
private readonly cacheService: CacheService,
private readonly passwordService: PasswordHandlers,
) {
this.cacheService = cacheService;
this.passwordService = passwordService;
}
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}`);
}
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 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 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;
}
}