From ac07724f2117df96cb1e8898c7836fe09cb996b0 Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Sun, 5 Jun 2022 00:59:41 -0700 Subject: [PATCH] chore: Synchronizing refactor and small fixes from enterprise codebase (#3634) * chore: Syncronizing refactor and small fixes from enterprise codebase * fix --- app/components/Input.tsx | 10 +++++- server/commands/teamPermanentDeleter.ts | 4 +-- server/models/Attachment.ts | 27 ++------------- server/models/Backlink.ts | 4 +-- server/models/CollectionGroup.ts | 4 +-- server/models/CollectionUser.ts | 4 +-- server/models/Event.ts | 4 +-- server/models/FileOperation.ts | 4 +-- server/models/Group.ts | 1 - server/models/GroupUser.ts | 4 +-- server/models/Integration.ts | 4 +-- server/models/IntegrationAuthentication.ts | 4 +-- server/models/Pin.ts | 4 +-- server/models/Revision.ts | 4 +-- server/models/Share.ts | 4 +-- server/models/Star.ts | 4 +-- server/models/TeamDomain.ts | 4 +-- server/models/User.ts | 21 +----------- server/models/UserAuthentication.ts | 4 +-- server/models/View.ts | 4 +-- server/models/base/BaseModel.ts | 40 +++++++++++----------- server/models/base/IdModel.ts | 26 ++++++++++++++ server/models/base/ParanoidModel.ts | 4 +-- server/routes/api/collections.ts | 1 + 24 files changed, 93 insertions(+), 101 deletions(-) create mode 100644 server/models/base/IdModel.ts diff --git a/app/components/Input.tsx b/app/components/Input.tsx index c73c8b133..014b097e4 100644 --- a/app/components/Input.tsx +++ b/app/components/Input.tsx @@ -38,6 +38,13 @@ const RealInput = styled.input<{ hasIcon?: boolean }>` color: ${(props) => props.theme.placeholder}; } + &:-webkit-autofill, + &:-webkit-autofill:hover, + &:-webkit-autofill:focus { + -webkit-box-shadow: 0 0 0px 1000px ${(props) => props.theme.background} + inset; + } + &::-webkit-search-cancel-button { -webkit-appearance: none; } @@ -97,7 +104,7 @@ export const LabelText = styled.div` display: inline-block; `; -export type Props = React.HTMLAttributes & { +export type Props = Omit, "onChange"> & { type?: "text" | "email" | "checkbox" | "search" | "textarea"; value?: string; label?: string; @@ -108,6 +115,7 @@ export type Props = React.HTMLAttributes & { margin?: string | number; icon?: React.ReactNode; name?: string; + pattern?: string; minLength?: number; maxLength?: number; autoFocus?: boolean; diff --git a/server/commands/teamPermanentDeleter.ts b/server/commands/teamPermanentDeleter.ts index c6edc34e5..be99053a7 100644 --- a/server/commands/teamPermanentDeleter.ts +++ b/server/commands/teamPermanentDeleter.ts @@ -37,7 +37,7 @@ async function teamPermanentDeleter(team: Team) { try { transaction = await sequelize.transaction(); - await Attachment.findAllInBatches( + await Attachment.findAllInBatches( { where: { teamId, @@ -62,7 +62,7 @@ async function teamPermanentDeleter(team: Team) { } ); // Destroy user-relation models - await User.findAllInBatches( + await User.findAllInBatches( { attributes: ["id"], where: { diff --git a/server/models/Attachment.ts b/server/models/Attachment.ts index 54b23a9c7..f9cc96d32 100644 --- a/server/models/Attachment.ts +++ b/server/models/Attachment.ts @@ -1,5 +1,4 @@ import path from "path"; -import { FindOptions } from "sequelize"; import { BeforeDestroy, BelongsTo, @@ -14,12 +13,12 @@ import { publicS3Endpoint, deleteFromS3, getFileByKey } from "@server/utils/s3"; import Document from "./Document"; import Team from "./Team"; import User from "./User"; -import BaseModel from "./base/BaseModel"; +import IdModel from "./base/IdModel"; import Fix from "./decorators/Fix"; @Table({ tableName: "attachments", modelName: "attachment" }) @Fix -class Attachment extends BaseModel { +class Attachment extends IdModel { @Column key: string; @@ -92,28 +91,6 @@ class Attachment extends BaseModel { @ForeignKey(() => User) @Column(DataType.UUID) userId: string; - - static async findAllInBatches( - query: FindOptions, - callback: ( - attachments: Array, - query: FindOptions - ) => Promise - ) { - if (!query.offset) { - query.offset = 0; - } - if (!query.limit) { - query.limit = 10; - } - let results; - - do { - results = await this.findAll(query); - await callback(results, query); - query.offset += query.limit; - } while (results.length >= query.limit); - } } export default Attachment; diff --git a/server/models/Backlink.ts b/server/models/Backlink.ts index 3e2a06b45..833f53607 100644 --- a/server/models/Backlink.ts +++ b/server/models/Backlink.ts @@ -7,12 +7,12 @@ import { } from "sequelize-typescript"; import Document from "./Document"; import User from "./User"; -import BaseModel from "./base/BaseModel"; +import IdModel from "./base/IdModel"; import Fix from "./decorators/Fix"; @Table({ tableName: "backlinks", modelName: "backlink" }) @Fix -class Backlink extends BaseModel { +class Backlink extends IdModel { @BelongsTo(() => User, "userId") user: User; diff --git a/server/models/CollectionGroup.ts b/server/models/CollectionGroup.ts index d2c32d48a..b6edc1dba 100644 --- a/server/models/CollectionGroup.ts +++ b/server/models/CollectionGroup.ts @@ -4,18 +4,18 @@ import { Default, ForeignKey, IsIn, - Model, Table, DataType, } from "sequelize-typescript"; import Collection from "./Collection"; import Group from "./Group"; import User from "./User"; +import BaseModel from "./base/BaseModel"; import Fix from "./decorators/Fix"; @Table({ tableName: "collection_groups", modelName: "collection_group" }) @Fix -class CollectionGroup extends Model { +class CollectionGroup extends BaseModel { @Default("read_write") @IsIn([["read", "read_write", "maintainer"]]) @Column diff --git a/server/models/CollectionUser.ts b/server/models/CollectionUser.ts index 711a5c514..b3a7b0dd8 100644 --- a/server/models/CollectionUser.ts +++ b/server/models/CollectionUser.ts @@ -6,15 +6,15 @@ import { IsIn, Table, DataType, - Model, } from "sequelize-typescript"; import Collection from "./Collection"; import User from "./User"; +import BaseModel from "./base/BaseModel"; import Fix from "./decorators/Fix"; @Table({ tableName: "collection_users", modelName: "collection_user" }) @Fix -class CollectionUser extends Model { +class CollectionUser extends BaseModel { @Default("read_write") @IsIn([["read", "read_write", "maintainer"]]) @Column diff --git a/server/models/Event.ts b/server/models/Event.ts index 63a308534..904b6945f 100644 --- a/server/models/Event.ts +++ b/server/models/Event.ts @@ -15,12 +15,12 @@ import Collection from "./Collection"; import Document from "./Document"; import Team from "./Team"; import User from "./User"; -import BaseModel from "./base/BaseModel"; +import IdModel from "./base/IdModel"; import Fix from "./decorators/Fix"; @Table({ tableName: "events", modelName: "event" }) @Fix -class Event extends BaseModel { +class Event extends IdModel { @IsUUID(4) @Column(DataType.UUID) modelId: string; diff --git a/server/models/FileOperation.ts b/server/models/FileOperation.ts index 918671db1..672c13621 100644 --- a/server/models/FileOperation.ts +++ b/server/models/FileOperation.ts @@ -11,7 +11,7 @@ import { deleteFromS3, getFileByKey } from "@server/utils/s3"; import Collection from "./Collection"; import Team from "./Team"; import User from "./User"; -import BaseModel from "./base/BaseModel"; +import IdModel from "./base/IdModel"; import Fix from "./decorators/Fix"; export enum FileOperationType { @@ -48,7 +48,7 @@ export enum FileOperationState { })) @Table({ tableName: "file_operations", modelName: "file_operation" }) @Fix -class FileOperation extends BaseModel { +class FileOperation extends IdModel { @Column(DataType.ENUM("import", "export")) type: FileOperationType; diff --git a/server/models/Group.ts b/server/models/Group.ts index 1ed0a791f..182b93f9d 100644 --- a/server/models/Group.ts +++ b/server/models/Group.ts @@ -24,7 +24,6 @@ import Fix from "./decorators/Fix"; required: false, }, ], - order: [["name", "ASC"]], })) @Table({ tableName: "groups", diff --git a/server/models/GroupUser.ts b/server/models/GroupUser.ts index 8723e8795..34f1898f3 100644 --- a/server/models/GroupUser.ts +++ b/server/models/GroupUser.ts @@ -5,10 +5,10 @@ import { Column, Table, DataType, - Model, } from "sequelize-typescript"; import Group from "./Group"; import User from "./User"; +import BaseModel from "./base/BaseModel"; import Fix from "./decorators/Fix"; @DefaultScope(() => ({ @@ -20,7 +20,7 @@ import Fix from "./decorators/Fix"; })) @Table({ tableName: "group_users", modelName: "group_user", paranoid: true }) @Fix -class GroupUser extends Model { +class GroupUser extends BaseModel { @BelongsTo(() => User, "userId") user: User; diff --git a/server/models/Integration.ts b/server/models/Integration.ts index f7d7566ce..a63ea391a 100644 --- a/server/models/Integration.ts +++ b/server/models/Integration.ts @@ -10,7 +10,7 @@ import Collection from "./Collection"; import IntegrationAuthentication from "./IntegrationAuthentication"; import Team from "./Team"; import User from "./User"; -import BaseModel from "./base/BaseModel"; +import IdModel from "./base/IdModel"; import Fix from "./decorators/Fix"; @Scopes(() => ({ @@ -26,7 +26,7 @@ import Fix from "./decorators/Fix"; })) @Table({ tableName: "integrations", modelName: "integration" }) @Fix -class Integration extends BaseModel { +class Integration extends IdModel { @Column type: string; diff --git a/server/models/IntegrationAuthentication.ts b/server/models/IntegrationAuthentication.ts index 005744ca2..18aee1ea2 100644 --- a/server/models/IntegrationAuthentication.ts +++ b/server/models/IntegrationAuthentication.ts @@ -7,7 +7,7 @@ import { } from "sequelize-typescript"; import Team from "./Team"; import User from "./User"; -import BaseModel from "./base/BaseModel"; +import IdModel from "./base/IdModel"; import Encrypted, { getEncryptedColumn, setEncryptedColumn, @@ -16,7 +16,7 @@ import Fix from "./decorators/Fix"; @Table({ tableName: "authentications", modelName: "authentication" }) @Fix -class IntegrationAuthentication extends BaseModel { +class IntegrationAuthentication extends IdModel { @Column service: string; diff --git a/server/models/Pin.ts b/server/models/Pin.ts index 1730ab8be..80f2c0309 100644 --- a/server/models/Pin.ts +++ b/server/models/Pin.ts @@ -9,12 +9,12 @@ import Collection from "./Collection"; import Document from "./Document"; import Team from "./Team"; import User from "./User"; -import BaseModel from "./base/BaseModel"; +import IdModel from "./base/IdModel"; import Fix from "./decorators/Fix"; @Table({ tableName: "pins", modelName: "pin" }) @Fix -class Pin extends BaseModel { +class Pin extends IdModel { @Column index: string | null; diff --git a/server/models/Revision.ts b/server/models/Revision.ts index 09fb485e8..475b016e2 100644 --- a/server/models/Revision.ts +++ b/server/models/Revision.ts @@ -10,7 +10,7 @@ import { import MarkdownSerializer from "slate-md-serializer"; import Document from "./Document"; import User from "./User"; -import BaseModel from "./base/BaseModel"; +import IdModel from "./base/IdModel"; import Fix from "./decorators/Fix"; const serializer = new MarkdownSerializer(); @@ -26,7 +26,7 @@ const serializer = new MarkdownSerializer(); })) @Table({ tableName: "revisions", modelName: "revision" }) @Fix -class Revision extends BaseModel { +class Revision extends IdModel { @Column(DataType.SMALLINT) version: number; diff --git a/server/models/Share.ts b/server/models/Share.ts index 4f765955b..ad8941a3d 100644 --- a/server/models/Share.ts +++ b/server/models/Share.ts @@ -11,7 +11,7 @@ import Collection from "./Collection"; import Document from "./Document"; import Team from "./Team"; import User from "./User"; -import BaseModel from "./base/BaseModel"; +import IdModel from "./base/IdModel"; import Fix from "./decorators/Fix"; @DefaultScope(() => ({ @@ -66,7 +66,7 @@ import Fix from "./decorators/Fix"; })) @Table({ tableName: "shares", modelName: "share" }) @Fix -class Share extends BaseModel { +class Share extends IdModel { @Column published: boolean; diff --git a/server/models/Star.ts b/server/models/Star.ts index 07f9449f3..55ffe5a54 100644 --- a/server/models/Star.ts +++ b/server/models/Star.ts @@ -8,12 +8,12 @@ import { import Collection from "./Collection"; import Document from "./Document"; import User from "./User"; -import BaseModel from "./base/BaseModel"; +import IdModel from "./base/IdModel"; import Fix from "./decorators/Fix"; @Table({ tableName: "stars", modelName: "star" }) @Fix -class Star extends BaseModel { +class Star extends IdModel { @Column index: string | null; diff --git a/server/models/TeamDomain.ts b/server/models/TeamDomain.ts index 24668d2ec..f316ca7b8 100644 --- a/server/models/TeamDomain.ts +++ b/server/models/TeamDomain.ts @@ -7,12 +7,12 @@ import { } from "sequelize-typescript"; import Team from "./Team"; import User from "./User"; -import BaseModel from "./base/BaseModel"; +import IdModel from "./base/IdModel"; import Fix from "./decorators/Fix"; @Table({ tableName: "team_domains", modelName: "team_domain" }) @Fix -class TeamDomain extends BaseModel { +class TeamDomain extends IdModel { @NotEmpty @Column name: string; diff --git a/server/models/User.ts b/server/models/User.ts index 027529b71..8dc9eeeef 100644 --- a/server/models/User.ts +++ b/server/models/User.ts @@ -1,7 +1,7 @@ import crypto from "crypto"; import { addMinutes, subMinutes } from "date-fns"; import JWT from "jsonwebtoken"; -import { Transaction, QueryTypes, FindOptions, Op } from "sequelize"; +import { Transaction, QueryTypes, Op } from "sequelize"; import { Table, Column, @@ -536,25 +536,6 @@ class User extends ParanoidModel { suspended: parseInt(counts.suspendedCount), }; }; - - static async findAllInBatches( - query: FindOptions, - callback: (users: Array, query: FindOptions) => Promise - ) { - if (!query.offset) { - query.offset = 0; - } - if (!query.limit) { - query.limit = 10; - } - let results; - - do { - results = await this.findAll(query); - await callback(results, query); - query.offset += query.limit; - } while (results.length >= query.limit); - } } export default User; diff --git a/server/models/UserAuthentication.ts b/server/models/UserAuthentication.ts index 8e080e3a9..06211eaa8 100644 --- a/server/models/UserAuthentication.ts +++ b/server/models/UserAuthentication.ts @@ -8,7 +8,7 @@ import { } from "sequelize-typescript"; import AuthenticationProvider from "./AuthenticationProvider"; import User from "./User"; -import BaseModel from "./base/BaseModel"; +import IdModel from "./base/IdModel"; import Encrypted, { getEncryptedColumn, setEncryptedColumn, @@ -17,7 +17,7 @@ import Fix from "./decorators/Fix"; @Table({ tableName: "user_authentications", modelName: "user_authentication" }) @Fix -class UserAuthentication extends BaseModel { +class UserAuthentication extends IdModel { @Column(DataType.ARRAY(DataType.STRING)) scopes: string[]; diff --git a/server/models/View.ts b/server/models/View.ts index e95f03cac..c9acb37ad 100644 --- a/server/models/View.ts +++ b/server/models/View.ts @@ -11,12 +11,12 @@ import { import { USER_PRESENCE_INTERVAL } from "@shared/constants"; import Document from "./Document"; import User from "./User"; -import BaseModel from "./base/BaseModel"; +import IdModel from "./base/IdModel"; import Fix from "./decorators/Fix"; @Table({ tableName: "views", modelName: "view" }) @Fix -class View extends BaseModel { +class View extends IdModel { @Column lastEditingAt: Date | null; diff --git a/server/models/base/BaseModel.ts b/server/models/base/BaseModel.ts index 444a79d1f..0b436536a 100644 --- a/server/models/base/BaseModel.ts +++ b/server/models/base/BaseModel.ts @@ -1,26 +1,26 @@ -import { - CreatedAt, - UpdatedAt, - Column, - PrimaryKey, - IsUUID, - DataType, - Model, - Default, -} from "sequelize-typescript"; +import { FindOptions } from "sequelize"; +import { Model } from "sequelize-typescript"; class BaseModel extends Model { - @IsUUID(4) - @PrimaryKey - @Default(DataType.UUIDV4) - @Column(DataType.UUID) - id: string; + static async findAllInBatches( + query: FindOptions, + callback: (results: Array, query: FindOptions) => Promise + ) { + if (!query.offset) { + query.offset = 0; + } + if (!query.limit) { + query.limit = 10; + } + let results; - @CreatedAt - createdAt: Date; - - @UpdatedAt - updatedAt: Date; + do { + // @ts-expect-error this T + results = await this.findAll(query); + await callback(results, query); + query.offset += query.limit; + } while (results.length >= query.limit); + } } export default BaseModel; diff --git a/server/models/base/IdModel.ts b/server/models/base/IdModel.ts new file mode 100644 index 000000000..799760054 --- /dev/null +++ b/server/models/base/IdModel.ts @@ -0,0 +1,26 @@ +import { + CreatedAt, + UpdatedAt, + Column, + PrimaryKey, + IsUUID, + DataType, + Default, +} from "sequelize-typescript"; +import BaseModel from "./BaseModel"; + +class IdModel extends BaseModel { + @IsUUID(4) + @PrimaryKey + @Default(DataType.UUIDV4) + @Column(DataType.UUID) + id: string; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; +} + +export default IdModel; diff --git a/server/models/base/ParanoidModel.ts b/server/models/base/ParanoidModel.ts index 94b46eb97..335240c35 100644 --- a/server/models/base/ParanoidModel.ts +++ b/server/models/base/ParanoidModel.ts @@ -1,7 +1,7 @@ import { DeletedAt } from "sequelize-typescript"; -import BaseModel from "./BaseModel"; +import IdModel from "./IdModel"; -class ParanoidModel extends BaseModel { +class ParanoidModel extends IdModel { @DeletedAt deletedAt: Date | null; } diff --git a/server/routes/api/collections.ts b/server/routes/api/collections.ts index b4688355b..ff59bc8b2 100644 --- a/server/routes/api/collections.ts +++ b/server/routes/api/collections.ts @@ -642,6 +642,7 @@ router.post("collections.update", auth(), async (ctx) => { if (privacyChanged || sharingChanged) { await collection.reload(); const team = await Team.findByPk(user.teamId); + invariant(team, "team not found"); if ( collection.permission === null &&