mirror of
https://github.com/usatiuk/photos.git
synced 2025-10-28 15:27:49 +01:00
some validation on entities' properties
This commit is contained in:
26
package-lock.json
generated
26
package-lock.json
generated
@@ -500,6 +500,11 @@
|
|||||||
"@types/superagent": "*"
|
"@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": {
|
"@typescript-eslint/eslint-plugin": {
|
||||||
"version": "4.4.0",
|
"version": "4.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.4.0.tgz",
|
"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",
|
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
|
||||||
"integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="
|
"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": {
|
"clean-stack": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
|
"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": {
|
"graceful-fs": {
|
||||||
"version": "4.2.4",
|
"version": "4.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
|
||||||
@@ -5467,6 +5488,11 @@
|
|||||||
"spdx-expression-parse": "^3.0.0"
|
"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": {
|
"vary": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
"@typescript-eslint/parser": "^4.4.0",
|
"@typescript-eslint/parser": "^4.4.0",
|
||||||
"bcrypt": "^5.0.0",
|
"bcrypt": "^5.0.0",
|
||||||
"chai": "^4.2.0",
|
"chai": "^4.2.0",
|
||||||
|
"class-validator": "^0.12.2",
|
||||||
"concurrently": "^5.3.0",
|
"concurrently": "^5.3.0",
|
||||||
"cross-env": "^7.0.2",
|
"cross-env": "^7.0.2",
|
||||||
"deasync": "^0.1.20",
|
"deasync": "^0.1.20",
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ import { constants as fsConstants } from "fs";
|
|||||||
import {
|
import {
|
||||||
AfterRemove,
|
AfterRemove,
|
||||||
BaseEntity,
|
BaseEntity,
|
||||||
|
BeforeInsert,
|
||||||
BeforeRemove,
|
BeforeRemove,
|
||||||
|
BeforeUpdate,
|
||||||
Column,
|
Column,
|
||||||
Entity,
|
Entity,
|
||||||
Index,
|
Index,
|
||||||
@@ -14,6 +16,15 @@ import {
|
|||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
} from "typeorm";
|
} from "typeorm";
|
||||||
import { User } from "./User";
|
import { User } from "./User";
|
||||||
|
import {
|
||||||
|
isAlphanumeric,
|
||||||
|
IsAlphanumeric,
|
||||||
|
IsHash,
|
||||||
|
IsMimeType,
|
||||||
|
Length,
|
||||||
|
Matches,
|
||||||
|
validateOrReject,
|
||||||
|
} from "class-validator";
|
||||||
|
|
||||||
export interface IPhotoJSON {
|
export interface IPhotoJSON {
|
||||||
id: number;
|
id: number;
|
||||||
@@ -32,14 +43,16 @@ export class Photo extends BaseEntity {
|
|||||||
|
|
||||||
@Column({ length: 190 })
|
@Column({ length: 190 })
|
||||||
@Index()
|
@Index()
|
||||||
|
@IsHash("md5")
|
||||||
public hash: string;
|
public hash: string;
|
||||||
|
|
||||||
@Column({ length: 190 })
|
@Column({ length: 190 })
|
||||||
@Index()
|
@IsAlphanumeric()
|
||||||
|
@Matches(/\d*x\d*/)
|
||||||
public size: string;
|
public size: string;
|
||||||
|
|
||||||
@Column({ length: 190 })
|
@Column({ length: 190 })
|
||||||
@Index()
|
@IsMimeType()
|
||||||
public format: string;
|
public format: string;
|
||||||
|
|
||||||
@Column({ type: "timestamp", default: null })
|
@Column({ type: "timestamp", default: null })
|
||||||
@@ -61,6 +74,16 @@ export class Photo extends BaseEntity {
|
|||||||
return path.join(this.user.getDataPath(), this.getFileName());
|
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()
|
@BeforeRemove()
|
||||||
async cleanupFiles(): Promise<void> {
|
async cleanupFiles(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
BaseEntity,
|
BaseEntity,
|
||||||
BeforeInsert,
|
BeforeInsert,
|
||||||
BeforeRemove,
|
BeforeRemove,
|
||||||
|
BeforeUpdate,
|
||||||
Column,
|
Column,
|
||||||
Entity,
|
Entity,
|
||||||
Index,
|
Index,
|
||||||
@@ -16,6 +17,14 @@ import {
|
|||||||
} from "typeorm";
|
} from "typeorm";
|
||||||
import { config } from "../config";
|
import { config } from "../config";
|
||||||
import { Photo } from "./Photo";
|
import { Photo } from "./Photo";
|
||||||
|
import {
|
||||||
|
IsAlphanumeric,
|
||||||
|
IsBase32,
|
||||||
|
IsBase64,
|
||||||
|
IsEmail,
|
||||||
|
IsHash,
|
||||||
|
validateOrReject,
|
||||||
|
} from "class-validator";
|
||||||
|
|
||||||
export type IUserJSON = Pick<User, "id" | "username">;
|
export type IUserJSON = Pick<User, "id" | "username">;
|
||||||
|
|
||||||
@@ -35,10 +44,12 @@ export class User extends BaseEntity {
|
|||||||
|
|
||||||
@Column({ length: 190 })
|
@Column({ length: 190 })
|
||||||
@Index({ unique: true })
|
@Index({ unique: true })
|
||||||
|
@IsAlphanumeric()
|
||||||
public username: string;
|
public username: string;
|
||||||
|
|
||||||
@Column({ length: 190 })
|
@Column({ length: 190 })
|
||||||
@Index({ unique: true })
|
@Index({ unique: true })
|
||||||
|
@IsEmail()
|
||||||
public email: string;
|
public email: string;
|
||||||
|
|
||||||
@Column({ length: 190 })
|
@Column({ length: 190 })
|
||||||
@@ -75,6 +86,16 @@ export class User extends BaseEntity {
|
|||||||
await fs.rmdir(this.getDataPath(), { recursive: true });
|
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 {
|
public toJSON(): IUserJSON {
|
||||||
const { id, username } = this;
|
const { id, username } = this;
|
||||||
return { id, username };
|
return { id, username };
|
||||||
|
|||||||
@@ -222,6 +222,21 @@ describe("photos", function () {
|
|||||||
.expect(404);
|
.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 () {
|
it("should update a photo", async function () {
|
||||||
const response = await request(callback)
|
const response = await request(callback)
|
||||||
|
|||||||
Reference in New Issue
Block a user