refactor backend names

This commit is contained in:
rubikscraft
2022-04-18 14:34:53 +02:00
parent 2273fefd27
commit 32dff04e84
71 changed files with 404 additions and 148 deletions

View File

@@ -1,12 +1,12 @@
import { Module } from '@nestjs/common';
import { ServeStaticModule } from '@nestjs/serve-static';
import { TypeOrmModule } from '@nestjs/typeorm';
import { EarlyConfigModule } from './config/early/earlyconfig.module';
import { ServeStaticConfigService } from './config/early/servestatic.config.service';
import { TypeOrmConfigService } from './config/early/typeorm.config.service';
import { EarlyConfigModule } from './config/early/early-config.module';
import { ServeStaticConfigService } from './config/early/serve-static.config.service';
import { TypeOrmConfigService } from './config/early/type-orm.config.service';
import { PicsurLoggerModule } from './logger/logger.module';
import { AuthManagerModule } from './managers/auth/auth.module';
import { DemoManagerModule } from './managers/demo/demomanager.module';
import { DemoManagerModule } from './managers/demo/demo.module';
import { PicsurRoutesModule } from './routes/routes.module';
@Module({

View File

@@ -1,7 +1,7 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { EImageBackend } from '../../models/entities/image.entity';
import { ImageDBService } from './imagedb.service';
import { ImageDBService } from './image-db.service';
@Module({
imports: [TypeOrmModule.forFeature([EImageBackend])],

View File

@@ -1,12 +1,12 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { EarlyConfigModule } from '../../config/early/earlyconfig.module';
import { ESysPreferenceBackend } from '../../models/entities/syspreference.entity';
import { EUsrPreferenceBackend } from '../../models/entities/usrpreference.entity';
import { PreferenceCommonService } from './preferencecommon.service';
import { PreferenceDefaultsService } from './preferencedefaults.service';
import { SysPreferenceService } from './syspreferencedb.service';
import { UsrPreferenceService } from './usrpreferencedb.service';
import { EarlyConfigModule } from '../../config/early/early-config.module';
import { ESysPreferenceBackend } from '../../models/entities/sys-preference.entity';
import { EUsrPreferenceBackend } from '../../models/entities/usr-preference.entity';
import { PreferenceCommonService } from './preference-common.service';
import { PreferenceDefaultsService } from './preference-defaults.service';
import { SysPreferenceService } from './sys-preference-db.service';
import { UsrPreferenceService } from './usr-preference-db.service';
@Module({
imports: [

View File

@@ -3,7 +3,7 @@ import { PrefValueType } from 'picsur-shared/dist/dto/preferences.dto';
import { SysPreference } from 'picsur-shared/dist/dto/sys-preferences.dto';
import { UsrPreference } from 'picsur-shared/dist/dto/usr-preferences.dto';
import { generateRandomString } from 'picsur-shared/dist/util/random';
import { EarlyJwtConfigService } from '../../config/early/earlyjwt.config.service';
import { EarlyJwtConfigService } from '../../config/early/early-jwt.config.service';
// This specific service is used to store default values for system preferences
// It needs to be in a service because the values depend on the environment

View File

@@ -11,14 +11,14 @@ import { Repository } from 'typeorm';
import {
SysPreferenceList,
SysPreferenceValueTypes
} from '../../models/dto/syspreferences.dto';
} from '../../models/constants/syspreferences.const';
import {
ESysPreferenceBackend,
ESysPreferenceSchema
} from '../../models/entities/syspreference.entity';
import { FallBackMutex } from '../../models/util/FallBackMutex';
import { PreferenceCommonService } from './preferencecommon.service';
import { PreferenceDefaultsService } from './preferencedefaults.service';
} from '../../models/entities/sys-preference.entity';
import { MutexFallBack } from '../../models/util/mutex-fallback';
import { PreferenceCommonService } from './preference-common.service';
import { PreferenceDefaultsService } from './preference-defaults.service';
@Injectable()
export class SysPreferenceService {
@@ -66,7 +66,7 @@ export class SysPreferenceService {
let foundSysPreference: ESysPreferenceBackend;
try {
foundSysPreference = await FallBackMutex(
foundSysPreference = await MutexFallBack(
'fetchSysPrefrence',
() =>
this.sysPreferenceRepository.findOne({

View File

@@ -11,14 +11,14 @@ import { Repository } from 'typeorm';
import {
UsrPreferenceList,
UsrPreferenceValueTypes
} from '../../models/dto/usrpreferences.dto';
} from '../../models/constants/usrpreferences.const';
import {
EUsrPreferenceBackend,
EUsrPreferenceSchema
} from '../../models/entities/usrpreference.entity';
import { FallBackMutex } from '../../models/util/FallBackMutex';
import { PreferenceCommonService } from './preferencecommon.service';
import { PreferenceDefaultsService } from './preferencedefaults.service';
} from '../../models/entities/usr-preference.entity';
import { MutexFallBack } from '../../models/util/mutex-fallback';
import { PreferenceCommonService } from './preference-common.service';
import { PreferenceDefaultsService } from './preference-defaults.service';
@Injectable()
export class UsrPreferenceService {
@@ -71,7 +71,7 @@ export class UsrPreferenceService {
let foundUsrPreference: EUsrPreferenceBackend;
try {
foundUsrPreference = await FallBackMutex(
foundUsrPreference = await MutexFallBack(
'fetchUsrPrefrence',
() =>
this.usrPreferenceRepository.findOne({

View File

@@ -1,11 +1,11 @@
import { Logger, Module, OnModuleInit } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { HasFailed } from 'picsur-shared/dist/types';
import { EarlyConfigModule } from '../../config/early/earlyconfig.module';
import { EarlyConfigModule } from '../../config/early/early-config.module';
import { HostConfigService } from '../../config/early/host.config.service';
import { ImmutableRolesList, SystemRoleDefaults, UndeletableRolesList } from '../../models/dto/roles.dto';
import { ImmutableRolesList, SystemRoleDefaults, UndeletableRolesList } from '../../models/constants/roles.const';
import { ERoleBackend } from '../../models/entities/role.entity';
import { RolesService } from './roledb.service';
import { RolesService } from './role-db.service';
@Module({
imports: [EarlyConfigModule, TypeOrmModule.forFeature([ERoleBackend])],

View File

@@ -9,11 +9,11 @@ import {
} from 'picsur-shared/dist/types';
import { makeUnique } from 'picsur-shared/dist/util/unique';
import { In, Repository } from 'typeorm';
import { Permissions } from '../../models/dto/permissions.dto';
import { Permissions } from '../../models/constants/permissions.const';
import {
ImmutableRolesList,
UndeletableRolesList
} from '../../models/dto/roles.dto';
} from '../../models/constants/roles.const';
import { ERoleBackend } from '../../models/entities/role.entity';
@Injectable()

View File

@@ -3,11 +3,11 @@ import { TypeOrmModule } from '@nestjs/typeorm';
import { HasFailed } from 'picsur-shared/dist/types';
import { generateRandomString } from 'picsur-shared/dist/util/random';
import { AuthConfigService } from '../../config/early/auth.config.service';
import { EarlyConfigModule } from '../../config/early/earlyconfig.module';
import { EarlyConfigModule } from '../../config/early/early-config.module';
import { EUserBackend } from '../../models/entities/user.entity';
import { PreferenceModule } from '../preferencesdb/preferencedb.module';
import { RolesModule } from '../roledb/roledb.module';
import { UsersService } from './userdb.service';
import { PreferenceModule } from '../preference-db/preference-db.module';
import { RolesModule } from '../role-db/role-db.module';
import { UsersService } from './user-db.service';
@Module({
imports: [

View File

@@ -10,20 +10,20 @@ import {
} from 'picsur-shared/dist/types';
import { makeUnique } from 'picsur-shared/dist/util/unique';
import { Repository } from 'typeorm';
import { Permissions } from '../../models/dto/permissions.dto';
import { Permissions } from '../../models/constants/permissions.const';
import {
DefaultRolesList,
SoulBoundRolesList
} from '../../models/dto/roles.dto';
} from '../../models/constants/roles.const';
import {
ImmutableUsersList,
LockedLoginUsersList,
UndeletableUsersList
} from '../../models/dto/specialusers.dto';
} from '../../models/constants/special-users.const';
import { EUserBackend } from '../../models/entities/user.entity';
import { GetCols } from '../../models/util/collection';
import { SysPreferenceService } from '../preferencesdb/syspreferencedb.service';
import { RolesService } from '../roledb/roledb.service';
import { SysPreferenceService } from '../preference-db/sys-preference-db.service';
import { RolesService } from '../role-db/role-db.service';
@Injectable()
export class UsersService {

View File

@@ -0,0 +1,254 @@
import { Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import * as bcrypt from 'bcrypt';
import { SysPreference } from 'picsur-shared/dist/dto/sys-preferences.dto';
import {
AsyncFailable,
Fail,
HasFailed,
HasSuccess
} from 'picsur-shared/dist/types';
import { makeUnique } from 'picsur-shared/dist/util/unique';
import { Repository } from 'typeorm';
import { Permissions } from '../../models/constants/permissions.const';
import {
DefaultRolesList,
SoulBoundRolesList
} from '../../models/constants/roles.const';
import {
ImmutableUsersList,
LockedLoginUsersList,
UndeletableUsersList
} from '../../models/constants/special-users.const';
import { EUserBackend } from '../../models/entities/user.entity';
import { GetCols } from '../../models/util/collection';
import { SysPreferenceService } from '../preference-db/sys-preference-db.service';
import { RolesService } from '../role-db/role-db.service';
@Injectable()
export class UsersService {
private readonly logger = new Logger('UsersService');
constructor(
@InjectRepository(EUserBackend)
private usersRepository: Repository<EUserBackend>,
private rolesService: RolesService,
private prefService: SysPreferenceService,
) {}
// Creation and deletion
public async create(
username: string,
password: string,
roles?: string[],
// Add option to create "invalid" users, should only be used by system
byPassRoleCheck?: boolean,
): AsyncFailable<EUserBackend> {
if (await this.exists(username)) return Fail('User already exists');
const strength = await this.getBCryptStrength();
const hashedPassword = await bcrypt.hash(password, strength);
let user = new EUserBackend();
user.username = username;
user.hashedPassword = hashedPassword;
if (byPassRoleCheck) {
const rolesToAdd = roles ?? [];
user.roles = makeUnique(rolesToAdd);
} else {
// Strip soulbound roles and add default roles
const rolesToAdd = this.filterAddedRoles(roles ?? []);
user.roles = makeUnique([...DefaultRolesList, ...rolesToAdd]);
}
try {
return await this.usersRepository.save(user);
} catch (e: any) {
return Fail(e?.message);
}
}
public async delete(uuid: string): AsyncFailable<EUserBackend> {
const userToModify = await this.findOne(uuid);
if (HasFailed(userToModify)) return userToModify;
if (UndeletableUsersList.includes(userToModify.username)) {
return Fail('Cannot delete system user');
}
try {
return await this.usersRepository.remove(userToModify);
} catch (e: any) {
return Fail(e?.message);
}
}
// Updating
public async setRoles(
uuid: string,
roles: string[],
): AsyncFailable<EUserBackend> {
const userToModify = await this.findOne(uuid);
if (HasFailed(userToModify)) return userToModify;
if (ImmutableUsersList.includes(userToModify.username)) {
// Just fail silently
this.logger.log("Can't modify system user");
return userToModify;
}
const rolesToKeep = userToModify.roles.filter((role) =>
SoulBoundRolesList.includes(role),
);
const rolesToAdd = this.filterAddedRoles(roles);
const newRoles = makeUnique([...rolesToKeep, ...rolesToAdd]);
userToModify.roles = newRoles;
try {
return await this.usersRepository.save(userToModify);
} catch (e: any) {
return Fail(e?.message);
}
}
public async removeRoleEveryone(role: string): AsyncFailable<true> {
try {
await this.usersRepository
.createQueryBuilder('user')
.update()
.set({
roles: () => 'ARRAY_REMOVE(roles, :role)',
})
.where('roles @> ARRAY[:role]', { role })
.execute();
} catch (e) {
this.logger.error(e);
return Fail("Couldn't remove role from everyone");
}
return true;
}
public async getPermissions(uuid: string): AsyncFailable<Permissions> {
const userToModify = await this.findOne(uuid);
if (HasFailed(userToModify)) return userToModify;
return await this.rolesService.getPermissions(userToModify.roles);
}
public async updatePassword(
uuid: string,
password: string,
): AsyncFailable<EUserBackend> {
let userToModify = await this.findOne(uuid);
if (HasFailed(userToModify)) return userToModify;
const strength = await this.getBCryptStrength();
userToModify.hashedPassword = await bcrypt.hash(password, strength);
try {
userToModify = await this.usersRepository.save(userToModify);
} catch (e: any) {
return Fail(e?.message);
}
return userToModify;
}
// Authentication
async authenticate(
username: string,
password: string,
): AsyncFailable<EUserBackend> {
const user = await this.findByUsername(username, true);
if (HasFailed(user)) return user;
if (LockedLoginUsersList.includes(user.username)) {
// Error should be kept in backend
return Fail('Wrong username');
}
if (!(await bcrypt.compare(password, user.hashedPassword ?? '')))
return Fail('Wrong password');
return await this.findOne(user.id ?? '');
}
// Listing
public async findByUsername(
username: string,
// Also fetch fields that aren't normally sent to the client
// (e.g. hashed password)
getPrivate: boolean = false,
): AsyncFailable<EUserBackend> {
try {
const found = await this.usersRepository.findOne({
where: { username },
select: getPrivate ? GetCols(this.usersRepository) : undefined,
});
if (!found) return Fail('User not found');
return found;
} catch (e: any) {
return Fail(e?.message);
}
}
public async findOne(uuid: string): AsyncFailable<EUserBackend> {
try {
const found = await this.usersRepository.findOne({
where: { id: uuid },
});
if (!found) return Fail('User not found');
return found as EUserBackend;
} catch (e: any) {
return Fail(e?.message);
}
}
public async findMany(
count: number,
page: number,
): AsyncFailable<EUserBackend[]> {
if (count < 1 || page < 0) return Fail('Invalid page');
if (count > 100) return Fail('Too many results');
try {
return await this.usersRepository.find({
take: count,
skip: count * page,
});
} catch (e: any) {
return Fail(e?.message);
}
}
public async exists(username: string): Promise<boolean> {
return HasSuccess(await this.findByUsername(username));
}
// Internal
private filterAddedRoles(roles: string[]): string[] {
const filteredRoles = roles.filter(
(role) => !SoulBoundRolesList.includes(role),
);
return filteredRoles;
}
private async getBCryptStrength(): Promise<number> {
const result = await this.prefService.getNumberPreference(
SysPreference.BCryptStrength,
);
if (HasFailed(result)) {
return 12;
}
return result;
}
}

View File

@@ -1,11 +1,11 @@
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { AuthConfigService } from './auth.config.service';
import { EarlyJwtConfigService } from './earlyjwt.config.service';
import { EarlyJwtConfigService } from './early-jwt.config.service';
import { HostConfigService } from './host.config.service';
import { MultipartConfigService } from './multipart.config.service';
import { ServeStaticConfigService } from './servestatic.config.service';
import { TypeOrmConfigService } from './typeorm.config.service';
import { ServeStaticConfigService } from './serve-static.config.service';
import { TypeOrmConfigService } from './type-orm.config.service';
@Module({
imports: [

View File

@@ -1,7 +1,7 @@
import { FactoryProvider, Injectable, Logger } from '@nestjs/common';
import { JwtModuleOptions, JwtOptionsFactory } from '@nestjs/jwt';
import { HasFailed } from 'picsur-shared/dist/types';
import { SysPreferenceService } from '../../collections/preferencesdb/syspreferencedb.service';
import { SysPreferenceService } from '../../collections/preference-db/sys-preference-db.service';
@Injectable()
export class JwtConfigService implements JwtOptionsFactory {

View File

@@ -1,8 +1,8 @@
import { Logger, Module, OnModuleInit } from '@nestjs/common';
import { PreferenceModule } from '../../collections/preferencesdb/preferencedb.module';
import { SysPreferenceService } from '../../collections/preferencesdb/syspreferencedb.service';
import { EarlyConfigModule } from '../early/earlyconfig.module';
import { EarlyJwtConfigService } from '../early/earlyjwt.config.service';
import { PreferenceModule } from '../../collections/preference-db/preference-db.module';
import { SysPreferenceService } from '../../collections/preference-db/sys-preference-db.service';
import { EarlyConfigModule } from '../early/early-config.module';
import { EarlyJwtConfigService } from '../early/early-jwt.config.service';
import { JwtConfigService } from './jwt.config.service';
// This module contains all configservices that depend on the syspref module

View File

@@ -1,15 +1,17 @@
import { Module } from '@nestjs/common';
import { EarlyConfigModule } from '../config/early/earlyconfig.module';
import { MultiPartPipe } from './multipart.pipe';
import { PostFilePipe } from './postfile.pipe';
import { EarlyConfigModule } from '../config/early/early-config.module';
import { ImageIdPipe } from './image-id/image-id.pipe';
import { MultiPartPipe } from './multipart/multipart.pipe';
import { PostFilePipe } from './multipart/postfile.pipe';
@Module({
imports: [EarlyConfigModule],
providers: [MultiPartPipe, PostFilePipe],
providers: [MultiPartPipe, PostFilePipe, ImageIdPipe],
exports: [
MultiPartPipe,
PostFilePipe,
MultiPartPipe,
PostFilePipe,
ImageIdPipe,
// EarlyConfigModule is exported here because the pipes are dependedant on the config
// But these pipes dont resolve their dependencies via this module
// So this way we force it to be "global"

View File

@@ -0,0 +1,10 @@
import {
Param,
PipeTransform,
Type
} from '@nestjs/common';
import { ImageIdPipe } from './image-id.pipe';
export const ImageIdParam = (
...pipes: (PipeTransform<any, any> | Type<PipeTransform<any, any>>)[]
) => Param('id', ImageIdPipe, ...pipes);

View File

@@ -7,7 +7,7 @@ import {
import { UUIDRegex } from 'picsur-shared/dist/util/common-regex';
@Injectable()
export class ImageIdValidator implements PipeTransform<string, string> {
export class ImageIdPipe implements PipeTransform<string, string> {
transform(value: string, metadata: ArgumentMetadata): string {
if (UUIDRegex.test(value)) return value;
throw new BadRequestException('Invalid image id');

View File

@@ -1,4 +1,4 @@
import { InjectRequest } from './injectrequest.decorator';
import { InjectRequest } from './inject-request.decorator';
import { MultiPartPipe } from './multipart.pipe';
import { PostFilePipe } from './postfile.pipe';

View File

@@ -10,11 +10,11 @@ import {
import { FastifyRequest } from 'fastify';
import { MultipartFields, MultipartFile } from 'fastify-multipart';
import { ZodDtoStatic } from 'picsur-shared/dist/util/create-zod-dto';
import { MultipartConfigService } from '../config/early/multipart.config.service';
import { MultipartConfigService } from '../../config/early/multipart.config.service';
import {
CreateMultiPartFieldDto,
CreateMultiPartFileDto
} from '../models/requests/multipart.dto';
} from '../../models/dto/multipart.dto';
@Injectable({ scope: Scope.REQUEST })
export class MultiPartPipe implements PipeTransform {

View File

@@ -7,7 +7,7 @@ import {
} from '@nestjs/common';
import { FastifyRequest } from 'fastify';
import { Multipart } from 'fastify-multipart';
import { MultipartConfigService } from '../config/early/multipart.config.service';
import { MultipartConfigService } from '../../config/early/multipart.config.service';
@Injectable({ scope: Scope.REQUEST })
export class PostFilePipe implements PipeTransform {

View File

@@ -1,7 +1,7 @@
import { SetMetadata, UseGuards } from '@nestjs/common';
import { CombineFCDecorators } from 'picsur-shared/dist/util/decorator';
import { LocalAuthGuard } from '../managers/auth/guards/localauth.guard';
import { Permissions } from '../models/dto/permissions.dto';
import { LocalAuthGuard } from '../managers/auth/guards/local-auth.guard';
import { Permissions } from '../models/constants/permissions.const';
export const RequiredPermissions = (...permissions: Permissions) => {
return SetMetadata('permissions', permissions);

View File

@@ -1,5 +1,5 @@
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
import AuthFasityRequest from '../models/requests/authrequest.dto';
import AuthFasityRequest from '../models/interfaces/authrequest.dto';
export const ReqUser = createParamDecorator(
(input: any, ctx: ExecutionContext) => {

View File

@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { EarlyConfigModule } from '../config/early/earlyconfig.module';
import { EarlyConfigModule } from '../config/early/early-config.module';
import { PicsurLoggerService } from './logger.service';
@Module({

View File

@@ -6,9 +6,9 @@ import {
import fastifyHelmet from 'fastify-helmet';
import * as multipart from 'fastify-multipart';
import { AppModule } from './app.module';
import { UsersService } from './collections/userdb/userdb.service';
import { UsersService } from './collections/user-db/user-db.service';
import { HostConfigService } from './config/early/host.config.service';
import { MainExceptionFilter } from './layers/httpexception/httpexception.filter';
import { MainExceptionFilter } from './layers/exception/exception.filter';
import { SuccessInterceptor } from './layers/success/success.interceptor';
import { ZodValidationPipe } from './layers/validate/zod-validator.pipe';
import { PicsurLoggerService } from './logger/logger.service';

View File

@@ -1,14 +1,14 @@
import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { PreferenceModule } from '../../collections/preferencesdb/preferencedb.module';
import { UsersModule } from '../../collections/userdb/userdb.module';
import { PreferenceModule } from '../../collections/preference-db/preference-db.module';
import { UsersModule } from '../../collections/user-db/user-db.module';
import { JwtConfigService, JwtSecretProvider } from '../../config/late/jwt.config.service';
import { LateConfigModule } from '../../config/late/lateconfig.module';
import { LateConfigModule } from '../../config/late/late-config.module';
import { AuthManagerService } from './auth.service';
import { GuestStrategy } from './guards/guest.strategy';
import { JwtStrategy } from './guards/jwt.strategy';
import { LocalAuthStrategy } from './guards/localauth.strategy';
import { LocalAuthStrategy } from './guards/local-auth.strategy';
import { GuestService } from './guest.service';
@Module({

View File

@@ -3,7 +3,7 @@ import { PassportStrategy } from '@nestjs/passport';
import { Strategy } from 'passport-local';
import { EUser } from 'picsur-shared/dist/entities/user.entity';
import { AsyncFailable, HasFailed } from 'picsur-shared/dist/types';
import { UsersService } from '../../../collections/userdb/userdb.service';
import { UsersService } from '../../../collections/user-db/user-db.service';
import { EUserBackend2EUser } from '../../../models/transformers/user.transformer';
@Injectable()

View File

@@ -9,8 +9,8 @@ import { Reflector } from '@nestjs/core';
import { AuthGuard } from '@nestjs/passport';
import { EUser, EUserSchema } from 'picsur-shared/dist/entities/user.entity';
import { Fail, Failable, HasFailed } from 'picsur-shared/dist/types';
import { UsersService } from '../../../collections/userdb/userdb.service';
import { Permissions } from '../../../models/dto/permissions.dto';
import { UsersService } from '../../../collections/user-db/user-db.service';
import { Permissions } from '../../../models/constants/permissions.const';
import { isPermissionsArray } from '../../../models/validators/permissions.validator';
// This guard extends both the jwt authenticator and the guest authenticator

View File

@@ -1,6 +1,6 @@
import { Injectable } from '@nestjs/common';
import { HasFailed } from 'picsur-shared/dist/types';
import { UsersService } from '../../collections/userdb/userdb.service';
import { UsersService } from '../../collections/user-db/user-db.service';
import { EUserBackend } from '../../models/entities/user.entity';
@Injectable()

View File

@@ -1,9 +1,9 @@
import { Logger, Module, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import { ImageDBModule } from '../../collections/imagedb/imagedb.module';
import { RolesModule } from '../../collections/roledb/roledb.module';
import { EarlyConfigModule } from '../../config/early/earlyconfig.module';
import { ImageDBModule } from '../../collections/image-db/image-db.module';
import { RolesModule } from '../../collections/role-db/role-db.module';
import { EarlyConfigModule } from '../../config/early/early-config.module';
import { HostConfigService } from '../../config/early/host.config.service';
import { DemoManagerService } from './demomanager.service';
import { DemoManagerService } from './demo.service';
@Module({
imports: [ImageDBModule, EarlyConfigModule, RolesModule],

View File

@@ -1,7 +1,7 @@
import { Injectable, Logger } from '@nestjs/common';
import { ImageDBService } from '../../collections/imagedb/imagedb.service';
import { RolesService } from '../../collections/roledb/roledb.service';
import { Permission } from '../../models/dto/permissions.dto';
import { ImageDBService } from '../../collections/image-db/image-db.service';
import { RolesService } from '../../collections/role-db/role-db.service';
import { Permission } from '../../models/constants/permissions.const';
@Injectable()
export class DemoManagerService {

View File

@@ -9,7 +9,7 @@ import {
import { AsyncFailable, Fail } from 'picsur-shared/dist/types';
import { QOIColorSpace, QOIdecode, QOIencode } from 'qoi-img';
import sharp from 'sharp';
import { UsrPreferenceService } from '../../collections/preferencesdb/usrpreferencedb.service';
import { UsrPreferenceService } from '../../collections/preference-db/usr-preference-db.service';
@Injectable()
export class ImageProcessorService {

View File

@@ -0,0 +1,12 @@
import { Module } from '@nestjs/common';
import { ImageDBModule } from '../../collections/image-db/image-db.module';
import { PreferenceModule } from '../../collections/preference-db/preference-db.module';
import { ImageProcessorService } from './image-processor.service';
import { ImageManagerService } from './image.service';
@Module({
imports: [ImageDBModule, PreferenceModule],
providers: [ImageManagerService, ImageProcessorService],
exports: [ImageManagerService],
})
export class ImageManagerModule {}

View File

@@ -4,9 +4,9 @@ import { FullMime } from 'picsur-shared/dist/dto/mimes.dto';
import { AsyncFailable, HasFailed } from 'picsur-shared/dist/types';
import { ParseMime } from 'picsur-shared/dist/util/parse-mime';
import { IsQOI } from 'qoi-img';
import { ImageDBService } from '../../collections/imagedb/imagedb.service';
import { ImageDBService } from '../../collections/image-db/image-db.service';
import { EImageBackend } from '../../models/entities/image.entity';
import { ImageProcessorService } from './imageprocessor.service';
import { ImageProcessorService } from './image-processor.service';
// Right now this service is mostly a wrapper for the imagedbservice.
// But in the future the actual image logic will happend here

View File

@@ -1,12 +0,0 @@
import { Module } from '@nestjs/common';
import { ImageDBModule } from '../../collections/imagedb/imagedb.module';
import { PreferenceModule } from '../../collections/preferencesdb/preferencedb.module';
import { ImageManagerService } from './imagemanager.service';
import { ImageProcessorService } from './imageprocessor.service';
@Module({
imports: [ImageDBModule, PreferenceModule],
providers: [ImageManagerService, ImageProcessorService],
exports: [ImageManagerService],
})
export class ImageManagerModule {}

View File

@@ -1,5 +1,5 @@
import tuple from 'picsur-shared/dist/types/tuple';
import { Permission, Permissions, PermissionsList } from './permissions.dto';
import { Permission, Permissions, PermissionsList } from './permissions.const';
// Config

View File

@@ -1,8 +1,8 @@
import { EImageBackend } from './image.entity';
import { ERoleBackend } from './role.entity';
import { ESysPreferenceBackend } from './syspreference.entity';
import { ESysPreferenceBackend } from './sys-preference.entity';
import { EUserBackend } from './user.entity';
import { EUsrPreferenceBackend } from './usrpreference.entity';
import { EUsrPreferenceBackend } from './usr-preference.entity';
export const EntityList = [
EImageBackend,

View File

@@ -1,6 +1,6 @@
import { ERole } from 'picsur-shared/dist/entities/role.entity';
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
import { Permissions } from '../dto/permissions.dto';
import { Permissions } from '../constants/permissions.const';
@Entity()
export class ERoleBackend implements ERole {

View File

@@ -12,7 +12,7 @@ After that is done it will retry the first function again.
const fallBackMap: Record<string, Promise<unknown>> = {};
export async function FallBackMutex<
export async function MutexFallBack<
MF extends () => Promise<O | null | undefined>,
FF extends () => Promise<unknown>,
O,
@@ -22,7 +22,7 @@ export async function FallBackMutex<
if (fallBackMap[key] !== undefined) {
await fallBackMap[key];
return FallBackMutex(key, mainFunc, fallBackFunc);
return MutexFallBack(key, mainFunc, fallBackFunc);
}
fallBackMap[key] = fallBackFunc();
@@ -33,5 +33,5 @@ export async function FallBackMutex<
.catch(() => {
delete fallBackMap[key];
});
return FallBackMutex(key, mainFunc, fallBackFunc);
return MutexFallBack(key, mainFunc, fallBackFunc);
}

View File

@@ -1,5 +1,5 @@
import { isPermissionsArray as isPArr } from 'picsur-shared/dist/validators/permissions.validator';
import { Permissions, PermissionsList } from '../dto/permissions.dto';
import { Permissions, PermissionsList } from '../constants/permissions.const';
export function isPermissionsArray(value: any): value is Permissions {
return isPArr(value, PermissionsList);

View File

@@ -1,15 +1,10 @@
import {
Controller, Get,
Request
} from '@nestjs/common';
import { Controller, Get, Request } from '@nestjs/common';
import { UserInfoResponse } from 'picsur-shared/dist/dto/api/user-manage.dto';
import { Permission } from 'picsur-shared/dist/dto/permissions.dto';
import { RequiredPermissions } from '../../../decorators/permissions.decorator';
import { ReqUserID } from '../../../decorators/request-user.decorator';
import { Returns } from '../../../decorators/returns.decorator';
import AuthFasityRequest from '../../../models/requests/authrequest.dto';
import AuthFasityRequest from '../../../models/interfaces/authrequest.dto';
@Controller('api/experiment')
@RequiredPermissions(Permission.Settings)
@@ -20,7 +15,6 @@ export class ExperimentController {
@Request() req: AuthFasityRequest,
@ReqUserID() thing: string,
): Promise<UserInfoResponse> {
return req.user;
}
}

View File

@@ -5,6 +5,6 @@ import { ExperimentController } from './experiment.controller';
// TODO: remove when out of beta
@Module({
controllers: [ExperimentController]
controllers: [ExperimentController],
})
export class ExperimentModule {}

View File

@@ -6,7 +6,7 @@ import {
import { HostConfigService } from '../../../config/early/host.config.service';
import { NoPermissions } from '../../../decorators/permissions.decorator';
import { Returns } from '../../../decorators/returns.decorator';
import { PermissionsList } from '../../../models/dto/permissions.dto';
import { PermissionsList } from '../../../models/constants/permissions.const';
@Controller('api/info')
@NoPermissions()

View File

@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { EarlyConfigModule } from '../../../config/early/earlyconfig.module';
import { EarlyConfigModule } from '../../../config/early/early-config.module';
import { InfoController } from './info.controller';
@Module({

View File

@@ -1,7 +1,7 @@
import { Module } from '@nestjs/common';
import { PreferenceModule } from '../../../collections/preferencesdb/preferencedb.module';
import { SysPrefController } from './syspref.controller';
import { UsrPrefController } from './usrpref.controller';
import { PreferenceModule } from '../../../collections/preference-db/preference-db.module';
import { SysPrefController } from './sys-pref.controller';
import { UsrPrefController } from './usr-pref.controller';
@Module({
imports: [PreferenceModule],

View File

@@ -14,10 +14,10 @@ import {
UpdatePreferenceResponse
} from 'picsur-shared/dist/dto/api/pref.dto';
import { HasFailed } from 'picsur-shared/dist/types';
import { SysPreferenceService } from '../../../collections/preferencesdb/syspreferencedb.service';
import { SysPreferenceService } from '../../../collections/preference-db/sys-preference-db.service';
import { RequiredPermissions } from '../../../decorators/permissions.decorator';
import { Returns } from '../../../decorators/returns.decorator';
import { Permission } from '../../../models/dto/permissions.dto';
import { Permission } from '../../../models/constants/permissions.const';
@Controller('api/pref/sys')
@RequiredPermissions(Permission.SysPrefManage)

View File

@@ -14,11 +14,11 @@ import {
UpdatePreferenceResponse
} from 'picsur-shared/dist/dto/api/pref.dto';
import { HasFailed } from 'picsur-shared/dist/types';
import { UsrPreferenceService } from '../../../collections/preferencesdb/usrpreferencedb.service';
import { UsrPreferenceService } from '../../../collections/preference-db/usr-preference-db.service';
import { RequiredPermissions } from '../../../decorators/permissions.decorator';
import { ReqUserID } from '../../../decorators/request-user.decorator';
import { Returns } from '../../../decorators/returns.decorator';
import { Permission } from '../../../models/dto/permissions.dto';
import { Permission } from '../../../models/constants/permissions.const';
@Controller('api/pref/usr')
@RequiredPermissions(Permission.Settings)

View File

@@ -19,17 +19,17 @@ import {
SpecialRolesResponse
} from 'picsur-shared/dist/dto/api/roles.dto';
import { HasFailed } from 'picsur-shared/dist/types';
import { RolesService } from '../../../collections/roledb/roledb.service';
import { UsersService } from '../../../collections/userdb/userdb.service';
import { RolesService } from '../../../collections/role-db/role-db.service';
import { UsersService } from '../../../collections/user-db/user-db.service';
import { RequiredPermissions } from '../../../decorators/permissions.decorator';
import { Returns } from '../../../decorators/returns.decorator';
import { Permission } from '../../../models/dto/permissions.dto';
import { Permission } from '../../../models/constants/permissions.const';
import {
DefaultRolesList,
ImmutableRolesList,
SoulBoundRolesList,
UndeletableRolesList
} from '../../../models/dto/roles.dto';
} from '../../../models/constants/roles.const';
import { isPermissionsArray } from '../../../models/validators/permissions.validator';
@Controller('api/roles')

View File

@@ -1,6 +1,6 @@
import { Module } from '@nestjs/common';
import { RolesModule } from '../../../collections/roledb/roledb.module';
import { UsersModule } from '../../../collections/userdb/userdb.module';
import { RolesModule } from '../../../collections/role-db/role-db.module';
import { UsersModule } from '../../../collections/user-db/user-db.module';
import { RolesController } from './roles.controller';
@Module({

View File

@@ -20,15 +20,15 @@ import {
UserUpdateResponse
} from 'picsur-shared/dist/dto/api/user-manage.dto';
import { HasFailed } from 'picsur-shared/dist/types';
import { UsersService } from '../../../collections/userdb/userdb.service';
import { UsersService } from '../../../collections/user-db/user-db.service';
import { RequiredPermissions } from '../../../decorators/permissions.decorator';
import { Returns } from '../../../decorators/returns.decorator';
import { Permission } from '../../../models/dto/permissions.dto';
import { Permission } from '../../../models/constants/permissions.const';
import {
ImmutableUsersList,
LockedLoginUsersList,
UndeletableUsersList
} from '../../../models/dto/specialusers.dto';
} from '../../../models/constants/special-users.const';
import { EUserBackend2EUser } from '../../../models/transformers/user.transformer';
@Controller('api/user')

View File

@@ -15,7 +15,7 @@ import {
} from 'picsur-shared/dist/dto/api/user.dto';
import { EUser } from 'picsur-shared/dist/entities/user.entity';
import { HasFailed } from 'picsur-shared/dist/types';
import { UsersService } from '../../../collections/userdb/userdb.service';
import { UsersService } from '../../../collections/user-db/user-db.service';
import {
NoPermissions,
RequiredPermissions,
@@ -24,7 +24,7 @@ import {
import { ReqUser, ReqUserID } from '../../../decorators/request-user.decorator';
import { Returns } from '../../../decorators/returns.decorator';
import { AuthManagerService } from '../../../managers/auth/auth.service';
import { Permission } from '../../../models/dto/permissions.dto';
import { Permission } from '../../../models/constants/permissions.const';
import { EUserBackend2EUser } from '../../../models/transformers/user.transformer';
@Controller('api/user')

View File

@@ -1,7 +1,7 @@
import { Module } from '@nestjs/common';
import { AuthManagerModule } from '../../../managers/auth/auth.module';
import { UserManageController } from './user-manage.controller';
import { UserController } from './user.controller';
import { UserManageController } from './usermanage.controller';
@Module({
imports: [AuthManagerModule],

View File

@@ -4,23 +4,21 @@ import {
Head,
InternalServerErrorException,
Logger,
NotFoundException,
Param,
Post,
NotFoundException, Post,
Res
} from '@nestjs/common';
import { FastifyReply } from 'fastify';
import { ImageMetaResponse } from 'picsur-shared/dist/dto/api/image.dto';
import { HasFailed } from 'picsur-shared/dist/types';
import { MultiPart } from '../../decorators/multipart.decorator';
import { ImageIdParam } from '../../decorators/image-id/image-id.decorator';
import { MultiPart } from '../../decorators/multipart/multipart.decorator';
import { RequiredPermissions } from '../../decorators/permissions.decorator';
import { ReqUserID } from '../../decorators/request-user.decorator';
import { Returns } from '../../decorators/returns.decorator';
import { ImageManagerService } from '../../managers/imagemanager/imagemanager.service';
import { Permission } from '../../models/dto/permissions.dto';
import { ImageUploadDto } from '../../models/requests/imageroute.dto';
import { ImageManagerService } from '../../managers/image/image.service';
import { Permission } from '../../models/constants/permissions.const';
import { ImageUploadDto } from '../../models/dto/image-upload.dto';
import { EImageBackend2EImage } from '../../models/transformers/image.transformer';
import { ImageIdValidator } from './imageid.validator';
// This is the only controller with CORS enabled
@Controller('i')
@@ -35,7 +33,7 @@ export class ImageController {
// Usually passthrough is for manually sending the response,
// But we need it here to set the mime type
@Res({ passthrough: true }) res: FastifyReply,
@Param('id', ImageIdValidator) id: string,
@ImageIdParam() id: string,
): Promise<Buffer> {
const image = await this.imagesService.retrieveComplete(id);
if (HasFailed(image)) {
@@ -50,7 +48,7 @@ export class ImageController {
@Head(':id')
async headImage(
@Res({ passthrough: true }) res: FastifyReply,
@Param('id', ImageIdValidator) id: string,
@ImageIdParam() id: string,
) {
const image = await this.imagesService.retrieveInfo(id);
if (HasFailed(image)) {
@@ -64,7 +62,7 @@ export class ImageController {
@Get('meta/:id')
@Returns(ImageMetaResponse)
async getImageMeta(
@Param('id', ImageIdValidator) id: string,
@ImageIdParam() id: string,
): Promise<ImageMetaResponse> {
const image = await this.imagesService.retrieveInfo(id);
if (HasFailed(image)) {

View File

@@ -1,9 +1,8 @@
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import cors from 'cors';
import { DecoratorsModule } from '../../decorators/decorators.module';
import { ImageManagerModule } from '../../managers/imagemanager/imagemanager.module';
import { ImageIdValidator } from './imageid.validator';
import { ImageController } from './imageroute.controller';
import { ImageManagerModule } from '../../managers/image/image.module';
import { ImageController } from './image.controller';
const corsConfig = cors({
// 48 hours
@@ -12,7 +11,6 @@ const corsConfig = cors({
@Module({
imports: [ImageManagerModule, DecoratorsModule],
providers: [ImageIdValidator],
controllers: [ImageController],
})
export class ImageModule implements NestModule {

View File

@@ -1,6 +1,6 @@
import { Module } from '@nestjs/common';
import { PicsurApiModule } from './api/api.module';
import { ImageModule } from './image/imageroute.module';
import { ImageModule } from './image/image.module';
@Module({
imports: [PicsurApiModule, ImageModule],