Files
keyvault/api/src/modules/key/key.service.ts
2026-03-05 14:51:45 +01:00

234 lines
7.7 KiB
TypeScript

import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { Customer, Cylinder, Key, User } from 'src/model/entitites';
import {
CylinderRepository,
KeyRepository,
KeySystemRepository,
} from 'src/model/repositories';
import { KeyHandoutRepository } from 'src/model/repositories/key-handout.repository';
import { ActivityHelperService } from 'src/shared/service/activity.logger.service';
import { HelperService } from 'src/shared/service/system.helper.service';
import { FindOperator, IsNull, Not } from 'typeorm';
import { faker } from '@faker-js/faker';
import { ConfigService } from '@nestjs/config';
import { MailService } from '../mail/mail.service';
import { SseService } from '../realtime/sse/sse.service';
@Injectable()
export class KeyService {
constructor(
private readonly keyrepository: KeyRepository,
private readonly cylinderRepository: CylinderRepository,
private readonly handoverRepo: KeyHandoutRepository,
private readonly activityService: ActivityHelperService,
private readonly helper: HelperService,
private readonly configService: ConfigService,
private readonly mailService: MailService,
private readonly sseService: SseService
) {
console.log("INIT KEYSERVICE")
}
get isDevelopMode(): boolean {
return (this.configService.get('DEVELOP_MODE') || '').toLowerCase() == 'true';
}
async getUsersKeys(user: User): Promise<Key[]> {
let keys = await this.keyrepository.find({
where: { cylinder: { system: { managers: { id: user.id } } }, keyLost: IsNull() },
relations: ['cylinder', 'cylinder.system', 'customer'],
});
for (let k of keys) {
k.customer = await this.getCustomerOfLastHandout(user, k.id);
}
if (this.isDevelopMode) {
keys = keys.filter(k => k.cylinder.some(c => c.name.toLowerCase().includes('develop') || c.system.name.toLowerCase().includes('develop')))
}
return keys;
}
async getLostKeys(user: User): Promise<Key[]> {
let keys = await this.keyrepository.find({
where: { cylinder: { system: { managers: { id: user.id } } }, keyLost: Not(IsNull()) },
relations: ['cylinder', 'cylinder.system', 'customer'],
});
for (let k of keys) {
k.customer = await this.getCustomerOfLastHandout(user, k.id);
}
if (this.isDevelopMode) {
keys = keys.filter(k => k.cylinder.some(c => c.name.toLowerCase().includes('develop') || c.system.name.toLowerCase().includes('develop')))
}
return keys;
}
async updateKey(user: User, key: Key) {
if (!user || !user.id) {
throw new HttpException('forbidden', HttpStatus.FORBIDDEN);
}
const k = await this.keyrepository.findOneOrFail({
where: { id: key.id, cylinder: { system: { managers: { id: user.id } } } },
relations: ['cylinder', 'cylinder.system'],
withDeleted: true
});
if (k.name != key.name) {
await this.activityService.logKeyRenamed(user, key, key.cylinder[0].system, k.name);
}
if (k.keyLost != key.keyLost) {
await this.activityService.logKeyLostUpdate(user, key, key.keyLost);
try {
const k = await this.keyrepository.findOne({
where: { id: key.id },
relations: ['cylinder', 'cylinder.system', 'cylinder.system.managers', 'cylinder.system.managers.settings'],
withDeleted: false
});
for (const to of k.cylinder[0].system.managers.filter(m => m.settings.sendSystemUpdateMails)) {
this.mailService.sendKeyLostOrFoundMail({ key, to } )
}
} catch (e) {
console.error(e);
}
}
const saved = await this.keyrepository.save(this.keyrepository.create(key));
this.sendKeysToSSE(saved);
return saved;
}
private async sendKeysToSSE(key: Key) {
const system = await this.helper.getSystemOfKey(key)
for (let manager of system.managers) {
const keys = await this.getUsersKeys(manager);
this.sseService.sendKeysToUsers(manager.id, keys)
}
}
async getUsersCylinders(user: User): Promise<Cylinder[]> {
if (!user || !user.id) {
throw new HttpException('forbidden', HttpStatus.FORBIDDEN);
}
return this.cylinderRepository.find({
where: { system: { managers: { id: user.id } } },
order: { name: { direction: 'ASC' } },
relations: ['system'],
});
}
async handoverKey(user: User, data: any, keyID: string) {
const key: Key = await this.keyrepository.findOneOrFail({
where: { id: keyID, cylinder: { system: { managers: { id: user.id } } } },
relations: [ 'cylinder', 'cylinder.system' ]
});
key.handedOut = data.direction == 'out';
this.keyrepository.save(key);
const res = await this.handoverRepo.save(
this.handoverRepo.create({
customer: data.customer,
direction: data.direction,
timestamp: data.timestamp,
key: key,
user: user as any
}),
);
this.activityService.logKeyHandover(user, key, key.cylinder[0].system, res);
try {
if (key && key.cylinder && key.cylinder[0].system) {
const managerOb: Key = await this.keyrepository.findOne({
where: { id: keyID },
relations: [ 'cylinder', 'cylinder.system', 'cylinder.system.managers', 'cylinder.system.managers.settings' ]
});
managerOb.cylinder[0].system.managers.filter(m => m.settings.sendSystemUpdateMails).forEach(m => {
this.mailService.sendKeyHandoutMail({ to: m, key, handoutAction: res })
})
}
} catch (e){
console.log(e)
}
this.sendKeysToSSE(key);
return res;
}
getKeyHandovers(user: User, keyID: string) {
return this.handoverRepo.find({
where: {
key: { cylinder: { system: { managers: { id: user.id } } }, id: keyID },
},
order: {
timestamp: { direction: 'DESC' },
created: { direction: 'DESC' },
},
relations: ['customer'],
});
}
async getCustomerOfLastHandout (user: User, keyID: string): Promise<Customer> {
const handover = await this.handoverRepo.find({
where: {
key: { cylinder: { system: { managers: { id: user.id } } }, id: keyID },
},
order: {
timestamp: { direction: 'DESC' },
created: { direction: 'DESC' },
},
relations: ['customer'],
take: 1
});
if (handover.length == 1 && handover[0].direction == 'out') {
return handover[0].customer;
} else {
return null;
}
}
async createKey(user: User, key: any): Promise<Key> {
const k = await this.keyrepository.save(this.keyrepository.create(key)) as any as Key;
this.activityService.logKeyCreated(user, key, key.cylinder[0].system);
this.sendKeysToSSE(k as any)
return k;
}
async deleteKey(user: User, id: string): Promise<Key> {
const key = await this.keyrepository.findOneOrFail({
where: { id, cylinder: { system: { managers: { id: user.id } } } },
});
await this.activityService.logDeleteKey(user, key);
const k = await this.keyrepository.softRemove(key);
this.sendKeysToSSE(k)
return k;
}
getDeletedKeys(user: User) {
return this.keyrepository.find({
where: {
cylinder: { system: { managers: { id: user.id } } },
deletedAt: Not(IsNull()),
},
withDeleted: true,
order: { deletedAt: { direction: 'DESC' } },
});
}
async restoreKey(user: User, keyID: string): Promise<Key> {
const key = await this.keyrepository.findOneOrFail({
where: { cylinder: { system: { managers: { id: user.id } } }, id: keyID },
withDeleted: true,
});
key.deletedAt = null;
await this.activityService.logKeyRestored(user, key);
await this.helper.deleteKeyArchiveCache();
const k = await this.keyrepository.save(key);
this.sendKeysToSSE(k)
return k;
}
}