// Copyright (c) 2023 Sourcefuse Technologies // // This software is released under the MIT License. // https://opensource.org/licenses/MIT import { Count, DataObject, Entity, Getter, Where, juggler, } from '@loopback/repository'; import {HttpErrors} from '@loopback/rest'; import {Options} from 'loopback-datasource-juggler'; import {AuthErrorKeys} from 'loopback4-authentication'; import {DefaultTransactionSoftCrudRepository} from 'loopback4-soft-delete'; import {IAuthUserWithPermissions} from '../components'; import {UserModifiableEntity} from '../models'; export abstract class DefaultTransactionalUserModifyRepository< T extends UserModifiableEntity, ID, Relations extends object = {}, > extends DefaultTransactionSoftCrudRepository { constructor( entityClass: typeof Entity & { prototype: T; }, dataSource: juggler.DataSource, protected readonly getCurrentUser: Getter< IAuthUserWithPermissions | undefined >, ) { super(entityClass, dataSource); } async create(entity: DataObject, options?: Options): Promise { let currentUser = await this.getCurrentUser(); currentUser = currentUser ?? options?.currentUser; if (!currentUser) { throw new HttpErrors.Forbidden(AuthErrorKeys.InvalidCredentials); } const uid = currentUser?.userTenantId ?? currentUser?.id; entity.createdBy = uid; entity.modifiedBy = uid; return super.create(entity, options); } async createAll(entities: DataObject[], options?: Options): Promise { let currentUser = await this.getCurrentUser(); currentUser = currentUser ?? options?.currentUser; if (!currentUser) { throw new HttpErrors.Forbidden(AuthErrorKeys.InvalidCredentials); } const uid = currentUser?.userTenantId ?? currentUser?.id; entities.forEach(entity => { entity.createdBy = uid ?? ''; entity.modifiedBy = uid ?? ''; }); return super.createAll(entities, options); } async save(entity: T, options?: Options): Promise { const currentUser = await this.getCurrentUser(); if (!currentUser) { throw new HttpErrors.Forbidden(AuthErrorKeys.InvalidCredentials); } const uid = currentUser?.userTenantId ?? currentUser?.id; entity.modifiedBy = uid; return super.save(entity, options); } async update(entity: T, options?: Options): Promise { const currentUser = await this.getCurrentUser(); if (!currentUser) { throw new HttpErrors.Forbidden(AuthErrorKeys.InvalidCredentials); } const uid = currentUser?.userTenantId ?? currentUser?.id; entity.modifiedBy = uid; return super.update(entity, options); } async updateAll( data: DataObject, where?: Where, options?: Options, ): Promise { let currentUser = await this.getCurrentUser(); currentUser = currentUser ?? options?.currentUser; if (!currentUser) { throw new HttpErrors.Forbidden(AuthErrorKeys.InvalidCredentials); } const uid = currentUser?.userTenantId ?? currentUser?.id; data.modifiedBy = uid; return super.updateAll(data, where, options); } async updateById( id: ID, data: DataObject, options?: Options, ): Promise { let currentUser = await this.getCurrentUser(); currentUser = currentUser ?? options?.currentUser; if (!currentUser) { throw new HttpErrors.Forbidden(AuthErrorKeys.InvalidCredentials); } const uid = currentUser?.userTenantId ?? currentUser?.id; data.modifiedBy = uid; return super.updateById(id, data, options); } async replaceById( id: ID, data: DataObject, options?: Options, ): Promise { const currentUser = await this.getCurrentUser(); if (!currentUser) { throw new HttpErrors.Forbidden(AuthErrorKeys.InvalidCredentials); } const uid = currentUser?.userTenantId ?? currentUser?.id; data.modifiedBy = uid; return super.replaceById(id, data, options); } }