import { BadRequestException, Injectable } from '@nestjs/common'; import { Insertable } from 'kysely'; import sanitize from 'sanitize-filename'; import { SystemConfig } from 'src/config'; import { SALT_ROUNDS } from 'src/constants'; import { StorageCore } from 'src/cores/storage.core'; import { UserEntity } from 'src/entities/user.entity'; import { AccessRepository } from 'src/repositories/access.repository'; import { ActivityRepository } from 'src/repositories/activity.repository'; import { AlbumUserRepository } from 'src/repositories/album-user.repository'; import { AlbumRepository } from 'src/repositories/album.repository'; import { ApiKeyRepository } from 'src/repositories/api-key.repository'; import { AssetRepository } from 'src/repositories/asset.repository'; import { AuditRepository } from 'src/repositories/audit.repository'; import { ConfigRepository } from 'src/repositories/config.repository'; import { CronRepository } from 'src/repositories/cron.repository'; import { CryptoRepository } from 'src/repositories/crypto.repository'; import { DatabaseRepository } from 'src/repositories/database.repository'; import { DownloadRepository } from 'src/repositories/download.repository'; import { EventRepository } from 'src/repositories/event.repository'; import { JobRepository } from 'src/repositories/job.repository'; import { LibraryRepository } from 'src/repositories/library.repository'; import { LoggingRepository } from 'src/repositories/logging.repository'; import { MachineLearningRepository } from 'src/repositories/machine-learning.repository'; import { MapRepository } from 'src/repositories/map.repository'; import { MediaRepository } from 'src/repositories/media.repository'; import { MemoryRepository } from 'src/repositories/memory.repository'; import { MetadataRepository } from 'src/repositories/metadata.repository'; import { MoveRepository } from 'src/repositories/move.repository'; import { NotificationRepository } from 'src/repositories/notification.repository'; import { OAuthRepository } from 'src/repositories/oauth.repository'; import { PartnerRepository } from 'src/repositories/partner.repository'; import { PersonRepository } from 'src/repositories/person.repository'; import { ProcessRepository } from 'src/repositories/process.repository'; import { SearchRepository } from 'src/repositories/search.repository'; import { ServerInfoRepository } from 'src/repositories/server-info.repository'; import { SessionRepository } from 'src/repositories/session.repository'; import { SharedLinkRepository } from 'src/repositories/shared-link.repository'; import { StackRepository } from 'src/repositories/stack.repository'; import { StorageRepository } from 'src/repositories/storage.repository'; import { SyncRepository } from 'src/repositories/sync.repository'; import { SystemMetadataRepository } from 'src/repositories/system-metadata.repository'; import { TagRepository } from 'src/repositories/tag.repository'; import { TelemetryRepository } from 'src/repositories/telemetry.repository'; import { TrashRepository } from 'src/repositories/trash.repository'; import { UserRepository } from 'src/repositories/user.repository'; import { VersionHistoryRepository } from 'src/repositories/version-history.repository'; import { ViewRepository } from 'src/repositories/view-repository'; import { UserTable } from 'src/schema/tables/user.table'; import { AccessRequest, checkAccess, requireAccess } from 'src/utils/access'; import { getConfig, updateConfig } from 'src/utils/config'; @Injectable() export class BaseService { protected storageCore: StorageCore; constructor( protected logger: LoggingRepository, protected accessRepository: AccessRepository, protected activityRepository: ActivityRepository, protected albumRepository: AlbumRepository, protected albumUserRepository: AlbumUserRepository, protected apiKeyRepository: ApiKeyRepository, protected assetRepository: AssetRepository, protected auditRepository: AuditRepository, protected configRepository: ConfigRepository, protected cronRepository: CronRepository, protected cryptoRepository: CryptoRepository, protected databaseRepository: DatabaseRepository, protected downloadRepository: DownloadRepository, protected eventRepository: EventRepository, protected jobRepository: JobRepository, protected libraryRepository: LibraryRepository, protected machineLearningRepository: MachineLearningRepository, protected mapRepository: MapRepository, protected mediaRepository: MediaRepository, protected memoryRepository: MemoryRepository, protected metadataRepository: MetadataRepository, protected moveRepository: MoveRepository, protected notificationRepository: NotificationRepository, protected oauthRepository: OAuthRepository, protected partnerRepository: PartnerRepository, protected personRepository: PersonRepository, protected processRepository: ProcessRepository, protected searchRepository: SearchRepository, protected serverInfoRepository: ServerInfoRepository, protected sessionRepository: SessionRepository, protected sharedLinkRepository: SharedLinkRepository, protected stackRepository: StackRepository, protected storageRepository: StorageRepository, protected syncRepository: SyncRepository, protected systemMetadataRepository: SystemMetadataRepository, protected tagRepository: TagRepository, protected telemetryRepository: TelemetryRepository, protected trashRepository: TrashRepository, protected userRepository: UserRepository, protected versionRepository: VersionHistoryRepository, protected viewRepository: ViewRepository, ) { this.logger.setContext(this.constructor.name); this.storageCore = StorageCore.create( assetRepository, configRepository, cryptoRepository, moveRepository, personRepository, storageRepository, systemMetadataRepository, this.logger, ); } get worker() { return this.configRepository.getWorker(); } private get configRepos() { return { configRepo: this.configRepository, metadataRepo: this.systemMetadataRepository, logger: this.logger, }; } getConfig(options: { withCache: boolean }) { return getConfig(this.configRepos, options); } updateConfig(newConfig: SystemConfig) { return updateConfig(this.configRepos, newConfig); } requireAccess(request: AccessRequest) { return requireAccess(this.accessRepository, request); } checkAccess(request: AccessRequest) { return checkAccess(this.accessRepository, request); } async createUser(dto: Insertable & { email: string }): Promise { const user = await this.userRepository.getByEmail(dto.email); if (user) { throw new BadRequestException('User exists'); } if (!dto.isAdmin) { const localAdmin = await this.userRepository.getAdmin(); if (!localAdmin) { throw new BadRequestException('The first registered account must the administrator.'); } } const payload: Insertable = { ...dto }; if (payload.password) { payload.password = await this.cryptoRepository.hashBcrypt(payload.password, SALT_ROUNDS); } if (payload.storageLabel) { payload.storageLabel = sanitize(payload.storageLabel.replaceAll('.', '')); } return this.userRepository.create(payload); } }