relocate validator composer

This commit is contained in:
rubikscraft
2022-03-27 22:48:10 +02:00
parent ac98db10df
commit 904ba2ee4b
18 changed files with 45 additions and 27 deletions

View File

@@ -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),
);

View File

@@ -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',

View File

@@ -11,9 +11,8 @@ export class EImage {
// Binary data
@IsOptional()
@Exclude()
@Exclude() // Dont send this by default
data?: object;
@IsNotEmpty()
@IsString()

View File

@@ -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;

View File

@@ -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;

View File

@@ -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) {}

View File

@@ -1,2 +1,3 @@
export * from './failable';
export * from './newable';
export * from './tuple';

View File

@@ -1 +1,3 @@
// Any thing that can come after 'new'
export type Newable<T> = { new (...args: any[]): T };

View File

@@ -1,3 +1,5 @@
// Easily create a tuple with appropriate types
const tuple = <T extends string[]>(...args: T): T => args;
export default tuple;

View File

@@ -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));
};
}
};

View File

@@ -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;

View File

@@ -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,

View File

@@ -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));
};
}
};

View File

@@ -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));

View File

@@ -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());

View File

@@ -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),

View File

@@ -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 }),

View File

@@ -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),