fix: Add additional model validation (#3725)
This commit is contained in:
@@ -33,6 +33,7 @@ import Team from "./Team";
|
||||
import User from "./User";
|
||||
import ParanoidModel from "./base/ParanoidModel";
|
||||
import Fix from "./decorators/Fix";
|
||||
import NotContainsUrl from "./validators/NotContainsUrl";
|
||||
|
||||
// without this indirection, the app crashes on starup
|
||||
type Sort = CollectionSort;
|
||||
@@ -131,6 +132,7 @@ class Collection extends ParanoidModel {
|
||||
@Column
|
||||
urlId: string;
|
||||
|
||||
@NotContainsUrl
|
||||
@Column
|
||||
name: string;
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ import User from "./User";
|
||||
import View from "./View";
|
||||
import ParanoidModel from "./base/ParanoidModel";
|
||||
import Fix from "./decorators/Fix";
|
||||
import { Length } from "./decorators/Length";
|
||||
import Length from "./validators/Length";
|
||||
|
||||
export type SearchResponse = {
|
||||
results: {
|
||||
|
||||
@@ -16,6 +16,8 @@ import Team from "./Team";
|
||||
import User from "./User";
|
||||
import ParanoidModel from "./base/ParanoidModel";
|
||||
import Fix from "./decorators/Fix";
|
||||
import Length from "./validators/Length";
|
||||
import NotContainsUrl from "./validators/NotContainsUrl";
|
||||
|
||||
@DefaultScope(() => ({
|
||||
include: [
|
||||
@@ -50,6 +52,8 @@ import Fix from "./decorators/Fix";
|
||||
})
|
||||
@Fix
|
||||
class Group extends ParanoidModel {
|
||||
@Length({ min: 0, max: 255, msg: "Must be less than 255 characters" })
|
||||
@NotContainsUrl
|
||||
@Column
|
||||
name: string;
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
BeforeSave,
|
||||
HasMany,
|
||||
Scopes,
|
||||
Length,
|
||||
Is,
|
||||
DataType,
|
||||
} from "sequelize-typescript";
|
||||
@@ -31,6 +30,8 @@ import TeamDomain from "./TeamDomain";
|
||||
import User from "./User";
|
||||
import ParanoidModel from "./base/ParanoidModel";
|
||||
import Fix from "./decorators/Fix";
|
||||
import Length from "./validators/Length";
|
||||
import NotContainsUrl from "./validators/NotContainsUrl";
|
||||
|
||||
const readFile = util.promisify(fs.readFile);
|
||||
|
||||
@@ -50,6 +51,7 @@ const readFile = util.promisify(fs.readFile);
|
||||
@Table({ tableName: "teams", modelName: "team" })
|
||||
@Fix
|
||||
class Team extends ParanoidModel {
|
||||
@NotContainsUrl
|
||||
@Column
|
||||
name: string;
|
||||
|
||||
@@ -74,6 +76,7 @@ class Team extends ParanoidModel {
|
||||
@Column(DataType.UUID)
|
||||
defaultCollectionId: string | null;
|
||||
|
||||
@Length({ min: 0, max: 255, msg: "Must be less than 255 characters" })
|
||||
@Column
|
||||
avatarUrl: string | null;
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import Team from "./Team";
|
||||
import User from "./User";
|
||||
import IdModel from "./base/IdModel";
|
||||
import Fix from "./decorators/Fix";
|
||||
import Length from "./validators/Length";
|
||||
|
||||
@Table({ tableName: "team_domains", modelName: "team_domain" })
|
||||
@Fix
|
||||
@@ -20,6 +21,7 @@ class TeamDomain extends IdModel {
|
||||
msg: "You chose a restricted domain, please try another.",
|
||||
})
|
||||
@NotEmpty
|
||||
@Length({ min: 0, max: 255, msg: "Must be less than 255 characters" })
|
||||
@Column
|
||||
name: string;
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ import Encrypted, {
|
||||
getEncryptedColumn,
|
||||
} from "./decorators/Encrypted";
|
||||
import Fix from "./decorators/Fix";
|
||||
import Length from "./validators/Length";
|
||||
import NotContainsUrl from "./validators/NotContainsUrl";
|
||||
|
||||
/**
|
||||
* Flags that are available for setting on the user.
|
||||
@@ -86,12 +88,17 @@ export enum UserFlag {
|
||||
@Fix
|
||||
class User extends ParanoidModel {
|
||||
@IsEmail
|
||||
@Length({ min: 0, max: 255, msg: "Must be less than 255 characters" })
|
||||
@Column
|
||||
email: string | null;
|
||||
|
||||
@NotContainsUrl
|
||||
@Length({ min: 0, max: 255, msg: "Must be less than 255 characters" })
|
||||
@Column
|
||||
username: string | null;
|
||||
|
||||
@NotContainsUrl
|
||||
@Length({ min: 0, max: 255, msg: "Must be less than 255 characters" })
|
||||
@Column
|
||||
name: string;
|
||||
|
||||
@@ -141,6 +148,7 @@ class User extends ParanoidModel {
|
||||
@Column
|
||||
language: string;
|
||||
|
||||
@Length({ min: 0, max: 255, msg: "Must be less than 255 characters" })
|
||||
@Column(DataType.STRING)
|
||||
get avatarUrl() {
|
||||
const original = this.getDataValue("avatarUrl");
|
||||
|
||||
@@ -13,6 +13,7 @@ import Team from "./Team";
|
||||
import User from "./User";
|
||||
import ParanoidModel from "./base/ParanoidModel";
|
||||
import Fix from "./decorators/Fix";
|
||||
import Length from "./validators/Length";
|
||||
|
||||
@Table({
|
||||
tableName: "webhook_subscriptions",
|
||||
@@ -21,11 +22,13 @@ import Fix from "./decorators/Fix";
|
||||
@Fix
|
||||
class WebhookSubscription extends ParanoidModel {
|
||||
@NotEmpty
|
||||
@Length({ min: 0, max: 255, msg: "Must be less than 255 characters" })
|
||||
@Column
|
||||
name: string;
|
||||
|
||||
@IsUrl
|
||||
@NotEmpty
|
||||
@Length({ min: 0, max: 255, msg: "Must be less than 255 characters" })
|
||||
@Column
|
||||
url: string;
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@ import { size } from "lodash";
|
||||
import { addAttributeOptions } from "sequelize-typescript";
|
||||
|
||||
/**
|
||||
* A decorator that calculates size of the string based on lodash's size function.
|
||||
* particularly useful for strings with unicode characters of variable lengths.
|
||||
* A decorator that validates the size of a string based on lodash's size.
|
||||
* function. Useful for strings with unicode characters of variable lengths.
|
||||
*/
|
||||
export function Length({
|
||||
export default function Length({
|
||||
msg,
|
||||
min,
|
||||
max,
|
||||
16
server/models/validators/NotContainsUrl.ts
Normal file
16
server/models/validators/NotContainsUrl.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { addAttributeOptions } from "sequelize-typescript";
|
||||
|
||||
/**
|
||||
* A decorator that validates that a string does not include something that
|
||||
* looks like a URL.
|
||||
*/
|
||||
export default function NotContainsUrl(target: any, propertyName: string) {
|
||||
return addAttributeOptions(target, propertyName, {
|
||||
validate: {
|
||||
not: {
|
||||
args: /(www|file:|http:|https:)+[^\s]+[\w]/,
|
||||
msg: "Must not contain a URL",
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user