Everything is validated now

This commit is contained in:
2022-08-25 15:13:44 +02:00
parent 23ba777e5a
commit 9170f8f7aa
14 changed files with 627 additions and 118 deletions

View File

@@ -1,2 +1,3 @@
export * as Requests from './requests';
export * as Responses from './responses';
export { validateSync, validateAsync, validateAsyncInline } from './utils';

View File

@@ -1,14 +1,36 @@
import { BaseRequest } from './base';
import { IsEmail, IsNotEmpty } from 'class-validator';
import {
IsBoolean,
IsEmail,
IsNotEmpty,
IsOptional,
IsString
} from 'class-validator';
export class AuthSignUpRequest extends BaseRequest {
export class SignUpRequest extends BaseRequest {
@IsEmail()
username: string;
@IsNotEmpty()
@IsString()
password: string;
}
export class AuthLoginRequest extends AuthSignUpRequest {
export class LoginRequest extends SignUpRequest {
@IsOptional()
@IsNotEmpty()
@IsString()
otp?: string;
}
export class TfaComplete extends BaseRequest {
@IsNotEmpty()
@IsString()
code: string;
}
export class TfaSetup extends BaseRequest {
@IsNotEmpty()
@IsBoolean()
mail: boolean;
}

View File

@@ -1,7 +1,5 @@
import { BaseRequest } from './base';
import { IsInt, IsNotEmpty, Min } from 'class-validator';
export type CreateFileRequest = CreateFolderRequest;
import { IsInt, IsNotEmpty, IsString, Min } from 'class-validator';
export class CreateFolderRequest extends BaseRequest {
@IsInt()
@@ -9,6 +7,7 @@ export class CreateFolderRequest extends BaseRequest {
parent: number;
@IsNotEmpty()
@IsString()
name: string;
}
@@ -17,3 +16,5 @@ export class DeleteRequest extends BaseRequest {
@Min(1)
node: number;
}
export class CreateFileRequest extends CreateFolderRequest {}

View File

@@ -1,20 +1,27 @@
import { SuccessResponse } from './base';
import { IsBase32, IsJWT, IsNotEmpty } from 'class-validator';
import { ValidateConstructor } from '../utils';
export type TfaRequiredResponse = SuccessResponse;
export type RemoveTfaResponse = SuccessResponse;
export type RequestEmailTfaResponse = SuccessResponse;
export type TfaCompletedResponse = SuccessResponse;
export type SignupResponse = SuccessResponse;
export type RefreshResponse = LoginResponse;
@ValidateConstructor
export class LoginResponse extends SuccessResponse {
constructor(jwt: string) {
super();
this.jwt = jwt;
}
@IsNotEmpty()
@IsJWT()
jwt: string;
}
@ValidateConstructor
export class RequestTotpTfaResponse extends SuccessResponse {
constructor(qrCode: string, secret: string) {
super();
this.qrCode = qrCode;
this.secret = secret;
}
@IsNotEmpty()
qrCode: string;
@@ -22,3 +29,10 @@ export class RequestTotpTfaResponse extends SuccessResponse {
@IsBase32()
secret: string;
}
export class TfaRequiredResponse extends SuccessResponse {}
export class RemoveTfaResponse extends SuccessResponse {}
export class RequestEmailTfaResponse extends SuccessResponse {}
export class TfaCompletedResponse extends SuccessResponse {}
export class SignupResponse extends SuccessResponse {}
export class RefreshResponse extends LoginResponse {}

View File

@@ -1,17 +1,39 @@
import { SuccessResponse } from './base';
import { IsBoolean, IsInt, IsNotEmpty, Min } from 'class-validator';
export type UploadFileResponse = SuccessResponse;
export type DeleteResponse = SuccessResponse;
export type CreateFileResponse = CreateFolderResponse;
import {
IsBoolean,
IsInt,
IsNotEmpty,
IsOptional,
IsString,
Min
} from 'class-validator';
import { ValidateConstructor } from '../utils';
@ValidateConstructor
export class GetRootResponse extends SuccessResponse {
constructor(rootId: number) {
super();
this.rootId = rootId;
}
@IsInt()
@Min(1)
rootId: number;
}
export class GetNodeResponse extends SuccessResponse {
constructor(
id: number,
name: string,
isFile: boolean,
parent: number | null
) {
super();
this.id = id;
this.name = name;
this.isFile = isFile;
this.parent = parent;
}
@IsInt()
@Min(1)
id: number;
@@ -22,22 +44,46 @@ export class GetNodeResponse extends SuccessResponse {
@IsBoolean()
isFile: boolean;
@IsOptional()
@IsInt()
@Min(1)
parent: number | null;
@IsOptional()
@IsInt({ each: true })
@Min(1, { each: true })
children?: number[];
@IsOptional()
@IsInt()
@Min(0)
size?: number;
}
@ValidateConstructor
export class GetPathResponse extends SuccessResponse {
constructor(path: string) {
super();
this.path = path;
}
@IsNotEmpty()
@IsString()
path: string;
}
@ValidateConstructor
export class CreateFolderResponse extends SuccessResponse {
constructor(id: number) {
super();
this.id = id;
}
@IsInt()
@Min(1)
id: number;
}
export class UploadFileResponse extends SuccessResponse {}
export class DeleteResponse extends SuccessResponse {}
export class CreateFileResponse extends CreateFolderResponse {}

35
dto/src/utils.ts Normal file
View File

@@ -0,0 +1,35 @@
import { validate, validateSync as _validateSync } from 'class-validator';
export function validateSync<T extends object>(data: T): void {
const errors = _validateSync(data);
if (errors.length > 0) {
console.error('Validation failed, errors: ', errors);
throw new Error('Validation failed');
}
}
export async function validateAsync<T extends object>(data: T): Promise<void> {
const errors = await validate(data);
if (errors.length > 0) {
console.error('Validation failed, errors: ', errors);
throw new Error('Validation failed');
}
}
export async function validateAsyncInline<T extends object>(
data: T
): Promise<T> {
await validateAsync(data);
return data;
}
export function ValidateConstructor<T extends { new (...args: any[]): any }>(
constr: T
) {
return class extends constr {
constructor(...args: any[]) {
super(...args);
validateSync(this);
}
};
}