diff --git a/backend/src/decorators/permissions.decorator.ts b/backend/src/decorators/permissions.decorator.ts index 177ef97..d5a9f68 100644 --- a/backend/src/decorators/permissions.decorator.ts +++ b/backend/src/decorators/permissions.decorator.ts @@ -1,5 +1,5 @@ import { SetMetadata, UseGuards } from '@nestjs/common'; -import { CombineDecorators } from 'picsur-shared/dist/util/decorator'; +import { CombineFCDecorators } from 'picsur-shared/dist/util/decorator'; import { LocalAuthGuard } from '../managers/auth/guards/localauth.guard'; import { Permissions } from '../models/dto/permissions.dto'; @@ -11,7 +11,7 @@ export const RequiredPermissions = (...permissions: Permissions) => { export const NoPermissions = () => RequiredPermissions(); export const UseLocalAuth = (...permissions: Permissions) => - CombineDecorators( + CombineFCDecorators( RequiredPermissions(...permissions), UseGuards(LocalAuthGuard), ); diff --git a/shared/src/dto/syspreferences.dto.ts b/shared/src/dto/syspreferences.dto.ts index 52811c3..168b832 100644 --- a/shared/src/dto/syspreferences.dto.ts +++ b/shared/src/dto/syspreferences.dto.ts @@ -1,3 +1,4 @@ +// This enum is only here to make accessing the values easier, and type checking in the backend export enum SysPreference { JwtSecret = 'jwt_secret', JwtExpiresIn = 'jwt_expires_in', diff --git a/shared/src/entities/image.entity.ts b/shared/src/entities/image.entity.ts index 15504d7..e53cc22 100644 --- a/shared/src/entities/image.entity.ts +++ b/shared/src/entities/image.entity.ts @@ -11,9 +11,8 @@ export class EImage { // Binary data @IsOptional() - @Exclude() + @Exclude() // Dont send this by default data?: object; - @IsNotEmpty() @IsString() diff --git a/shared/src/entities/role.entity.ts b/shared/src/entities/role.entity.ts index 97f757c..88d9ba9 100644 --- a/shared/src/entities/role.entity.ts +++ b/shared/src/entities/role.entity.ts @@ -3,6 +3,9 @@ import { EntityID } from '../validators/entity-id.validator'; import { IsRoleName } from '../validators/role.validators'; import { IsStringList } from '../validators/string-list.validator'; +// This entity is build from multiple smaller enitities +// Theses smaller entities are used in other places + export class RoleNameObject { @IsRoleName() name: string; diff --git a/shared/src/entities/user.entity.ts b/shared/src/entities/user.entity.ts index fe177e5..33b9a48 100644 --- a/shared/src/entities/user.entity.ts +++ b/shared/src/entities/user.entity.ts @@ -4,6 +4,9 @@ import { EntityID } from '../validators/entity-id.validator'; import { IsStringList } from '../validators/string-list.validator'; import { IsPlainTextPwd, IsUsername } from '../validators/user.validators'; +// This entity is build from multiple smaller enitities +// Theses smaller entities are used in other places + export class UsernameUser { @IsUsername() username: string; diff --git a/shared/src/types/failable.ts b/shared/src/types/failable.ts index 43291ce..f1f78d4 100644 --- a/shared/src/types/failable.ts +++ b/shared/src/types/failable.ts @@ -1,3 +1,8 @@ +// This is a simple wrapper for failures +// It makes it a lot more pleasant to work with errors +// Since now they dont just come out of nowhere +// -> Side effects go brrr + export class Failure { constructor(private readonly reason?: string) {} diff --git a/shared/src/types/index.ts b/shared/src/types/index.ts index f1cf155..4afc322 100644 --- a/shared/src/types/index.ts +++ b/shared/src/types/index.ts @@ -1,2 +1,3 @@ export * from './failable'; export * from './newable'; +export * from './tuple'; diff --git a/shared/src/types/newable.ts b/shared/src/types/newable.ts index 8755c6e..f58c241 100644 --- a/shared/src/types/newable.ts +++ b/shared/src/types/newable.ts @@ -1 +1,3 @@ +// Any thing that can come after 'new' + export type Newable = { new (...args: any[]): T }; diff --git a/shared/src/types/tuple.ts b/shared/src/types/tuple.ts index 0432787..ab152c8 100644 --- a/shared/src/types/tuple.ts +++ b/shared/src/types/tuple.ts @@ -1,3 +1,5 @@ +// Easily create a tuple with appropriate types + const tuple = (...args: T): T => args; export default tuple; diff --git a/shared/src/util/decorator.ts b/shared/src/util/decorator.ts index 148472d..e2836b2 100644 --- a/shared/src/util/decorator.ts +++ b/shared/src/util/decorator.ts @@ -1,9 +1,17 @@ type FCDecorator = MethodDecorator & ClassDecorator; -export function CombineDecorators(...decorators: FCDecorator[]) { +export function CombineFCDecorators(...decorators: FCDecorator[]) { return (target: any, key: string, descriptor: PropertyDescriptor) => { decorators.forEach(decorator => { decorator(target, key, descriptor); }); } } + +export const CombinePDecorators = (...decorators: PropertyDecorator[]): () => PropertyDecorator => { + return () => { + return (target: Object, propertyKey: string | symbol): void => { + decorators.forEach((decorator) => decorator(target, propertyKey)); + }; + } +}; diff --git a/shared/src/util/random.ts b/shared/src/util/random.ts index 8d39e7d..c6ffc21 100644 --- a/shared/src/util/random.ts +++ b/shared/src/util/random.ts @@ -6,6 +6,7 @@ const randomCharacters = export function generateRandomString(length: number): string { let out = ''; for (let i = 0; i < length; i++) { + // Yes this is done synchronously, but it's not a big deal out += randomCharacters[crypto.randomInt(0, randomCharacters.length - 1)]; } return out; diff --git a/shared/src/util/validate.ts b/shared/src/util/validate.ts index 88db690..1cbc3a6 100644 --- a/shared/src/util/validate.ts +++ b/shared/src/util/validate.ts @@ -1,5 +1,8 @@ import { validate } from 'class-validator'; +// For some stupid reason, the class-validator library does not have a way to set global defaults +// So now we have to do it this way + export const ValidateOptions = { disableErrorMessages: true, forbidNonWhitelisted: true, diff --git a/shared/src/validators/compose.validator.ts b/shared/src/validators/compose.validator.ts deleted file mode 100644 index b0bb0a2..0000000 --- a/shared/src/validators/compose.validator.ts +++ /dev/null @@ -1,10 +0,0 @@ - -export const ComposeValidators = (...validators: PropertyDecorator[]): () => PropertyDecorator => { - return () => { - const decorators = [...validators]; - - return (target: Object, propertyKey: string | symbol): void => { - decorators.forEach((decorator) => decorator(target, propertyKey)); - }; - } -}; diff --git a/shared/src/validators/entity-id.validator.ts b/shared/src/validators/entity-id.validator.ts index c22cd25..eed04ae 100644 --- a/shared/src/validators/entity-id.validator.ts +++ b/shared/src/validators/entity-id.validator.ts @@ -1,5 +1,5 @@ import { IsInt, IsNotEmpty, IsOptional, Min } from 'class-validator'; -import { ComposeValidators } from './compose.validator'; +import { CombinePDecorators } from '../util/decorator'; -export const EntityID = ComposeValidators(IsOptional(), IsInt(), Min(0)); -export const EntityIDRequired = ComposeValidators(IsNotEmpty(), IsInt(), Min(0)); +export const EntityID = CombinePDecorators(IsOptional(), IsInt(), Min(0)); +export const EntityIDRequired = CombinePDecorators(IsNotEmpty(), IsInt(), Min(0)); diff --git a/shared/src/validators/positive-int.validator.ts b/shared/src/validators/positive-int.validator.ts index 2601cbf..05b4cc5 100644 --- a/shared/src/validators/positive-int.validator.ts +++ b/shared/src/validators/positive-int.validator.ts @@ -1,4 +1,4 @@ import { IsDefined, IsInt, Min } from 'class-validator'; -import { ComposeValidators } from './compose.validator'; +import { CombinePDecorators } from '../util/decorator'; -export const IsPosInt = ComposeValidators(IsInt(), Min(0), IsDefined()); +export const IsPosInt = CombinePDecorators(IsInt(), Min(0), IsDefined()); diff --git a/shared/src/validators/role.validators.ts b/shared/src/validators/role.validators.ts index 556c288..02b4332 100644 --- a/shared/src/validators/role.validators.ts +++ b/shared/src/validators/role.validators.ts @@ -1,7 +1,7 @@ import { IsAlphanumeric, IsNotEmpty, IsString, Length } from 'class-validator'; -import { ComposeValidators } from './compose.validator'; +import { CombinePDecorators } from '../util/decorator'; -export const IsRoleName = ComposeValidators( +export const IsRoleName = CombinePDecorators( IsNotEmpty(), IsString(), Length(4, 32), diff --git a/shared/src/validators/string-list.validator.ts b/shared/src/validators/string-list.validator.ts index 478f691..132b4d7 100644 --- a/shared/src/validators/string-list.validator.ts +++ b/shared/src/validators/string-list.validator.ts @@ -3,9 +3,9 @@ import { IsNotEmpty, IsString } from 'class-validator'; -import { ComposeValidators } from './compose.validator'; +import { CombinePDecorators } from '../util/decorator'; -export const IsStringList = ComposeValidators( +export const IsStringList = CombinePDecorators( IsArray(), IsString({ each: true }), IsNotEmpty({ each: true }), diff --git a/shared/src/validators/user.validators.ts b/shared/src/validators/user.validators.ts index df6d8b8..d833cf9 100644 --- a/shared/src/validators/user.validators.ts +++ b/shared/src/validators/user.validators.ts @@ -1,17 +1,17 @@ import { IsAlphanumeric, IsNotEmpty, IsString, Length } from 'class-validator'; -import { ComposeValidators } from './compose.validator'; +import { CombinePDecorators } from '../util/decorator'; // Match this with user validators in frontend // (Frontend is not security focused, but it tells the user what is wrong) -export const IsUsername = ComposeValidators( +export const IsUsername = CombinePDecorators( IsNotEmpty(), IsString(), Length(4, 32), IsAlphanumeric(), ); -export const IsPlainTextPwd = ComposeValidators( +export const IsPlainTextPwd = CombinePDecorators( IsNotEmpty(), IsString(), Length(4, 1024),