import {ApiError} from 'app/common/ApiError'; import {Role} from 'app/common/roles'; import {DocumentProperties, documentPropertyKeys, NEW_DOCUMENT_CODE} from "app/common/UserAPI"; import {nativeValues} from 'app/gen-server/lib/values'; import {Column, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryColumn} from "typeorm"; import {AclRuleDoc} from "./AclRule"; import {Alias} from "./Alias"; import {Resource} from "./Resource"; import {Workspace} from "./Workspace"; // Acceptable ids for use in document urls. const urlIdRegex = /^[-a-z0-9]+$/i; function isValidUrlId(urlId: string) { if (urlId === NEW_DOCUMENT_CODE) { return false; } return urlIdRegex.exec(urlId); } @Entity({name: 'docs'}) export class Document extends Resource { @PrimaryColumn() public id: string; @ManyToOne(type => Workspace) @JoinColumn({name: 'workspace_id'}) public workspace: Workspace; @OneToMany(type => AclRuleDoc, aclRule => aclRule.document) public aclRules: AclRuleDoc[]; // Indicates whether the doc is pinned to the org it lives in. @Column({name: 'is_pinned', default: false}) public isPinned: boolean; // Property that may be returned when the doc is fetched to indicate the access the // fetching user has on the doc, i.e. 'owners', 'editors', 'viewers' public access: Role|null; // a computed column with permissions. // {insert: false} makes sure typeorm doesn't try to put values into such // a column when creating documents. @Column({name: 'permissions', type: 'text', select: false, insert: false, update: false}) public permissions?: any; @Column({name: 'url_id', type: 'text', nullable: true}) public urlId: string|null; @Column({name: 'removed_at', type: nativeValues.dateTimeType, nullable: true}) public removedAt: Date|null; @OneToMany(type => Alias, alias => alias.doc) public aliases: Alias[]; public checkProperties(props: any): props is Partial { return super.checkProperties(props, documentPropertyKeys); } public updateFromProperties(props: Partial) { super.updateFromProperties(props); if (props.isPinned !== undefined) { this.isPinned = props.isPinned; } if (props.urlId !== undefined) { if (props.urlId !== null && !isValidUrlId(props.urlId)) { throw new ApiError('invalid urlId', 400); } this.urlId = props.urlId; } } }