some validation on entities' properties

This commit is contained in:
2020-10-14 09:05:31 +03:00
committed by Stepan Usatiuk
parent e792fc6adc
commit 0dbf4b020e
5 changed files with 88 additions and 2 deletions

26
package-lock.json generated
View File

@@ -500,6 +500,11 @@
"@types/superagent": "*"
}
},
"@types/validator": {
"version": "13.0.0",
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.0.0.tgz",
"integrity": "sha512-WAy5txG7aFX8Vw3sloEKp5p/t/Xt8jD3GRD9DacnFv6Vo8ubudAsRTXgxpQwU0mpzY/H8U4db3roDuCMjShBmw=="
},
"@typescript-eslint/eslint-plugin": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.4.0.tgz",
@@ -1149,6 +1154,17 @@
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
"integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="
},
"class-validator": {
"version": "0.12.2",
"resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.12.2.tgz",
"integrity": "sha512-TDzPzp8BmpsbPhQpccB3jMUE/3pK0TyqamrK0kcx+ZeFytMA+O6q87JZZGObHHnoo9GM8vl/JppIyKWeEA/EVw==",
"requires": {
"@types/validator": "13.0.0",
"google-libphonenumber": "^3.2.8",
"tslib": ">=1.9.0",
"validator": "13.0.0"
}
},
"clean-stack": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
@@ -2466,6 +2482,11 @@
}
}
},
"google-libphonenumber": {
"version": "3.2.13",
"resolved": "https://registry.npmjs.org/google-libphonenumber/-/google-libphonenumber-3.2.13.tgz",
"integrity": "sha512-USnpjJkD8St+wyshy154lF74JeauNCd8vrcusSlWjSFWitXzl7ZSuCunA/XxeVLqBv6DShrSfFMYdwGZ7x4hOw=="
},
"graceful-fs": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
@@ -5467,6 +5488,11 @@
"spdx-expression-parse": "^3.0.0"
}
},
"validator": {
"version": "13.0.0",
"resolved": "https://registry.npmjs.org/validator/-/validator-13.0.0.tgz",
"integrity": "sha512-anYx5fURbgF04lQV18nEQWZ/3wHGnxiKdG4aL8J+jEDsm98n/sU/bey+tYk6tnGJzm7ioh5FoqrAiQ6m03IgaA=="
},
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",

View File

@@ -28,6 +28,7 @@
"@typescript-eslint/parser": "^4.4.0",
"bcrypt": "^5.0.0",
"chai": "^4.2.0",
"class-validator": "^0.12.2",
"concurrently": "^5.3.0",
"cross-env": "^7.0.2",
"deasync": "^0.1.20",

View File

@@ -6,7 +6,9 @@ import { constants as fsConstants } from "fs";
import {
AfterRemove,
BaseEntity,
BeforeInsert,
BeforeRemove,
BeforeUpdate,
Column,
Entity,
Index,
@@ -14,6 +16,15 @@ import {
PrimaryGeneratedColumn,
} from "typeorm";
import { User } from "./User";
import {
isAlphanumeric,
IsAlphanumeric,
IsHash,
IsMimeType,
Length,
Matches,
validateOrReject,
} from "class-validator";
export interface IPhotoJSON {
id: number;
@@ -32,14 +43,16 @@ export class Photo extends BaseEntity {
@Column({ length: 190 })
@Index()
@IsHash("md5")
public hash: string;
@Column({ length: 190 })
@Index()
@IsAlphanumeric()
@Matches(/\d*x\d*/)
public size: string;
@Column({ length: 190 })
@Index()
@IsMimeType()
public format: string;
@Column({ type: "timestamp", default: null })
@@ -61,6 +74,16 @@ export class Photo extends BaseEntity {
return path.join(this.user.getDataPath(), this.getFileName());
}
@BeforeInsert()
async beforeInsertValidate(): Promise<void> {
return validateOrReject(this);
}
@BeforeUpdate()
async beforeUpdateValidate(): Promise<void> {
return validateOrReject(this);
}
@BeforeRemove()
async cleanupFiles(): Promise<void> {
try {

View File

@@ -8,6 +8,7 @@ import {
BaseEntity,
BeforeInsert,
BeforeRemove,
BeforeUpdate,
Column,
Entity,
Index,
@@ -16,6 +17,14 @@ import {
} from "typeorm";
import { config } from "../config";
import { Photo } from "./Photo";
import {
IsAlphanumeric,
IsBase32,
IsBase64,
IsEmail,
IsHash,
validateOrReject,
} from "class-validator";
export type IUserJSON = Pick<User, "id" | "username">;
@@ -35,10 +44,12 @@ export class User extends BaseEntity {
@Column({ length: 190 })
@Index({ unique: true })
@IsAlphanumeric()
public username: string;
@Column({ length: 190 })
@Index({ unique: true })
@IsEmail()
public email: string;
@Column({ length: 190 })
@@ -75,6 +86,16 @@ export class User extends BaseEntity {
await fs.rmdir(this.getDataPath(), { recursive: true });
}
@BeforeInsert()
async beforeInsertValidate(): Promise<void> {
return validateOrReject(this);
}
@BeforeUpdate()
async beforeUpdateValidate(): Promise<void> {
return validateOrReject(this);
}
public toJSON(): IUserJSON {
const { id, username } = this;
return { id, username };

View File

@@ -222,6 +222,21 @@ describe("photos", function () {
.expect(404);
});
it("should not create a photo with weird properties", async function () {
const response = await request(callback)
.post("/photos/new")
.set({
Authorization: `Bearer ${seed.user1.toJWT()}`,
"Content-Type": "application/json",
})
.send({
hash: "../test",
size: "33333",
format: dogFormat,
} as IPhotosNewPostBody)
.expect(400);
});
/*
it("should update a photo", async function () {
const response = await request(callback)