diff --git a/.vscode/launch.json b/.vscode/launch.json index d0ac923e28..28b058e424 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -196,6 +196,7 @@ "MAIL_URL": "", // "DB_NS": "account-2", // "WS_LIVENESS_DAYS": "1", + // "WORKSPACE_LIMIT_PER_USER": "1", "MINIO_ACCESS_KEY": "minioadmin", "MINIO_SECRET_KEY": "minioadmin", "MINIO_ENDPOINT": "localhost" diff --git a/server/account/src/__tests__/postgres.test.ts b/server/account/src/__tests__/postgres.test.ts index 1512038290..837d5e795f 100644 --- a/server/account/src/__tests__/postgres.test.ts +++ b/server/account/src/__tests__/postgres.test.ts @@ -335,6 +335,7 @@ describe('AccountPostgresDbCollection', () => { a.timezone, a.locale, a.automatic, + a.max_workspaces, p.hash, p.salt FROM global_account.account as a diff --git a/server/account/src/collections/postgres.ts b/server/account/src/collections/postgres.ts index 9c3bd29750..9320c565ea 100644 --- a/server/account/src/collections/postgres.ts +++ b/server/account/src/collections/postgres.ts @@ -371,6 +371,7 @@ export class AccountPostgresDbCollection a.timezone, a.locale, a.automatic, + a.max_workspaces, p.hash, p.salt FROM ${this.getTableName()} as a @@ -851,7 +852,8 @@ export class PostgresAccountDB implements AccountDB { this.getV4Migration1(), this.getV5Migration(), this.getV6Migration(), - this.getV7Migration() + this.getV7Migration(), + this.getV8Migration() ] } @@ -1145,4 +1147,14 @@ export class PostgresAccountDB implements AccountDB { ` ] } + + private getV8Migration (): [string, string] { + return [ + 'account_db_v8_add_account_max_workspaces', + ` + ALTER TABLE ${this.ns}.account + ADD COLUMN IF NOT EXISTS max_workspaces SMALLINT; + ` + ] + } } diff --git a/server/account/src/operations.ts b/server/account/src/operations.ts index fe287987c5..2a2726f9a6 100644 --- a/server/account/src/operations.ts +++ b/server/account/src/operations.ts @@ -379,11 +379,15 @@ export async function createWorkspace ( throw new PlatformError(new Status(Severity.ERROR, platform.status.InternalServerError, {})) } + const accountObj = await db.account.findOne({ uuid: account }) + if (accountObj == null) { + throw new PlatformError(new Status(Severity.ERROR, platform.status.InternalServerError, {})) + } + // Get a list of created workspaces const created = (await db.workspace.find({ createdBy: socialId.personUuid })).length - // TODO: Add support for per person limit increase - if (created >= workspaceLimitPerUser) { + if (created >= (accountObj.maxWorkspaces ?? workspaceLimitPerUser)) { ctx.warn('created-by-limit', { person: socialId.key, workspace: workspaceName }) throw new PlatformError( new Status(Severity.ERROR, platform.status.WorkspaceLimitReached, { workspace: workspaceName }) diff --git a/server/account/src/types.ts b/server/account/src/types.ts index 979db634f5..485f03d198 100644 --- a/server/account/src/types.ts +++ b/server/account/src/types.ts @@ -58,6 +58,7 @@ export interface Account { locale?: string hash?: Buffer | null salt?: Buffer | null + maxWorkspaces?: number } // TODO: type data with generic type