mirror of
https://github.com/immich-app/immich.git
synced 2024-11-28 09:33:27 +02:00
refactor(server): domain/infra (#1298)
* refactor: user repository * refactor: user module * refactor: move database into infra * refactor(cli): use user core * chore: import path * chore: tests
This commit is contained in:
parent
89a6ed2a5b
commit
131caa20eb
@ -1,11 +1,17 @@
|
|||||||
import { DatabaseModule, SystemConfigEntity, UserEntity } from '@app/database';
|
import { DomainModule } from '@app/domain';
|
||||||
|
import { InfraModule, SystemConfigEntity } from '@app/infra';
|
||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { DisablePasswordLoginCommand, EnablePasswordLoginCommand } from './commands/password-login';
|
import { DisablePasswordLoginCommand, EnablePasswordLoginCommand } from './commands/password-login';
|
||||||
import { PromptPasswordQuestions, ResetAdminPasswordCommand } from './commands/reset-admin-password.command';
|
import { PromptPasswordQuestions, ResetAdminPasswordCommand } from './commands/reset-admin-password.command';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [DatabaseModule, TypeOrmModule.forFeature([UserEntity, SystemConfigEntity])],
|
imports: [
|
||||||
|
DomainModule.register({
|
||||||
|
imports: [InfraModule],
|
||||||
|
}),
|
||||||
|
TypeOrmModule.forFeature([SystemConfigEntity]),
|
||||||
|
],
|
||||||
providers: [
|
providers: [
|
||||||
ResetAdminPasswordCommand,
|
ResetAdminPasswordCommand,
|
||||||
PromptPasswordQuestions,
|
PromptPasswordQuestions,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { SystemConfigEntity, SystemConfigKey } from '@app/database';
|
import { SystemConfigEntity, SystemConfigKey } from '@app/infra';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { Command, CommandRunner } from 'nest-commander';
|
import { Command, CommandRunner } from 'nest-commander';
|
||||||
@ -9,9 +9,7 @@ import { Repository } from 'typeorm';
|
|||||||
description: 'Enable password login',
|
description: 'Enable password login',
|
||||||
})
|
})
|
||||||
export class EnablePasswordLoginCommand extends CommandRunner {
|
export class EnablePasswordLoginCommand extends CommandRunner {
|
||||||
constructor(
|
constructor(@InjectRepository(SystemConfigEntity) private repository: Repository<SystemConfigEntity>) {
|
||||||
@InjectRepository(SystemConfigEntity) private repository: Repository<SystemConfigEntity>, //
|
|
||||||
) {
|
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,40 +1,38 @@
|
|||||||
import { UserEntity } from '@app/database';
|
import { Inject } from '@nestjs/common';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
|
||||||
import bcrypt from 'bcrypt';
|
|
||||||
import { Command, CommandRunner, InquirerService, Question, QuestionSet } from 'nest-commander';
|
import { Command, CommandRunner, InquirerService, Question, QuestionSet } from 'nest-commander';
|
||||||
import { randomBytes } from 'node:crypto';
|
import { randomBytes } from 'node:crypto';
|
||||||
import { Repository } from 'typeorm';
|
import { IUserRepository, UserCore } from '@app/domain';
|
||||||
|
|
||||||
@Command({
|
@Command({
|
||||||
name: 'reset-admin-password',
|
name: 'reset-admin-password',
|
||||||
description: 'Reset the admin password',
|
description: 'Reset the admin password',
|
||||||
})
|
})
|
||||||
export class ResetAdminPasswordCommand extends CommandRunner {
|
export class ResetAdminPasswordCommand extends CommandRunner {
|
||||||
constructor(
|
userCore: UserCore;
|
||||||
private readonly inquirer: InquirerService,
|
|
||||||
@InjectRepository(UserEntity) private userRepository: Repository<UserEntity>,
|
constructor(private readonly inquirer: InquirerService, @Inject(IUserRepository) userRepository: IUserRepository) {
|
||||||
) {
|
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
this.userCore = new UserCore(userRepository);
|
||||||
}
|
}
|
||||||
|
|
||||||
async run(): Promise<void> {
|
async run(): Promise<void> {
|
||||||
let { password } = await this.inquirer.ask<{ password: string }>('prompt-password', undefined);
|
const user = await this.userCore.getAdmin();
|
||||||
password = password || randomBytes(24).toString('base64').replace(/\W/g, '');
|
|
||||||
|
|
||||||
const hashedPassword = await bcrypt.hash(password, 10);
|
|
||||||
|
|
||||||
const user = await this.userRepository.findOne({ where: { isAdmin: true } });
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
console.log('Unable to reset password: no admin user.');
|
console.log('Unable to reset password: no admin user.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
user.password = hashedPassword;
|
const { password: providedPassword } = await this.inquirer.ask<{ password: string }>('prompt-password', undefined);
|
||||||
user.shouldChangePassword = true;
|
const password = providedPassword || randomBytes(24).toString('base64').replace(/\W/g, '');
|
||||||
|
|
||||||
await this.userRepository.save(user);
|
await this.userCore.updateUser(user, user.id, { password });
|
||||||
|
|
||||||
console.log(`New password:\n${password}`);
|
if (providedPassword) {
|
||||||
|
console.log('The admin password has been updated.');
|
||||||
|
} else {
|
||||||
|
console.log(`The admin password has been updated to:\n${password}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { AlbumEntity, AssetAlbumEntity, UserAlbumEntity } from '@app/database';
|
import { AlbumEntity, AssetAlbumEntity, UserAlbumEntity } from '@app/infra';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { In, Repository, SelectQueryBuilder, DataSource, Brackets, Not, IsNull } from 'typeorm';
|
import { In, Repository, SelectQueryBuilder, DataSource, Brackets, Not, IsNull } from 'typeorm';
|
||||||
|
@ -2,11 +2,10 @@ import { forwardRef, Module } from '@nestjs/common';
|
|||||||
import { AlbumService } from './album.service';
|
import { AlbumService } from './album.service';
|
||||||
import { AlbumController } from './album.controller';
|
import { AlbumController } from './album.controller';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { AlbumEntity, AssetAlbumEntity, UserAlbumEntity } from '@app/database';
|
import { AlbumEntity, AssetAlbumEntity, UserAlbumEntity } from '@app/infra';
|
||||||
import { AlbumRepository, IAlbumRepository } from './album-repository';
|
import { AlbumRepository, IAlbumRepository } from './album-repository';
|
||||||
import { DownloadModule } from '../../modules/download/download.module';
|
import { DownloadModule } from '../../modules/download/download.module';
|
||||||
import { AssetModule } from '../asset/asset.module';
|
import { AssetModule } from '../asset/asset.module';
|
||||||
import { UserModule } from '../user/user.module';
|
|
||||||
import { ShareModule } from '../share/share.module';
|
import { ShareModule } from '../share/share.module';
|
||||||
|
|
||||||
const ALBUM_REPOSITORY_PROVIDER = {
|
const ALBUM_REPOSITORY_PROVIDER = {
|
||||||
@ -18,7 +17,6 @@ const ALBUM_REPOSITORY_PROVIDER = {
|
|||||||
imports: [
|
imports: [
|
||||||
TypeOrmModule.forFeature([AlbumEntity, AssetAlbumEntity, UserAlbumEntity]),
|
TypeOrmModule.forFeature([AlbumEntity, AssetAlbumEntity, UserAlbumEntity]),
|
||||||
DownloadModule,
|
DownloadModule,
|
||||||
UserModule,
|
|
||||||
forwardRef(() => AssetModule),
|
forwardRef(() => AssetModule),
|
||||||
ShareModule,
|
ShareModule,
|
||||||
],
|
],
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { AlbumService } from './album.service';
|
import { AlbumService } from './album.service';
|
||||||
import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
||||||
import { BadRequestException, NotFoundException, ForbiddenException } from '@nestjs/common';
|
import { BadRequestException, NotFoundException, ForbiddenException } from '@nestjs/common';
|
||||||
import { AlbumEntity } from '@app/database';
|
import { AlbumEntity } from '@app/infra';
|
||||||
import { AlbumResponseDto } from './response-dto/album-response.dto';
|
import { AlbumResponseDto } from './response-dto/album-response.dto';
|
||||||
import { AddAssetsResponseDto } from './response-dto/add-assets-response.dto';
|
import { AddAssetsResponseDto } from './response-dto/add-assets-response.dto';
|
||||||
import { IAlbumRepository } from './album-repository';
|
import { IAlbumRepository } from './album-repository';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { BadRequestException, Inject, Injectable, NotFoundException, ForbiddenException, Logger } from '@nestjs/common';
|
import { BadRequestException, Inject, Injectable, NotFoundException, ForbiddenException, Logger } from '@nestjs/common';
|
||||||
import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
||||||
import { CreateAlbumDto } from './dto/create-album.dto';
|
import { CreateAlbumDto } from './dto/create-album.dto';
|
||||||
import { AlbumEntity, SharedLinkType } from '@app/database';
|
import { AlbumEntity, SharedLinkType } from '@app/infra';
|
||||||
import { AddUsersDto } from './dto/add-users.dto';
|
import { AddUsersDto } from './dto/add-users.dto';
|
||||||
import { RemoveAssetsDto } from './dto/remove-assets.dto';
|
import { RemoveAssetsDto } from './dto/remove-assets.dto';
|
||||||
import { UpdateAlbumDto } from './dto/update-album.dto';
|
import { UpdateAlbumDto } from './dto/update-album.dto';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { AlbumEntity } from '@app/database';
|
import { AlbumEntity } from '@app/infra';
|
||||||
import { UserResponseDto, mapUser } from '../../user/response-dto/user-response.dto';
|
import { UserResponseDto, mapUser } from '@app/domain';
|
||||||
import { AssetResponseDto, mapAsset } from '../../asset/response-dto/asset-response.dto';
|
import { AssetResponseDto, mapAsset } from '../../asset/response-dto/asset-response.dto';
|
||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { APIKeyEntity } from '@app/database';
|
import { APIKeyEntity } from '@app/infra';
|
||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { APIKeyController } from './api-key.controller';
|
import { APIKeyController } from './api-key.controller';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { APIKeyEntity } from '@app/database';
|
import { APIKeyEntity } from '@app/infra';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { UserEntity } from '@app/database';
|
import { UserEntity } from '@app/infra';
|
||||||
import { BadRequestException, Inject, Injectable, UnauthorizedException } from '@nestjs/common';
|
import { BadRequestException, Inject, Injectable, UnauthorizedException } from '@nestjs/common';
|
||||||
import { compareSync, hash } from 'bcrypt';
|
import { compareSync, hash } from 'bcrypt';
|
||||||
import { randomBytes } from 'node:crypto';
|
import { randomBytes } from 'node:crypto';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { APIKeyEntity } from '@app/database';
|
import { APIKeyEntity } from '@app/infra';
|
||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
export class APIKeyResponseDto {
|
export class APIKeyResponseDto {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { SearchPropertiesDto } from './dto/search-properties.dto';
|
import { SearchPropertiesDto } from './dto/search-properties.dto';
|
||||||
import { CuratedLocationsResponseDto } from './response-dto/curated-locations-response.dto';
|
import { CuratedLocationsResponseDto } from './response-dto/curated-locations-response.dto';
|
||||||
import { AssetEntity, AssetType } from '@app/database';
|
import { AssetEntity, AssetType } from '@app/infra';
|
||||||
import { BadRequestException, Inject, Injectable } from '@nestjs/common';
|
import { BadRequestException, Inject, Injectable } from '@nestjs/common';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { Repository } from 'typeorm/repository/Repository';
|
import { Repository } from 'typeorm/repository/Repository';
|
||||||
|
@ -2,7 +2,7 @@ import { forwardRef, Module } from '@nestjs/common';
|
|||||||
import { AssetService } from './asset.service';
|
import { AssetService } from './asset.service';
|
||||||
import { AssetController } from './asset.controller';
|
import { AssetController } from './asset.controller';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { AssetEntity } from '@app/database';
|
import { AssetEntity } from '@app/infra';
|
||||||
import { BullModule } from '@nestjs/bull';
|
import { BullModule } from '@nestjs/bull';
|
||||||
import { BackgroundTaskModule } from '../../modules/background-task/background-task.module';
|
import { BackgroundTaskModule } from '../../modules/background-task/background-task.module';
|
||||||
import { BackgroundTaskService } from '../../modules/background-task/background-task.service';
|
import { BackgroundTaskService } from '../../modules/background-task/background-task.service';
|
||||||
@ -11,7 +11,6 @@ import { AssetRepository, IAssetRepository } from './asset-repository';
|
|||||||
import { DownloadModule } from '../../modules/download/download.module';
|
import { DownloadModule } from '../../modules/download/download.module';
|
||||||
import { TagModule } from '../tag/tag.module';
|
import { TagModule } from '../tag/tag.module';
|
||||||
import { AlbumModule } from '../album/album.module';
|
import { AlbumModule } from '../album/album.module';
|
||||||
import { UserModule } from '../user/user.module';
|
|
||||||
import { StorageModule } from '@app/storage';
|
import { StorageModule } from '@app/storage';
|
||||||
import { immichSharedQueues } from '@app/job/constants/bull-queue-registration.constant';
|
import { immichSharedQueues } from '@app/job/constants/bull-queue-registration.constant';
|
||||||
import { ShareModule } from '../share/share.module';
|
import { ShareModule } from '../share/share.module';
|
||||||
@ -27,7 +26,6 @@ const ASSET_REPOSITORY_PROVIDER = {
|
|||||||
CommunicationModule,
|
CommunicationModule,
|
||||||
BackgroundTaskModule,
|
BackgroundTaskModule,
|
||||||
DownloadModule,
|
DownloadModule,
|
||||||
UserModule,
|
|
||||||
AlbumModule,
|
AlbumModule,
|
||||||
TagModule,
|
TagModule,
|
||||||
StorageModule,
|
StorageModule,
|
||||||
|
@ -2,7 +2,7 @@ import { IAssetRepository } from './asset-repository';
|
|||||||
import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
||||||
import { AssetService } from './asset.service';
|
import { AssetService } from './asset.service';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { AssetEntity, AssetType } from '@app/database';
|
import { AssetEntity, AssetType } from '@app/infra';
|
||||||
import { CreateAssetDto } from './dto/create-asset.dto';
|
import { CreateAssetDto } from './dto/create-asset.dto';
|
||||||
import { AssetCountByTimeBucket } from './response-dto/asset-count-by-time-group-response.dto';
|
import { AssetCountByTimeBucket } from './response-dto/asset-count-by-time-group-response.dto';
|
||||||
import { TimeGroupEnum } from './dto/get-asset-count-by-time-bucket.dto';
|
import { TimeGroupEnum } from './dto/get-asset-count-by-time-bucket.dto';
|
||||||
|
@ -13,7 +13,7 @@ import { InjectRepository } from '@nestjs/typeorm';
|
|||||||
import { createHash, randomUUID } from 'node:crypto';
|
import { createHash, randomUUID } from 'node:crypto';
|
||||||
import { QueryFailedError, Repository } from 'typeorm';
|
import { QueryFailedError, Repository } from 'typeorm';
|
||||||
import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
||||||
import { AssetEntity, AssetType } from '@app/database';
|
import { AssetEntity, AssetType } from '@app/infra';
|
||||||
import { constants, createReadStream, ReadStream, stat } from 'fs';
|
import { constants, createReadStream, ReadStream, stat } from 'fs';
|
||||||
import { ServeFileDto } from './dto/serve-file.dto';
|
import { ServeFileDto } from './dto/serve-file.dto';
|
||||||
import { Response as Res } from 'express';
|
import { Response as Res } from 'express';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { IsNotEmpty, IsOptional } from 'class-validator';
|
import { IsNotEmpty, IsOptional } from 'class-validator';
|
||||||
import { AssetType } from '@app/database';
|
import { AssetType } from '@app/infra';
|
||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
export class CreateAssetDto {
|
export class CreateAssetDto {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { AssetEntity, AssetType } from '@app/database';
|
import { AssetEntity, AssetType } from '@app/infra';
|
||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import { mapTag, TagResponseDto } from '../../tag/response-dto/tag-response.dto';
|
import { mapTag, TagResponseDto } from '../../tag/response-dto/tag-response.dto';
|
||||||
import { ExifResponseDto, mapExif } from './exif-response.dto';
|
import { ExifResponseDto, mapExif } from './exif-response.dto';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ExifEntity } from '@app/database';
|
import { ExifEntity } from '@app/infra';
|
||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
export class ExifResponseDto {
|
export class ExifResponseDto {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { SmartInfoEntity } from '@app/database';
|
import { SmartInfoEntity } from '@app/infra';
|
||||||
|
|
||||||
export class SmartInfoResponseDto {
|
export class SmartInfoResponseDto {
|
||||||
id?: string;
|
id?: string;
|
||||||
|
@ -5,7 +5,7 @@ import { AuthType, IMMICH_AUTH_TYPE_COOKIE } from '../../constants/jwt.constant'
|
|||||||
import { AuthUserDto, GetAuthUser } from '../../decorators/auth-user.decorator';
|
import { AuthUserDto, GetAuthUser } from '../../decorators/auth-user.decorator';
|
||||||
import { Authenticated } from '../../decorators/authenticated.decorator';
|
import { Authenticated } from '../../decorators/authenticated.decorator';
|
||||||
import { ImmichJwtService } from '../../modules/immich-jwt/immich-jwt.service';
|
import { ImmichJwtService } from '../../modules/immich-jwt/immich-jwt.service';
|
||||||
import { UserResponseDto } from '../user/response-dto/user-response.dto';
|
import { UserResponseDto } from '@app/domain';
|
||||||
import { AuthService } from './auth.service';
|
import { AuthService } from './auth.service';
|
||||||
import { ChangePasswordDto } from './dto/change-password.dto';
|
import { ChangePasswordDto } from './dto/change-password.dto';
|
||||||
import { LoginCredentialDto } from './dto/login-credential.dto';
|
import { LoginCredentialDto } from './dto/login-credential.dto';
|
||||||
|
@ -2,12 +2,11 @@ import { Module } from '@nestjs/common';
|
|||||||
import { ImmichConfigModule } from '@app/immich-config';
|
import { ImmichConfigModule } from '@app/immich-config';
|
||||||
import { ImmichJwtModule } from '../../modules/immich-jwt/immich-jwt.module';
|
import { ImmichJwtModule } from '../../modules/immich-jwt/immich-jwt.module';
|
||||||
import { OAuthModule } from '../oauth/oauth.module';
|
import { OAuthModule } from '../oauth/oauth.module';
|
||||||
import { UserModule } from '../user/user.module';
|
|
||||||
import { AuthController } from './auth.controller';
|
import { AuthController } from './auth.controller';
|
||||||
import { AuthService } from './auth.service';
|
import { AuthService } from './auth.service';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [UserModule, ImmichJwtModule, OAuthModule, ImmichConfigModule],
|
imports: [ImmichJwtModule, OAuthModule, ImmichConfigModule],
|
||||||
controllers: [AuthController],
|
controllers: [AuthController],
|
||||||
providers: [AuthService],
|
providers: [AuthService],
|
||||||
})
|
})
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { UserEntity } from '@app/database';
|
import { UserEntity } from '@app/infra';
|
||||||
import { BadRequestException, UnauthorizedException } from '@nestjs/common';
|
import { BadRequestException, UnauthorizedException } from '@nestjs/common';
|
||||||
import * as bcrypt from 'bcrypt';
|
import * as bcrypt from 'bcrypt';
|
||||||
import { SystemConfig } from '@app/database/entities/system-config.entity';
|
import { SystemConfig } from '@app/infra';
|
||||||
import { ImmichConfigService } from '@app/immich-config';
|
import { ImmichConfigService } from '@app/immich-config';
|
||||||
import { AuthType } from '../../constants/jwt.constant';
|
import { AuthType } from '../../constants/jwt.constant';
|
||||||
import { ImmichJwtService } from '../../modules/immich-jwt/immich-jwt.service';
|
import { ImmichJwtService } from '../../modules/immich-jwt/immich-jwt.service';
|
||||||
import { OAuthService } from '../oauth/oauth.service';
|
import { OAuthService } from '../oauth/oauth.service';
|
||||||
import { IUserRepository } from '../user/user-repository';
|
import { IUserRepository } from '@app/domain';
|
||||||
import { AuthService } from './auth.service';
|
import { AuthService } from './auth.service';
|
||||||
import { SignUpDto } from './dto/sign-up.dto';
|
import { SignUpDto } from './dto/sign-up.dto';
|
||||||
import { LoginResponseDto } from './response-dto/login-response.dto';
|
import { LoginResponseDto } from './response-dto/login-response.dto';
|
||||||
|
@ -7,11 +7,11 @@ import {
|
|||||||
UnauthorizedException,
|
UnauthorizedException,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import * as bcrypt from 'bcrypt';
|
import * as bcrypt from 'bcrypt';
|
||||||
import { UserEntity } from '@app/database';
|
import { UserEntity } from '@app/infra';
|
||||||
import { AuthType } from '../../constants/jwt.constant';
|
import { AuthType } from '../../constants/jwt.constant';
|
||||||
import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
||||||
import { ImmichJwtService } from '../../modules/immich-jwt/immich-jwt.service';
|
import { ImmichJwtService } from '../../modules/immich-jwt/immich-jwt.service';
|
||||||
import { IUserRepository } from '../user/user-repository';
|
import { IUserRepository } from '@app/domain';
|
||||||
import { ChangePasswordDto } from './dto/change-password.dto';
|
import { ChangePasswordDto } from './dto/change-password.dto';
|
||||||
import { LoginCredentialDto } from './dto/login-credential.dto';
|
import { LoginCredentialDto } from './dto/login-credential.dto';
|
||||||
import { SignUpDto } from './dto/sign-up.dto';
|
import { SignUpDto } from './dto/sign-up.dto';
|
||||||
@ -19,9 +19,9 @@ import { AdminSignupResponseDto, mapAdminSignupResponse } from './response-dto/a
|
|||||||
import { LoginResponseDto } from './response-dto/login-response.dto';
|
import { LoginResponseDto } from './response-dto/login-response.dto';
|
||||||
import { LogoutResponseDto } from './response-dto/logout-response.dto';
|
import { LogoutResponseDto } from './response-dto/logout-response.dto';
|
||||||
import { OAuthService } from '../oauth/oauth.service';
|
import { OAuthService } from '../oauth/oauth.service';
|
||||||
import { UserCore } from '../user/user.core';
|
import { UserCore } from '@app/domain';
|
||||||
import { ImmichConfigService, INITIAL_SYSTEM_CONFIG } from '@app/immich-config';
|
import { ImmichConfigService, INITIAL_SYSTEM_CONFIG } from '@app/immich-config';
|
||||||
import { SystemConfig } from '@app/database/entities/system-config.entity';
|
import { SystemConfig } from '@app/infra';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthService {
|
export class AuthService {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { UserEntity } from '@app/database';
|
import { UserEntity } from '@app/infra';
|
||||||
|
|
||||||
export class AdminSignupResponseDto {
|
export class AdminSignupResponseDto {
|
||||||
id!: string;
|
id!: string;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { UserEntity } from '@app/database';
|
import { UserEntity } from '@app/infra';
|
||||||
import { ApiResponseProperty } from '@nestjs/swagger';
|
import { ApiResponseProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
export class LoginResponseDto {
|
export class LoginResponseDto {
|
||||||
|
@ -3,7 +3,7 @@ import { Socket, Server } from 'socket.io';
|
|||||||
import { ImmichJwtService, JwtValidationResult } from '../../modules/immich-jwt/immich-jwt.service';
|
import { ImmichJwtService, JwtValidationResult } from '../../modules/immich-jwt/immich-jwt.service';
|
||||||
import { Logger } from '@nestjs/common';
|
import { Logger } from '@nestjs/common';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { UserEntity } from '@app/database';
|
import { UserEntity } from '@app/infra';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import cookieParser from 'cookie';
|
import cookieParser from 'cookie';
|
||||||
import { IMMICH_ACCESS_COOKIE } from '../../constants/jwt.constant';
|
import { IMMICH_ACCESS_COOKIE } from '../../constants/jwt.constant';
|
||||||
|
@ -6,7 +6,7 @@ import { ImmichJwtService } from '../../modules/immich-jwt/immich-jwt.service';
|
|||||||
import { JwtModule } from '@nestjs/jwt';
|
import { JwtModule } from '@nestjs/jwt';
|
||||||
import { jwtConfig } from '../../config/jwt.config';
|
import { jwtConfig } from '../../config/jwt.config';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { UserEntity } from '@app/database';
|
import { UserEntity } from '@app/infra';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [TypeOrmModule.forFeature([UserEntity]), ImmichJwtModule, JwtModule.register(jwtConfig)],
|
imports: [TypeOrmModule.forFeature([UserEntity]), ImmichJwtModule, JwtModule.register(jwtConfig)],
|
||||||
|
@ -2,7 +2,7 @@ import { Module } from '@nestjs/common';
|
|||||||
import { DeviceInfoService } from './device-info.service';
|
import { DeviceInfoService } from './device-info.service';
|
||||||
import { DeviceInfoController } from './device-info.controller';
|
import { DeviceInfoController } from './device-info.controller';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { DeviceInfoEntity } from '@app/database';
|
import { DeviceInfoEntity } from '@app/infra';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [TypeOrmModule.forFeature([DeviceInfoEntity])],
|
imports: [TypeOrmModule.forFeature([DeviceInfoEntity])],
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { DeviceInfoEntity, DeviceType } from '@app/database';
|
import { DeviceInfoEntity, DeviceType } from '@app/infra';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { DeviceInfoService } from './device-info.service';
|
import { DeviceInfoService } from './device-info.service';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { DeviceInfoEntity } from '@app/database';
|
import { DeviceInfoEntity } from '@app/infra';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { IsNotEmpty, IsOptional } from 'class-validator';
|
import { IsNotEmpty, IsOptional } from 'class-validator';
|
||||||
import { DeviceType } from '@app/database';
|
import { DeviceType } from '@app/infra';
|
||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
export class UpsertDeviceInfoDto {
|
export class UpsertDeviceInfoDto {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { DeviceInfoEntity, DeviceType } from '@app/database';
|
import { DeviceInfoEntity, DeviceType } from '@app/infra';
|
||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
export class DeviceInfoResponseDto {
|
export class DeviceInfoResponseDto {
|
||||||
|
@ -1,15 +1,11 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { JobService } from './job.service';
|
import { JobService } from './job.service';
|
||||||
import { JobController } from './job.controller';
|
import { JobController } from './job.controller';
|
||||||
import { ImmichJwtService } from '../../modules/immich-jwt/immich-jwt.service';
|
|
||||||
import { ImmichJwtModule } from '../../modules/immich-jwt/immich-jwt.module';
|
import { ImmichJwtModule } from '../../modules/immich-jwt/immich-jwt.module';
|
||||||
import { JwtModule } from '@nestjs/jwt';
|
|
||||||
import { jwtConfig } from '../../config/jwt.config';
|
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { ExifEntity } from '@app/database';
|
import { ExifEntity } from '@app/infra';
|
||||||
import { TagModule } from '../tag/tag.module';
|
import { TagModule } from '../tag/tag.module';
|
||||||
import { AssetModule } from '../asset/asset.module';
|
import { AssetModule } from '../asset/asset.module';
|
||||||
import { UserModule } from '../user/user.module';
|
|
||||||
|
|
||||||
import { StorageModule } from '@app/storage';
|
import { StorageModule } from '@app/storage';
|
||||||
import { BullModule } from '@nestjs/bull';
|
import { BullModule } from '@nestjs/bull';
|
||||||
@ -21,12 +17,10 @@ import { immichSharedQueues } from '@app/job/constants/bull-queue-registration.c
|
|||||||
ImmichJwtModule,
|
ImmichJwtModule,
|
||||||
TagModule,
|
TagModule,
|
||||||
AssetModule,
|
AssetModule,
|
||||||
UserModule,
|
|
||||||
JwtModule.register(jwtConfig),
|
|
||||||
StorageModule,
|
StorageModule,
|
||||||
BullModule.registerQueue(...immichSharedQueues),
|
BullModule.registerQueue(...immichSharedQueues),
|
||||||
],
|
],
|
||||||
controllers: [JobController],
|
controllers: [JobController],
|
||||||
providers: [JobService, ImmichJwtService],
|
providers: [JobService],
|
||||||
})
|
})
|
||||||
export class JobModule {}
|
export class JobModule {}
|
||||||
|
@ -15,7 +15,7 @@ import { BadRequestException, Inject, Injectable } from '@nestjs/common';
|
|||||||
import { AllJobStatusResponseDto } from './response-dto/all-job-status-response.dto';
|
import { AllJobStatusResponseDto } from './response-dto/all-job-status-response.dto';
|
||||||
import { randomUUID } from 'crypto';
|
import { randomUUID } from 'crypto';
|
||||||
import { IAssetRepository } from '../asset/asset-repository';
|
import { IAssetRepository } from '../asset/asset-repository';
|
||||||
import { AssetType } from '@app/database';
|
import { AssetType } from '@app/infra';
|
||||||
import { GetJobDto, JobId } from './dto/get-job.dto';
|
import { GetJobDto, JobId } from './dto/get-job.dto';
|
||||||
import { JobStatusResponseDto } from './response-dto/job-status-response.dto';
|
import { JobStatusResponseDto } from './response-dto/job-status-response.dto';
|
||||||
import { IMachineLearningJob } from '@app/job/interfaces/machine-learning.interface';
|
import { IMachineLearningJob } from '@app/job/interfaces/machine-learning.interface';
|
||||||
|
@ -6,7 +6,7 @@ import { AuthUserDto, GetAuthUser } from '../../decorators/auth-user.decorator';
|
|||||||
import { Authenticated } from '../../decorators/authenticated.decorator';
|
import { Authenticated } from '../../decorators/authenticated.decorator';
|
||||||
import { ImmichJwtService } from '../../modules/immich-jwt/immich-jwt.service';
|
import { ImmichJwtService } from '../../modules/immich-jwt/immich-jwt.service';
|
||||||
import { LoginResponseDto } from '../auth/response-dto/login-response.dto';
|
import { LoginResponseDto } from '../auth/response-dto/login-response.dto';
|
||||||
import { UserResponseDto } from '../user/response-dto/user-response.dto';
|
import { UserResponseDto } from '@app/domain';
|
||||||
import { OAuthCallbackDto } from './dto/oauth-auth-code.dto';
|
import { OAuthCallbackDto } from './dto/oauth-auth-code.dto';
|
||||||
import { OAuthConfigDto } from './dto/oauth-config.dto';
|
import { OAuthConfigDto } from './dto/oauth-config.dto';
|
||||||
import { MOBILE_REDIRECT, OAuthService } from './oauth.service';
|
import { MOBILE_REDIRECT, OAuthService } from './oauth.service';
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import { ImmichConfigModule } from '@app/immich-config';
|
import { ImmichConfigModule } from '@app/immich-config';
|
||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { ImmichJwtModule } from '../../modules/immich-jwt/immich-jwt.module';
|
import { ImmichJwtModule } from '../../modules/immich-jwt/immich-jwt.module';
|
||||||
import { UserModule } from '../user/user.module';
|
|
||||||
import { OAuthController } from './oauth.controller';
|
import { OAuthController } from './oauth.controller';
|
||||||
import { OAuthService } from './oauth.service';
|
import { OAuthService } from './oauth.service';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [UserModule, ImmichJwtModule, ImmichConfigModule],
|
imports: [ImmichJwtModule, ImmichConfigModule],
|
||||||
controllers: [OAuthController],
|
controllers: [OAuthController],
|
||||||
providers: [OAuthService],
|
providers: [OAuthService],
|
||||||
exports: [OAuthService],
|
exports: [OAuthService],
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { SystemConfig, UserEntity } from '@app/database';
|
import { SystemConfig, UserEntity } from '@app/infra';
|
||||||
import { ImmichConfigService } from '@app/immich-config';
|
import { ImmichConfigService } from '@app/immich-config';
|
||||||
import { BadRequestException } from '@nestjs/common';
|
import { BadRequestException } from '@nestjs/common';
|
||||||
import { generators, Issuer } from 'openid-client';
|
import { generators, Issuer } from 'openid-client';
|
||||||
@ -6,7 +6,7 @@ import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
|||||||
import { ImmichJwtService } from '../../modules/immich-jwt/immich-jwt.service';
|
import { ImmichJwtService } from '../../modules/immich-jwt/immich-jwt.service';
|
||||||
import { LoginResponseDto } from '../auth/response-dto/login-response.dto';
|
import { LoginResponseDto } from '../auth/response-dto/login-response.dto';
|
||||||
import { OAuthService } from '../oauth/oauth.service';
|
import { OAuthService } from '../oauth/oauth.service';
|
||||||
import { IUserRepository } from '../user/user-repository';
|
import { IUserRepository } from '@app/domain';
|
||||||
|
|
||||||
const email = 'user@immich.com';
|
const email = 'user@immich.com';
|
||||||
const sub = 'my-auth-user-sub';
|
const sub = 'my-auth-user-sub';
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
import { SystemConfig } from '@app/database/entities/system-config.entity';
|
import { SystemConfig } from '@app/infra';
|
||||||
import { ImmichConfigService, INITIAL_SYSTEM_CONFIG } from '@app/immich-config';
|
import { ImmichConfigService, INITIAL_SYSTEM_CONFIG } from '@app/immich-config';
|
||||||
import { BadRequestException, Inject, Injectable, Logger } from '@nestjs/common';
|
import { BadRequestException, Inject, Injectable, Logger } from '@nestjs/common';
|
||||||
import { ClientMetadata, custom, generators, Issuer, UserinfoResponse } from 'openid-client';
|
import { ClientMetadata, custom, generators, Issuer, UserinfoResponse } from 'openid-client';
|
||||||
import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
||||||
import { ImmichJwtService } from '../../modules/immich-jwt/immich-jwt.service';
|
import { ImmichJwtService } from '../../modules/immich-jwt/immich-jwt.service';
|
||||||
import { LoginResponseDto } from '../auth/response-dto/login-response.dto';
|
import { LoginResponseDto } from '../auth/response-dto/login-response.dto';
|
||||||
import { UserResponseDto } from '../user/response-dto/user-response.dto';
|
import { IUserRepository, UserResponseDto, UserCore } from '@app/domain';
|
||||||
import { IUserRepository } from '../user/user-repository';
|
|
||||||
import { UserCore } from '../user/user.core';
|
|
||||||
import { OAuthCallbackDto } from './dto/oauth-auth-code.dto';
|
import { OAuthCallbackDto } from './dto/oauth-auth-code.dto';
|
||||||
import { OAuthConfigDto } from './dto/oauth-config.dto';
|
import { OAuthConfigDto } from './dto/oauth-config.dto';
|
||||||
import { OAuthConfigResponseDto } from './response-dto/oauth-config-response.dto';
|
import { OAuthConfigResponseDto } from './response-dto/oauth-config-response.dto';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { ServerInfoService } from './server-info.service';
|
import { ServerInfoService } from './server-info.service';
|
||||||
import { ServerInfoController } from './server-info.controller';
|
import { ServerInfoController } from './server-info.controller';
|
||||||
import { AssetEntity, UserEntity } from '@app/database';
|
import { AssetEntity, UserEntity } from '@app/infra';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { ImmichJwtModule } from '../../modules/immich-jwt/immich-jwt.module';
|
import { ImmichJwtModule } from '../../modules/immich-jwt/immich-jwt.module';
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import { ServerInfoResponseDto } from './response-dto/server-info-response.dto';
|
|||||||
import diskusage from 'diskusage';
|
import diskusage from 'diskusage';
|
||||||
import { ServerStatsResponseDto } from './response-dto/server-stats-response.dto';
|
import { ServerStatsResponseDto } from './response-dto/server-stats-response.dto';
|
||||||
import { UsageByUserDto } from './response-dto/usage-by-user-response.dto';
|
import { UsageByUserDto } from './response-dto/usage-by-user-response.dto';
|
||||||
import { AssetEntity } from '@app/database';
|
import { AssetEntity } from '@app/infra';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { asHumanReadable } from '../../utils/human-readable.util';
|
import { asHumanReadable } from '../../utils/human-readable.util';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { AlbumEntity, AssetEntity } from '@app/database';
|
import { AlbumEntity, AssetEntity } from '@app/infra';
|
||||||
import { SharedLinkType } from '@app/database/entities/shared-link.entity';
|
import { SharedLinkType } from '@app/infra';
|
||||||
|
|
||||||
export class CreateSharedLinkDto {
|
export class CreateSharedLinkDto {
|
||||||
description?: string;
|
description?: string;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { SharedLinkEntity, SharedLinkType } from '@app/database';
|
import { SharedLinkEntity, SharedLinkType } from '@app/infra';
|
||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { AlbumResponseDto, mapAlbumExcludeAssetInfo } from '../../album/response-dto/album-response.dto';
|
import { AlbumResponseDto, mapAlbumExcludeAssetInfo } from '../../album/response-dto/album-response.dto';
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { SharedLinkEntity } from '@app/database/entities/shared-link.entity';
|
import { SharedLinkEntity } from '@app/infra';
|
||||||
import { CreateSharedLinkDto } from './dto/create-shared-link.dto';
|
import { CreateSharedLinkDto } from './dto/create-shared-link.dto';
|
||||||
import { ISharedLinkRepository } from './shared-link.repository';
|
import { ISharedLinkRepository } from './shared-link.repository';
|
||||||
import crypto from 'node:crypto';
|
import crypto from 'node:crypto';
|
||||||
import { BadRequestException, InternalServerErrorException, Logger } from '@nestjs/common';
|
import { BadRequestException, InternalServerErrorException, Logger } from '@nestjs/common';
|
||||||
import { AssetEntity } from '@app/database';
|
import { AssetEntity } from '@app/infra';
|
||||||
import { EditSharedLinkDto } from './dto/edit-shared-link.dto';
|
import { EditSharedLinkDto } from './dto/edit-shared-link.dto';
|
||||||
|
|
||||||
export class ShareCore {
|
export class ShareCore {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { ShareService } from './share.service';
|
import { ShareService } from './share.service';
|
||||||
import { ShareController } from './share.controller';
|
import { ShareController } from './share.controller';
|
||||||
import { SharedLinkEntity } from '@app/database/entities/shared-link.entity';
|
import { SharedLinkEntity } from '@app/infra';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { SharedLinkRepository, ISharedLinkRepository } from './shared-link.repository';
|
import { SharedLinkRepository, ISharedLinkRepository } from './shared-link.repository';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { SharedLinkEntity } from '@app/database/entities/shared-link.entity';
|
import { SharedLinkEntity } from '@app/infra';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { SystemConfig } from '@app/database';
|
import { SystemConfig } from '@app/infra';
|
||||||
import { ValidateNested } from 'class-validator';
|
import { ValidateNested } from 'class-validator';
|
||||||
import { SystemConfigFFmpegDto } from './system-config-ffmpeg.dto';
|
import { SystemConfigFFmpegDto } from './system-config-ffmpeg.dto';
|
||||||
import { SystemConfigOAuthDto } from './system-config-oauth.dto';
|
import { SystemConfigOAuthDto } from './system-config-oauth.dto';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { SystemConfigEntity } from '@app/database';
|
import { SystemConfigEntity } from '@app/infra';
|
||||||
import { immichSharedQueues } from '@app/job/constants/bull-queue-registration.constant';
|
import { immichSharedQueues } from '@app/job/constants/bull-queue-registration.constant';
|
||||||
import { BullModule } from '@nestjs/bull';
|
import { BullModule } from '@nestjs/bull';
|
||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { TagType } from '@app/database';
|
import { TagType } from '@app/infra';
|
||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import { IsEnum, IsNotEmpty, IsString } from 'class-validator';
|
import { IsEnum, IsNotEmpty, IsString } from 'class-validator';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { TagEntity, TagType } from '@app/database';
|
import { TagEntity, TagType } from '@app/infra';
|
||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
export class TagResponseDto {
|
export class TagResponseDto {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { TagService } from './tag.service';
|
import { TagService } from './tag.service';
|
||||||
import { TagController } from './tag.controller';
|
import { TagController } from './tag.controller';
|
||||||
import { TagEntity } from '@app/database';
|
import { TagEntity } from '@app/infra';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { TagRepository, ITagRepository } from './tag.repository';
|
import { TagRepository, ITagRepository } from './tag.repository';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { TagEntity, TagType } from '@app/database';
|
import { TagEntity, TagType } from '@app/infra';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { In, Repository } from 'typeorm';
|
import { In, Repository } from 'typeorm';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { TagEntity, TagType, UserEntity } from '@app/database';
|
import { TagEntity, TagType, UserEntity } from '@app/infra';
|
||||||
import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
||||||
import { ITagRepository } from './tag.repository';
|
import { ITagRepository } from './tag.repository';
|
||||||
import { TagService } from './tag.service';
|
import { TagService } from './tag.service';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { TagEntity } from '@app/database';
|
import { TagEntity } from '@app/infra';
|
||||||
import { BadRequestException, Inject, Injectable, Logger } from '@nestjs/common';
|
import { BadRequestException, Inject, Injectable, Logger } from '@nestjs/common';
|
||||||
import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
||||||
import { CreateTagDto } from './dto/create-tag.dto';
|
import { CreateTagDto } from './dto/create-tag.dto';
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
import { UserEntity } from '@app/database';
|
|
||||||
import { Module } from '@nestjs/common';
|
|
||||||
import { JwtModule } from '@nestjs/jwt';
|
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
||||||
import { jwtConfig } from '../../config/jwt.config';
|
|
||||||
import { ImmichJwtModule } from '../../modules/immich-jwt/immich-jwt.module';
|
|
||||||
import { ImmichJwtService } from '../../modules/immich-jwt/immich-jwt.service';
|
|
||||||
import { UserRepository, IUserRepository } from './user-repository';
|
|
||||||
import { UserController } from './user.controller';
|
|
||||||
import { UserService } from './user.service';
|
|
||||||
|
|
||||||
const USER_REPOSITORY_PROVIDER = {
|
|
||||||
provide: IUserRepository,
|
|
||||||
useClass: UserRepository,
|
|
||||||
};
|
|
||||||
|
|
||||||
@Module({
|
|
||||||
imports: [TypeOrmModule.forFeature([UserEntity]), ImmichJwtModule, JwtModule.register(jwtConfig)],
|
|
||||||
controllers: [UserController],
|
|
||||||
providers: [UserService, ImmichJwtService, USER_REPOSITORY_PROVIDER],
|
|
||||||
exports: [USER_REPOSITORY_PROVIDER],
|
|
||||||
})
|
|
||||||
export class UserModule {}
|
|
@ -1,6 +1,5 @@
|
|||||||
import { immichAppConfig, immichBullAsyncConfig } from '@app/common/config';
|
import { immichAppConfig, immichBullAsyncConfig } from '@app/common/config';
|
||||||
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
|
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
|
||||||
import { UserModule } from './api-v1/user/user.module';
|
|
||||||
import { AssetModule } from './api-v1/asset/asset.module';
|
import { AssetModule } from './api-v1/asset/asset.module';
|
||||||
import { AuthModule } from './api-v1/auth/auth.module';
|
import { AuthModule } from './api-v1/auth/auth.module';
|
||||||
import { APIKeyModule } from './api-v1/api-key/api-key.module';
|
import { APIKeyModule } from './api-v1/api-key/api-key.module';
|
||||||
@ -15,20 +14,23 @@ import { AlbumModule } from './api-v1/album/album.module';
|
|||||||
import { AppController } from './app.controller';
|
import { AppController } from './app.controller';
|
||||||
import { ScheduleModule } from '@nestjs/schedule';
|
import { ScheduleModule } from '@nestjs/schedule';
|
||||||
import { ScheduleTasksModule } from './modules/schedule-tasks/schedule-tasks.module';
|
import { ScheduleTasksModule } from './modules/schedule-tasks/schedule-tasks.module';
|
||||||
import { DatabaseModule } from '@app/database';
|
|
||||||
import { JobModule } from './api-v1/job/job.module';
|
import { JobModule } from './api-v1/job/job.module';
|
||||||
import { SystemConfigModule } from './api-v1/system-config/system-config.module';
|
import { SystemConfigModule } from './api-v1/system-config/system-config.module';
|
||||||
import { OAuthModule } from './api-v1/oauth/oauth.module';
|
import { OAuthModule } from './api-v1/oauth/oauth.module';
|
||||||
import { TagModule } from './api-v1/tag/tag.module';
|
import { TagModule } from './api-v1/tag/tag.module';
|
||||||
import { ImmichConfigModule } from '@app/immich-config';
|
import { ImmichConfigModule } from '@app/immich-config';
|
||||||
import { ShareModule } from './api-v1/share/share.module';
|
import { ShareModule } from './api-v1/share/share.module';
|
||||||
|
import { DomainModule } from '@app/domain';
|
||||||
|
import { InfraModule } from '@app/infra';
|
||||||
|
import { UserController } from './controllers';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
ConfigModule.forRoot(immichAppConfig),
|
ConfigModule.forRoot(immichAppConfig),
|
||||||
|
|
||||||
DatabaseModule,
|
DomainModule.register({
|
||||||
UserModule,
|
imports: [InfraModule],
|
||||||
|
}),
|
||||||
|
|
||||||
APIKeyModule,
|
APIKeyModule,
|
||||||
|
|
||||||
@ -64,7 +66,11 @@ import { ShareModule } from './api-v1/share/share.module';
|
|||||||
|
|
||||||
ShareModule,
|
ShareModule,
|
||||||
],
|
],
|
||||||
controllers: [AppController],
|
controllers: [
|
||||||
|
//
|
||||||
|
AppController,
|
||||||
|
UserController,
|
||||||
|
],
|
||||||
providers: [],
|
providers: [],
|
||||||
})
|
})
|
||||||
export class AppModule implements NestModule {
|
export class AppModule implements NestModule {
|
||||||
|
@ -51,7 +51,7 @@ function destination(req: Request, file: Express.Multer.File, cb: any) {
|
|||||||
|
|
||||||
const basePath = APP_UPLOAD_LOCATION;
|
const basePath = APP_UPLOAD_LOCATION;
|
||||||
const sanitizedDeviceId = sanitize(String(req.body['deviceId']));
|
const sanitizedDeviceId = sanitize(String(req.body['deviceId']));
|
||||||
const originalUploadFolder = join(basePath, req.user.id, 'original', sanitizedDeviceId);
|
const originalUploadFolder = join(basePath, user.id, 'original', sanitizedDeviceId);
|
||||||
|
|
||||||
if (!existsSync(originalUploadFolder)) {
|
if (!existsSync(originalUploadFolder)) {
|
||||||
mkdirSync(originalUploadFolder, { recursive: true });
|
mkdirSync(originalUploadFolder, { recursive: true });
|
||||||
|
@ -6,6 +6,7 @@ import { existsSync, mkdirSync } from 'fs';
|
|||||||
import { diskStorage } from 'multer';
|
import { diskStorage } from 'multer';
|
||||||
import { extname } from 'path';
|
import { extname } from 'path';
|
||||||
import sanitize from 'sanitize-filename';
|
import sanitize from 'sanitize-filename';
|
||||||
|
import { AuthUserDto } from '../decorators/auth-user.decorator';
|
||||||
import { patchFormData } from '../utils/path-form-data.util';
|
import { patchFormData } from '../utils/path-form-data.util';
|
||||||
|
|
||||||
export const profileImageUploadOption: MulterOptions = {
|
export const profileImageUploadOption: MulterOptions = {
|
||||||
@ -35,8 +36,10 @@ function destination(req: Request, file: Express.Multer.File, cb: any) {
|
|||||||
return cb(new UnauthorizedException());
|
return cb(new UnauthorizedException());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const user = req.user as AuthUserDto;
|
||||||
|
|
||||||
const basePath = APP_UPLOAD_LOCATION;
|
const basePath = APP_UPLOAD_LOCATION;
|
||||||
const profileImageLocation = `${basePath}/${req.user.id}/profile`;
|
const profileImageLocation = `${basePath}/${user.id}/profile`;
|
||||||
|
|
||||||
if (!existsSync(profileImageLocation)) {
|
if (!existsSync(profileImageLocation)) {
|
||||||
mkdirSync(profileImageLocation, { recursive: true });
|
mkdirSync(profileImageLocation, { recursive: true });
|
||||||
|
1
server/apps/immich/src/controllers/index.ts
Normal file
1
server/apps/immich/src/controllers/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './user.controller';
|
@ -15,20 +15,20 @@ import {
|
|||||||
StreamableFile,
|
StreamableFile,
|
||||||
Header,
|
Header,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { UserService } from './user.service';
|
import { UserService } from '@app/domain';
|
||||||
import { Authenticated } from '../../decorators/authenticated.decorator';
|
import { Authenticated } from '../decorators/authenticated.decorator';
|
||||||
import { AuthUserDto, GetAuthUser } from '../../decorators/auth-user.decorator';
|
import { AuthUserDto, GetAuthUser } from '../decorators/auth-user.decorator';
|
||||||
import { CreateUserDto } from './dto/create-user.dto';
|
import { CreateUserDto } from '@app/domain';
|
||||||
import { UpdateUserDto } from './dto/update-user.dto';
|
import { UpdateUserDto } from '@app/domain';
|
||||||
import { FileInterceptor } from '@nestjs/platform-express';
|
import { FileInterceptor } from '@nestjs/platform-express';
|
||||||
import { profileImageUploadOption } from '../../config/profile-image-upload.config';
|
import { profileImageUploadOption } from '../config/profile-image-upload.config';
|
||||||
import { Response as Res } from 'express';
|
import { Response as Res } from 'express';
|
||||||
import { ApiBearerAuth, ApiBody, ApiConsumes, ApiTags } from '@nestjs/swagger';
|
import { ApiBearerAuth, ApiBody, ApiConsumes, ApiTags } from '@nestjs/swagger';
|
||||||
import { UserResponseDto } from './response-dto/user-response.dto';
|
import { UserResponseDto } from '@app/domain';
|
||||||
import { UserCountResponseDto } from './response-dto/user-count-response.dto';
|
import { UserCountResponseDto } from '@app/domain';
|
||||||
import { CreateProfileImageDto } from './dto/create-profile-image.dto';
|
import { CreateProfileImageDto } from '@app/domain';
|
||||||
import { CreateProfileImageResponseDto } from './response-dto/create-profile-image-response.dto';
|
import { CreateProfileImageResponseDto } from '@app/domain';
|
||||||
import { UserCountDto } from './dto/user-count.dto';
|
import { UserCountDto } from '@app/domain';
|
||||||
|
|
||||||
@ApiTags('User')
|
@ApiTags('User')
|
||||||
@Controller('user')
|
@Controller('user')
|
@ -1,14 +1,6 @@
|
|||||||
|
export { AuthUserDto } from '@app/domain';
|
||||||
|
import { AuthUserDto } from '@app/domain';
|
||||||
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
|
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
|
||||||
// import { AuthUserDto } from './dto/auth-user.dto';
|
|
||||||
|
|
||||||
export class AuthUserDto {
|
|
||||||
id!: string;
|
|
||||||
email!: string;
|
|
||||||
isAdmin!: boolean;
|
|
||||||
isPublicUser?: boolean;
|
|
||||||
sharedLinkId?: string;
|
|
||||||
isAllowUpload?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const GetAuthUser = createParamDecorator((data, ctx: ExecutionContext): AuthUserDto => {
|
export const GetAuthUser = createParamDecorator((data, ctx: ExecutionContext): AuthUserDto => {
|
||||||
return ctx.switchToHttp().getRequest<{ user: AuthUserDto }>().user;
|
return ctx.switchToHttp().getRequest<{ user: AuthUserDto }>().user;
|
||||||
|
4
server/apps/immich/src/global.d.ts
vendored
4
server/apps/immich/src/global.d.ts
vendored
@ -1,8 +1,8 @@
|
|||||||
import { UserResponseDto } from './api-v1/user/response-dto/user-response.dto';
|
import { AuthUserDto } from './decorators/auth-user.decorator';
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
namespace Express {
|
namespace Express {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||||
interface User extends UserResponseDto {}
|
interface User extends AuthUserDto {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { CanActivate, ExecutionContext, Injectable, Logger } from '@nestjs/common';
|
import { CanActivate, ExecutionContext, Injectable, Logger } from '@nestjs/common';
|
||||||
import { Request } from 'express';
|
import { Request } from 'express';
|
||||||
import { UserResponseDto } from '../api-v1/user/response-dto/user-response.dto';
|
import { UserResponseDto } from '@app/domain';
|
||||||
|
|
||||||
interface UserRequest extends Request {
|
interface UserRequest extends Request {
|
||||||
user: UserResponseDto;
|
user: UserResponseDto;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { BullModule } from '@nestjs/bull';
|
import { BullModule } from '@nestjs/bull';
|
||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { AssetEntity, ExifEntity, SmartInfoEntity } from '@app/database';
|
import { AssetEntity, ExifEntity, SmartInfoEntity } from '@app/infra';
|
||||||
import { BackgroundTaskProcessor } from './background-task.processor';
|
import { BackgroundTaskProcessor } from './background-task.processor';
|
||||||
import { BackgroundTaskService } from './background-task.service';
|
import { BackgroundTaskService } from './background-task.service';
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Process, Processor } from '@nestjs/bull';
|
import { Process, Processor } from '@nestjs/bull';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { AssetEntity, SmartInfoEntity } from '@app/database';
|
import { AssetEntity, SmartInfoEntity } from '@app/infra';
|
||||||
import { Job } from 'bull';
|
import { Job } from 'bull';
|
||||||
import { AssetResponseDto } from '../../api-v1/asset/response-dto/asset-response.dto';
|
import { AssetResponseDto } from '../../api-v1/asset/response-dto/asset-response.dto';
|
||||||
import { assetUtils } from '@app/common/utils';
|
import { assetUtils } from '@app/common/utils';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { AssetEntity } from '@app/database';
|
import { AssetEntity } from '@app/infra';
|
||||||
import { BadRequestException, Injectable, InternalServerErrorException, Logger, StreamableFile } from '@nestjs/common';
|
import { BadRequestException, Injectable, InternalServerErrorException, Logger, StreamableFile } from '@nestjs/common';
|
||||||
import archiver from 'archiver';
|
import archiver from 'archiver';
|
||||||
import { extname } from 'path';
|
import { extname } from 'path';
|
||||||
|
@ -4,7 +4,7 @@ import { JwtModule } from '@nestjs/jwt';
|
|||||||
import { jwtConfig } from '../../config/jwt.config';
|
import { jwtConfig } from '../../config/jwt.config';
|
||||||
import { JwtStrategy } from './strategies/jwt.strategy';
|
import { JwtStrategy } from './strategies/jwt.strategy';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { UserEntity } from '@app/database';
|
import { UserEntity } from '@app/infra';
|
||||||
import { APIKeyModule } from '../../api-v1/api-key/api-key.module';
|
import { APIKeyModule } from '../../api-v1/api-key/api-key.module';
|
||||||
import { APIKeyStrategy } from './strategies/api-key.strategy';
|
import { APIKeyStrategy } from './strategies/api-key.strategy';
|
||||||
import { ShareModule } from '../../api-v1/share/share.module';
|
import { ShareModule } from '../../api-v1/share/share.module';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Logger } from '@nestjs/common';
|
import { Logger } from '@nestjs/common';
|
||||||
import { JwtService } from '@nestjs/jwt';
|
import { JwtService } from '@nestjs/jwt';
|
||||||
import { Request } from 'express';
|
import { Request } from 'express';
|
||||||
import { UserEntity } from '../../../../../libs/database/src/entities/user.entity';
|
import { UserEntity } from '@app/infra';
|
||||||
import { LoginResponseDto } from '../../api-v1/auth/response-dto/login-response.dto';
|
import { LoginResponseDto } from '../../api-v1/auth/response-dto/login-response.dto';
|
||||||
import { AuthType } from '../../constants/jwt.constant';
|
import { AuthType } from '../../constants/jwt.constant';
|
||||||
import { ImmichJwtService } from './immich-jwt.service';
|
import { ImmichJwtService } from './immich-jwt.service';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { UserEntity } from '@app/database';
|
import { UserEntity } from '@app/infra';
|
||||||
import { Injectable, Logger } from '@nestjs/common';
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
import { JwtService } from '@nestjs/jwt';
|
import { JwtService } from '@nestjs/jwt';
|
||||||
import { Request } from 'express';
|
import { Request } from 'express';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { UserEntity } from '@app/database';
|
import { UserEntity } from '@app/infra';
|
||||||
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
||||||
import { PassportStrategy } from '@nestjs/passport';
|
import { PassportStrategy } from '@nestjs/passport';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { UserEntity } from '@app/database';
|
import { UserEntity } from '@app/infra';
|
||||||
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
||||||
import { PassportStrategy } from '@nestjs/passport';
|
import { PassportStrategy } from '@nestjs/passport';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { BullModule } from '@nestjs/bull';
|
import { BullModule } from '@nestjs/bull';
|
||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { AssetEntity, ExifEntity, UserEntity } from '@app/database';
|
import { AssetEntity, ExifEntity, UserEntity } from '@app/infra';
|
||||||
import { ScheduleTasksService } from './schedule-tasks.service';
|
import { ScheduleTasksService } from './schedule-tasks.service';
|
||||||
import { immichSharedQueues } from '@app/job/constants/bull-queue-registration.constant';
|
import { immichSharedQueues } from '@app/job/constants/bull-queue-registration.constant';
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import { Injectable, Logger } from '@nestjs/common';
|
|||||||
import { Cron, CronExpression } from '@nestjs/schedule';
|
import { Cron, CronExpression } from '@nestjs/schedule';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { IsNull, Not, Repository } from 'typeorm';
|
import { IsNull, Not, Repository } from 'typeorm';
|
||||||
import { AssetEntity, AssetType, ExifEntity, UserEntity } from '@app/database';
|
import { AssetEntity, AssetType, ExifEntity, UserEntity } from '@app/infra';
|
||||||
import { InjectQueue } from '@nestjs/bull';
|
import { InjectQueue } from '@nestjs/bull';
|
||||||
import { Queue } from 'bull';
|
import { Queue } from 'bull';
|
||||||
import { randomUUID } from 'crypto';
|
import { randomUUID } from 'crypto';
|
||||||
|
@ -3,13 +3,12 @@ import { INestApplication } from '@nestjs/common';
|
|||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
import { clearDb, getAuthUser, authCustom } from './test-utils';
|
import { clearDb, getAuthUser, authCustom } from './test-utils';
|
||||||
import { databaseConfig } from '@app/database';
|
import { databaseConfig } from '@app/infra';
|
||||||
import { AlbumModule } from '../src/api-v1/album/album.module';
|
import { AlbumModule } from '../src/api-v1/album/album.module';
|
||||||
import { CreateAlbumDto } from '../src/api-v1/album/dto/create-album.dto';
|
import { CreateAlbumDto } from '../src/api-v1/album/dto/create-album.dto';
|
||||||
import { ImmichJwtModule } from '../src/modules/immich-jwt/immich-jwt.module';
|
import { ImmichJwtModule } from '../src/modules/immich-jwt/immich-jwt.module';
|
||||||
import { AuthUserDto } from '../src/decorators/auth-user.decorator';
|
import { AuthUserDto } from '../src/decorators/auth-user.decorator';
|
||||||
import { UserService } from '../src/api-v1/user/user.service';
|
import { UserService } from '@app/domain';
|
||||||
import { UserModule } from '../src/api-v1/user/user.module';
|
|
||||||
import { DataSource } from 'typeorm';
|
import { DataSource } from 'typeorm';
|
||||||
|
|
||||||
function _createAlbum(app: INestApplication, data: CreateAlbumDto) {
|
function _createAlbum(app: INestApplication, data: CreateAlbumDto) {
|
||||||
@ -52,7 +51,7 @@ describe('Album', () => {
|
|||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
const builder = Test.createTestingModule({
|
const builder = Test.createTestingModule({
|
||||||
imports: [AlbumModule, UserModule, TypeOrmModule.forRoot(databaseConfig)],
|
imports: [AlbumModule, TypeOrmModule.forRoot(databaseConfig)],
|
||||||
});
|
});
|
||||||
authUser = getAuthUser(); // set default auth user
|
authUser = getAuthUser(); // set default auth user
|
||||||
const moduleFixture: TestingModule = await authCustom(builder, () => authUser).compile();
|
const moduleFixture: TestingModule = await authCustom(builder, () => authUser).compile();
|
||||||
|
@ -7,15 +7,11 @@
|
|||||||
"^.+\\.(t|j)s$": "ts-jest"
|
"^.+\\.(t|j)s$": "ts-jest"
|
||||||
},
|
},
|
||||||
"moduleNameMapper": {
|
"moduleNameMapper": {
|
||||||
"^@app/database(|/.*)$": "<rootDir>../../../libs/database/src/$1",
|
"^@app/common": "<rootDir>../../../libs/common/src",
|
||||||
"@app/database/config": "<rootDir>../../../libs/database/src/config",
|
|
||||||
"@app/database/config/(.*)": "<rootDir>../../../libs/database/src/config/$1",
|
|
||||||
"@app/database/entities/(.*)": "<rootDir>../../../libs/database/src/entities/$1",
|
|
||||||
"@app/common": "<rootDir>../../../libs/common/src",
|
|
||||||
"@app/common/(.*)": "<rootDir>../../../libs/common/src/$1",
|
|
||||||
"^@app/job(|/.*)$": "<rootDir>../../../libs/job/src/$1",
|
"^@app/job(|/.*)$": "<rootDir>../../../libs/job/src/$1",
|
||||||
"@app/job": "<rootDir>../../../libs/job/src",
|
|
||||||
"^@app/immich-config(|/.*)$": "<rootDir>../../../libs/immich-config/src/$1",
|
"^@app/immich-config(|/.*)$": "<rootDir>../../../libs/immich-config/src/$1",
|
||||||
"^@app/storage(|/.*)$": "<rootDir>../../../libs/storage/src/$1"
|
"^@app/storage(|/.*)$": "<rootDir>../../../libs/storage/src/$1",
|
||||||
|
"^@app/infra(|/.*)$": "<rootDir>../../../libs/infra/src/$1",
|
||||||
|
"^@app/domain(|/.*)$": "<rootDir>../../../libs/domain/src/$1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
||||||
import { TestingModuleBuilder } from '@nestjs/testing';
|
import { TestingModuleBuilder } from '@nestjs/testing';
|
||||||
import { DataSource } from 'typeorm';
|
import { DataSource } from 'typeorm';
|
||||||
import { IUserRepository } from '../src/api-v1/user/user-repository';
|
|
||||||
import { AuthUserDto } from '../src/decorators/auth-user.decorator';
|
import { AuthUserDto } from '../src/decorators/auth-user.decorator';
|
||||||
import { AuthGuard } from '../src/modules/immich-jwt/guards/auth.guard';
|
import { AuthGuard } from '../src/modules/immich-jwt/guards/auth.guard';
|
||||||
|
|
||||||
@ -15,20 +14,6 @@ export async function clearDb(db: DataSource) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function newUserRepositoryMock(): jest.Mocked<IUserRepository> {
|
|
||||||
return {
|
|
||||||
get: jest.fn(),
|
|
||||||
getAdmin: jest.fn(),
|
|
||||||
getByEmail: jest.fn(),
|
|
||||||
getByOAuthId: jest.fn(),
|
|
||||||
getList: jest.fn(),
|
|
||||||
create: jest.fn(),
|
|
||||||
update: jest.fn(),
|
|
||||||
delete: jest.fn(),
|
|
||||||
restore: jest.fn(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAuthUser(): AuthUserDto {
|
export function getAuthUser(): AuthUserDto {
|
||||||
return {
|
return {
|
||||||
id: '3108ac14-8afb-4b7e-87fd-39ebb6b79750',
|
id: '3108ac14-8afb-4b7e-87fd-39ebb6b79750',
|
||||||
|
@ -3,12 +3,9 @@ import { INestApplication } from '@nestjs/common';
|
|||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
import { clearDb, authCustom } from './test-utils';
|
import { clearDb, authCustom } from './test-utils';
|
||||||
import { databaseConfig } from '@app/database/config/database.config';
|
import { databaseConfig } from '@app/infra';
|
||||||
import { UserModule } from '../src/api-v1/user/user.module';
|
|
||||||
import { ImmichJwtModule } from '../src/modules/immich-jwt/immich-jwt.module';
|
import { ImmichJwtModule } from '../src/modules/immich-jwt/immich-jwt.module';
|
||||||
import { UserService } from '../src/api-v1/user/user.service';
|
import { CreateAdminDto, CreateUserDto, UserResponseDto, UserService } from '@app/domain';
|
||||||
import { CreateAdminDto, CreateUserDto } from '../src/api-v1/user/dto/create-user.dto';
|
|
||||||
import { UserResponseDto } from '../src/api-v1/user/response-dto/user-response.dto';
|
|
||||||
import { DataSource } from 'typeorm';
|
import { DataSource } from 'typeorm';
|
||||||
|
|
||||||
function _createUser(userService: UserService, data: CreateUserDto | CreateAdminDto) {
|
function _createUser(userService: UserService, data: CreateUserDto | CreateAdminDto) {
|
||||||
@ -27,7 +24,7 @@ describe('User', () => {
|
|||||||
describe('without auth', () => {
|
describe('without auth', () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
const moduleFixture: TestingModule = await Test.createTestingModule({
|
const moduleFixture: TestingModule = await Test.createTestingModule({
|
||||||
imports: [UserModule, ImmichJwtModule, TypeOrmModule.forRoot(databaseConfig)],
|
imports: [ImmichJwtModule, TypeOrmModule.forRoot(databaseConfig)],
|
||||||
}).compile();
|
}).compile();
|
||||||
|
|
||||||
app = moduleFixture.createNestApplication();
|
app = moduleFixture.createNestApplication();
|
||||||
@ -51,7 +48,7 @@ describe('User', () => {
|
|||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
const builder = Test.createTestingModule({
|
const builder = Test.createTestingModule({
|
||||||
imports: [UserModule, TypeOrmModule.forRoot(databaseConfig)],
|
imports: [TypeOrmModule.forRoot(databaseConfig)],
|
||||||
});
|
});
|
||||||
const moduleFixture: TestingModule = await authCustom(builder, () => authUser).compile();
|
const moduleFixture: TestingModule = await authCustom(builder, () => authUser).compile();
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { immichAppConfig, immichBullAsyncConfig } from '@app/common/config';
|
import { immichAppConfig, immichBullAsyncConfig } from '@app/common/config';
|
||||||
import { DatabaseModule, AssetEntity, ExifEntity, SmartInfoEntity, UserEntity, APIKeyEntity } from '@app/database';
|
import { AssetEntity, ExifEntity, SmartInfoEntity, UserEntity, APIKeyEntity, InfraModule } from '@app/infra';
|
||||||
import { StorageModule } from '@app/storage';
|
import { StorageModule } from '@app/storage';
|
||||||
import { BullModule } from '@nestjs/bull';
|
import { BullModule } from '@nestjs/bull';
|
||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
@ -17,11 +17,14 @@ import { ThumbnailGeneratorProcessor } from './processors/thumbnail.processor';
|
|||||||
import { UserDeletionProcessor } from './processors/user-deletion.processor';
|
import { UserDeletionProcessor } from './processors/user-deletion.processor';
|
||||||
import { VideoTranscodeProcessor } from './processors/video-transcode.processor';
|
import { VideoTranscodeProcessor } from './processors/video-transcode.processor';
|
||||||
import { immichSharedQueues } from '@app/job/constants/bull-queue-registration.constant';
|
import { immichSharedQueues } from '@app/job/constants/bull-queue-registration.constant';
|
||||||
|
import { DomainModule } from '@app/domain';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
ConfigModule.forRoot(immichAppConfig),
|
ConfigModule.forRoot(immichAppConfig),
|
||||||
DatabaseModule,
|
DomainModule.register({
|
||||||
|
imports: [InfraModule],
|
||||||
|
}),
|
||||||
ImmichConfigModule,
|
ImmichConfigModule,
|
||||||
TypeOrmModule.forFeature([UserEntity, ExifEntity, AssetEntity, SmartInfoEntity, APIKeyEntity]),
|
TypeOrmModule.forFeature([UserEntity, ExifEntity, AssetEntity, SmartInfoEntity, APIKeyEntity]),
|
||||||
StorageModule,
|
StorageModule,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { AssetType } from '@app/database';
|
import { AssetType } from '@app/infra';
|
||||||
import {
|
import {
|
||||||
IAssetUploadedJob,
|
IAssetUploadedJob,
|
||||||
IMetadataExtractionJob,
|
IMetadataExtractionJob,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { AssetEntity } from '@app/database';
|
import { AssetEntity } from '@app/infra';
|
||||||
import { QueueNameEnum } from '@app/job';
|
import { QueueNameEnum } from '@app/job';
|
||||||
import { Process, Processor } from '@nestjs/bull';
|
import { Process, Processor } from '@nestjs/bull';
|
||||||
import { Logger } from '@nestjs/common';
|
import { Logger } from '@nestjs/common';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { AssetEntity } from '@app/database';
|
import { AssetEntity } from '@app/infra';
|
||||||
import { SmartInfoEntity } from '@app/database';
|
import { SmartInfoEntity } from '@app/infra';
|
||||||
import { MachineLearningJobNameEnum, QueueNameEnum } from '@app/job';
|
import { MachineLearningJobNameEnum, QueueNameEnum } from '@app/job';
|
||||||
import { IMachineLearningJob } from '@app/job/interfaces/machine-learning.interface';
|
import { IMachineLearningJob } from '@app/job/interfaces/machine-learning.interface';
|
||||||
import { Process, Processor } from '@nestjs/bull';
|
import { Process, Processor } from '@nestjs/bull';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ImmichLogLevel } from '@app/common/constants/log-level.constant';
|
import { ImmichLogLevel } from '@app/common/constants/log-level.constant';
|
||||||
import { AssetEntity, ExifEntity } from '@app/database';
|
import { AssetEntity, ExifEntity } from '@app/infra';
|
||||||
import {
|
import {
|
||||||
IExifExtractionProcessor,
|
IExifExtractionProcessor,
|
||||||
IVideoLengthExtractionProcessor,
|
IVideoLengthExtractionProcessor,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { APP_UPLOAD_LOCATION } from '@app/common';
|
import { APP_UPLOAD_LOCATION } from '@app/common';
|
||||||
import { AssetEntity } from '@app/database';
|
import { AssetEntity } from '@app/infra';
|
||||||
import { ImmichConfigService } from '@app/immich-config';
|
import { ImmichConfigService } from '@app/immich-config';
|
||||||
import { QueueNameEnum, templateMigrationProcessorName, updateTemplateProcessorName } from '@app/job';
|
import { QueueNameEnum, templateMigrationProcessorName, updateTemplateProcessorName } from '@app/job';
|
||||||
import { StorageService } from '@app/storage';
|
import { StorageService } from '@app/storage';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { APP_UPLOAD_LOCATION } from '@app/common';
|
import { APP_UPLOAD_LOCATION } from '@app/common';
|
||||||
import { AssetEntity, AssetType } from '@app/database';
|
import { AssetEntity, AssetType } from '@app/infra';
|
||||||
import {
|
import {
|
||||||
WebpGeneratorProcessor,
|
WebpGeneratorProcessor,
|
||||||
generateJPEGThumbnailProcessorName,
|
generateJPEGThumbnailProcessorName,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { APP_UPLOAD_LOCATION, userUtils } from '@app/common';
|
import { APP_UPLOAD_LOCATION, userUtils } from '@app/common';
|
||||||
import { APIKeyEntity, AssetEntity, UserEntity } from '@app/database';
|
import { APIKeyEntity, AssetEntity, UserEntity } from '@app/infra';
|
||||||
import { QueueNameEnum, userDeletionProcessorName } from '@app/job';
|
import { QueueNameEnum, userDeletionProcessorName } from '@app/job';
|
||||||
import { IUserDeletionJob } from '@app/job/interfaces/user-deletion.interface';
|
import { IUserDeletionJob } from '@app/job/interfaces/user-deletion.interface';
|
||||||
import { Process, Processor } from '@nestjs/bull';
|
import { Process, Processor } from '@nestjs/bull';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { APP_UPLOAD_LOCATION } from '@app/common/constants';
|
import { APP_UPLOAD_LOCATION } from '@app/common/constants';
|
||||||
import { AssetEntity } from '@app/database';
|
import { AssetEntity } from '@app/infra';
|
||||||
import { QueueNameEnum } from '@app/job';
|
import { QueueNameEnum } from '@app/job';
|
||||||
import { mp4ConversionProcessorName } from '@app/job/constants/job-name.constant';
|
import { mp4ConversionProcessorName } from '@app/job/constants/job-name.constant';
|
||||||
import { IMp4ConversionProcessor } from '@app/job/interfaces/video-transcode.interface';
|
import { IMp4ConversionProcessor } from '@app/job/interfaces/video-transcode.interface';
|
||||||
|
@ -473,147 +473,6 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/share": {
|
|
||||||
"get": {
|
|
||||||
"operationId": "getAllSharedLinks",
|
|
||||||
"parameters": [],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "",
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"$ref": "#/components/schemas/SharedLinkResponseDto"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tags": [
|
|
||||||
"share"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/share/me": {
|
|
||||||
"get": {
|
|
||||||
"operationId": "getMySharedLink",
|
|
||||||
"parameters": [],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "",
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/components/schemas/SharedLinkResponseDto"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tags": [
|
|
||||||
"share"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/share/{id}": {
|
|
||||||
"get": {
|
|
||||||
"operationId": "getSharedLinkById",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"name": "id",
|
|
||||||
"required": true,
|
|
||||||
"in": "path",
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "",
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/components/schemas/SharedLinkResponseDto"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tags": [
|
|
||||||
"share"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"delete": {
|
|
||||||
"operationId": "removeSharedLink",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"name": "id",
|
|
||||||
"required": true,
|
|
||||||
"in": "path",
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "",
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tags": [
|
|
||||||
"share"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"patch": {
|
|
||||||
"operationId": "editSharedLink",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"name": "id",
|
|
||||||
"required": true,
|
|
||||||
"in": "path",
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"requestBody": {
|
|
||||||
"required": true,
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/components/schemas/EditSharedLinkDto"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "",
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/components/schemas/SharedLinkResponseDto"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tags": [
|
|
||||||
"share"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/asset/upload": {
|
"/asset/upload": {
|
||||||
"post": {
|
"post": {
|
||||||
"operationId": "uploadFile",
|
"operationId": "uploadFile",
|
||||||
@ -1370,6 +1229,147 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/share": {
|
||||||
|
"get": {
|
||||||
|
"operationId": "getAllSharedLinks",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/SharedLinkResponseDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
"share"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/share/me": {
|
||||||
|
"get": {
|
||||||
|
"operationId": "getMySharedLink",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/SharedLinkResponseDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
"share"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/share/{id}": {
|
||||||
|
"get": {
|
||||||
|
"operationId": "getSharedLinkById",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"required": true,
|
||||||
|
"in": "path",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/SharedLinkResponseDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
"share"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"operationId": "removeSharedLink",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"required": true,
|
||||||
|
"in": "path",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
"share"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"patch": {
|
||||||
|
"operationId": "editSharedLink",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"required": true,
|
||||||
|
"in": "path",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/EditSharedLinkDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/SharedLinkResponseDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
"share"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"/album/count-by-user-id": {
|
"/album/count-by-user-id": {
|
||||||
"get": {
|
"get": {
|
||||||
"operationId": "getAlbumCountByUserId",
|
"operationId": "getAlbumCountByUserId",
|
||||||
@ -2879,11 +2879,114 @@
|
|||||||
"name"
|
"name"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"SharedLinkType": {
|
"AssetFileUploadDto": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"assetData": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "binary"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"assetData"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"AssetFileUploadResponseDto": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"DownloadFilesDto": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"assetIds": {
|
||||||
|
"title": "Array of asset ids to be downloaded",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"assetIds"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ThumbnailFormat": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"ALBUM",
|
"JPEG",
|
||||||
"INDIVIDUAL"
|
"WEBP"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CuratedObjectsResponseDto": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"object": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"resizePath": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"deviceAssetId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"deviceId": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"object",
|
||||||
|
"resizePath",
|
||||||
|
"deviceAssetId",
|
||||||
|
"deviceId"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CuratedLocationsResponseDto": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"city": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"resizePath": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"deviceAssetId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"deviceId": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"city",
|
||||||
|
"resizePath",
|
||||||
|
"deviceAssetId",
|
||||||
|
"deviceId"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"SearchAssetDto": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"searchTerm": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"searchTerm"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"AssetTypeEnum": {
|
"AssetTypeEnum": {
|
||||||
@ -3144,232 +3247,6 @@
|
|||||||
"tags"
|
"tags"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"AlbumResponseDto": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"assetCount": {
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"id": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"ownerId": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"albumName": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"createdAt": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"albumThumbnailAssetId": {
|
|
||||||
"type": "string",
|
|
||||||
"nullable": true
|
|
||||||
},
|
|
||||||
"shared": {
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"sharedUsers": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"$ref": "#/components/schemas/UserResponseDto"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"assets": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"$ref": "#/components/schemas/AssetResponseDto"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"assetCount",
|
|
||||||
"id",
|
|
||||||
"ownerId",
|
|
||||||
"albumName",
|
|
||||||
"createdAt",
|
|
||||||
"albumThumbnailAssetId",
|
|
||||||
"shared",
|
|
||||||
"sharedUsers",
|
|
||||||
"assets"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"SharedLinkResponseDto": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"type": {
|
|
||||||
"$ref": "#/components/schemas/SharedLinkType"
|
|
||||||
},
|
|
||||||
"id": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"description": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"userId": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"key": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"createdAt": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"expiresAt": {
|
|
||||||
"type": "string",
|
|
||||||
"nullable": true
|
|
||||||
},
|
|
||||||
"assets": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"$ref": "#/components/schemas/AssetResponseDto"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"album": {
|
|
||||||
"$ref": "#/components/schemas/AlbumResponseDto"
|
|
||||||
},
|
|
||||||
"allowUpload": {
|
|
||||||
"type": "boolean"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"type",
|
|
||||||
"id",
|
|
||||||
"userId",
|
|
||||||
"key",
|
|
||||||
"createdAt",
|
|
||||||
"expiresAt",
|
|
||||||
"assets",
|
|
||||||
"allowUpload"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"EditSharedLinkDto": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"description": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"expiredAt": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"allowUpload": {
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"isEditExpireTime": {
|
|
||||||
"type": "boolean"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AssetFileUploadDto": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"assetData": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "binary"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"assetData"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"AssetFileUploadResponseDto": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"id": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"id"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"DownloadFilesDto": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"assetIds": {
|
|
||||||
"title": "Array of asset ids to be downloaded",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"assetIds"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"ThumbnailFormat": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"JPEG",
|
|
||||||
"WEBP"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"CuratedObjectsResponseDto": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"id": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"object": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"resizePath": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"deviceAssetId": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"deviceId": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"id",
|
|
||||||
"object",
|
|
||||||
"resizePath",
|
|
||||||
"deviceAssetId",
|
|
||||||
"deviceId"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"CuratedLocationsResponseDto": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"id": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"city": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"resizePath": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"deviceAssetId": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"deviceId": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"id",
|
|
||||||
"city",
|
|
||||||
"resizePath",
|
|
||||||
"deviceAssetId",
|
|
||||||
"deviceId"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"SearchAssetDto": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"searchTerm": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"searchTerm"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"TimeGroupEnum": {
|
"TimeGroupEnum": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
@ -3596,6 +3473,129 @@
|
|||||||
"existingIds"
|
"existingIds"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"SharedLinkType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ALBUM",
|
||||||
|
"INDIVIDUAL"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"AlbumResponseDto": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"assetCount": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"ownerId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"albumName": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"albumThumbnailAssetId": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"shared": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"sharedUsers": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/UserResponseDto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"assets": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/AssetResponseDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"assetCount",
|
||||||
|
"id",
|
||||||
|
"ownerId",
|
||||||
|
"albumName",
|
||||||
|
"createdAt",
|
||||||
|
"albumThumbnailAssetId",
|
||||||
|
"shared",
|
||||||
|
"sharedUsers",
|
||||||
|
"assets"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"SharedLinkResponseDto": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"$ref": "#/components/schemas/SharedLinkType"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"key": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"expiresAt": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"assets": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/AssetResponseDto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"album": {
|
||||||
|
"$ref": "#/components/schemas/AlbumResponseDto"
|
||||||
|
},
|
||||||
|
"allowUpload": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"id",
|
||||||
|
"userId",
|
||||||
|
"key",
|
||||||
|
"createdAt",
|
||||||
|
"expiresAt",
|
||||||
|
"assets",
|
||||||
|
"allowUpload"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"EditSharedLinkDto": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"expiredAt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"allowUpload": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"isEditExpireTime": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"AlbumCountResponseDto": {
|
"AlbumCountResponseDto": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { AssetEntity } from '@app/database';
|
import { AssetEntity } from '@app/infra';
|
||||||
import { AssetResponseDto } from 'apps/immich/src/api-v1/asset/response-dto/asset-response.dto';
|
import { AssetResponseDto } from 'apps/immich/src/api-v1/asset/response-dto/asset-response.dto';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// create unit test for user utils
|
// create unit test for user utils
|
||||||
|
|
||||||
import { UserEntity } from '@app/database';
|
import { UserEntity } from '@app/infra';
|
||||||
import { userUtils } from './user-utils';
|
import { userUtils } from './user-utils';
|
||||||
|
|
||||||
describe('User Utilities', () => {
|
describe('User Utilities', () => {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { UserEntity } from '@app/database';
|
import { UserEntity } from '@app/infra';
|
||||||
|
|
||||||
function createUserUtils() {
|
function createUserUtils() {
|
||||||
const isReadyForDeletion = (user: UserEntity): boolean => {
|
const isReadyForDeletion = (user: UserEntity): boolean => {
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
import { Module } from '@nestjs/common';
|
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
||||||
import { databaseConfig } from './config/database.config';
|
|
||||||
|
|
||||||
@Module({
|
|
||||||
imports: [TypeOrmModule.forRoot(databaseConfig)],
|
|
||||||
providers: [],
|
|
||||||
exports: [TypeOrmModule],
|
|
||||||
})
|
|
||||||
export class DatabaseModule {}
|
|
8
server/libs/domain/src/auth/dto/auth-user.dto.ts
Normal file
8
server/libs/domain/src/auth/dto/auth-user.dto.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export class AuthUserDto {
|
||||||
|
id!: string;
|
||||||
|
email!: string;
|
||||||
|
isAdmin!: boolean;
|
||||||
|
isPublicUser?: boolean;
|
||||||
|
sharedLinkId?: string;
|
||||||
|
isAllowUpload?: boolean;
|
||||||
|
}
|
1
server/libs/domain/src/auth/dto/index.ts
Normal file
1
server/libs/domain/src/auth/dto/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './auth-user.dto';
|
1
server/libs/domain/src/auth/index.ts
Normal file
1
server/libs/domain/src/auth/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './dto';
|
20
server/libs/domain/src/domain.module.ts
Normal file
20
server/libs/domain/src/domain.module.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { DynamicModule, Global, Module, ModuleMetadata, Provider } from '@nestjs/common';
|
||||||
|
import { UserService } from './user';
|
||||||
|
|
||||||
|
const providers: Provider[] = [
|
||||||
|
//
|
||||||
|
UserService,
|
||||||
|
];
|
||||||
|
|
||||||
|
@Global()
|
||||||
|
@Module({})
|
||||||
|
export class DomainModule {
|
||||||
|
static register(options: Pick<ModuleMetadata, 'imports'>): DynamicModule {
|
||||||
|
return {
|
||||||
|
module: DomainModule,
|
||||||
|
imports: options.imports,
|
||||||
|
providers: [...providers],
|
||||||
|
exports: [...providers],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
3
server/libs/domain/src/index.ts
Normal file
3
server/libs/domain/src/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export * from './auth';
|
||||||
|
export * from './domain.module';
|
||||||
|
export * from './user';
|
4
server/libs/domain/src/user/dto/index.ts
Normal file
4
server/libs/domain/src/user/dto/index.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export * from './create-profile-image.dto';
|
||||||
|
export * from './create-user.dto';
|
||||||
|
export * from './update-user.dto';
|
||||||
|
export * from './user-count.dto';
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user