From 1a4ed15c38a31f49eea69872f6ddefc353279040 Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Wed, 26 Aug 2026 12:09:43 +0100 Subject: [PATCH] fix: small refactor --- .../public/locales/en-US/translation.json | 17 +- .../src/ee/ai/components/mcp-settings.tsx | 210 +++++------------- .../src/ee/api-key/pages/user-api-keys.tsx | 2 +- apps/client/src/ee/features.ts | 1 + .../src/ee/oauth/pages/oauth-consent.tsx | 4 +- .../workspace/types/workspace.types.ts | 8 +- apps/server/src/common/features.ts | 1 + .../workspace/dto/update-workspace.dto.ts | 28 +-- .../workspace/services/workspace.service.ts | 55 ++--- .../src/core/workspace/workspace.util.spec.ts | 49 ---- .../src/core/workspace/workspace.util.ts | 34 --- .../migrations/20260825T022612-oauth.ts | 8 - .../repos/workspace/workspace.repo.ts | 1 - apps/server/src/database/types/db.d.ts | 1 - apps/server/src/ee | 2 +- 15 files changed, 107 insertions(+), 314 deletions(-) delete mode 100644 apps/server/src/core/workspace/workspace.util.spec.ts diff --git a/apps/client/public/locales/en-US/translation.json b/apps/client/public/locales/en-US/translation.json index a5bf72589..298340db4 100644 --- a/apps/client/public/locales/en-US/translation.json +++ b/apps/client/public/locales/en-US/translation.json @@ -707,7 +707,10 @@ "Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "Enable the MCP server to allow AI assistants and tools to interact with your workspace content.", "MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.", "MCP Server URL": "MCP Server URL", - "Connect with your Docmost account via OAuth when your client supports it, or use an API key from your account settings.": "Connect with your Docmost account via OAuth when your client supports it, or use an API key from your account settings.", + "Connect AI assistants with your Docmost account via OAuth.": "Connect AI assistants with your Docmost account via OAuth.", + "Require OAuth": "Require OAuth", + "AI assistants must connect with a Docmost account via OAuth. API keys cannot be used with the MCP server.": "AI assistants must connect with a Docmost account via OAuth. API keys cannot be used with the MCP server.", + "Toggle require OAuth for MCP": "Toggle require OAuth for MCP", "Supported tools": "Supported tools", "MCP server URL:": "MCP server URL:", "Learn more": "Learn more", @@ -1318,20 +1321,14 @@ "Revoke access for {{name}}": "Revoke access for {{name}}", "Are you sure you want to revoke access for {{name}}? The application will no longer be able to access your account.": "Are you sure you want to revoke access for {{name}}? The application will no longer be able to access your account.", "Something went wrong. Please try again.": "Something went wrong. Please try again.", - "Trusted applications": "Trusted applications", "Remove {{name}}": "Remove {{name}}", - "This origin is already trusted.": "This origin is already trusted.", - "Trusted application name": "Trusted application name", - "Trusted application origin": "Trusted application origin", - "I recognize this application and want to continue": "I recognize this application and want to continue", + "I trust this application and want to continue": "I trust this application and want to continue", "You will be redirected to": "You will be redirected to", "View content without making changes.": "View content without making changes.", "Create and modify content.": "Create and modify content.", - "This application is not on your workspace's trusted list. Authorize only if you recognize it.": "This application is not on your workspace's trusted list. Authorize only if you recognize it.", - "Applications with these callback origins are trusted. Members will not see a warning when authorizing them.": "Applications with these callback origins are trusted. Members will not see a warning when authorizing them.", - "Enter the app's callback origin, e.g. https://app.yourcompany.com": "Enter the app's callback origin, e.g. https://app.yourcompany.com", + "Make sure you trust this application before authorizing it.": "Make sure you trust this application before authorizing it.", "Applications and AI assistants you have authorized to access your account.": "Applications and AI assistants you have authorized to access your account.", - "Your workspace has MCP enabled. Connect AI assistants with your Docmost account, or with an API key.": "Your workspace has MCP enabled. Connect AI assistants with your Docmost account, or with an API key.", + "Your workspace has MCP enabled. Connect AI assistants with your Docmost account via OAuth.": "Your workspace has MCP enabled. Connect AI assistants with your Docmost account via OAuth.", "Authorized apps": "Authorized apps", "No authorized apps yet.": "No authorized apps yet.", "Workspace knowledge only": "Workspace knowledge only", diff --git a/apps/client/src/ee/ai/components/mcp-settings.tsx b/apps/client/src/ee/ai/components/mcp-settings.tsx index 102da44e3..eeb7ad47e 100644 --- a/apps/client/src/ee/ai/components/mcp-settings.tsx +++ b/apps/client/src/ee/ai/components/mcp-settings.tsx @@ -1,9 +1,8 @@ import { Anchor, - Button, + Badge, Group, List, - Table, Text, Switch, TextInput, @@ -17,33 +16,14 @@ import { workspaceAtom } from "@/features/user/atoms/current-user-atom.ts"; import React, { useState } from "react"; import { Trans, useTranslation } from "react-i18next"; import { updateWorkspace } from "@/features/workspace/services/workspace-service.ts"; -import { ITrustedOAuthClient } from "@/features/workspace/types/workspace.types.ts"; import { notifications } from "@mantine/notifications"; import { useHasFeature } from "@/ee/hooks/use-feature"; import { Feature } from "@/ee/features"; import { useUpgradeLabel } from "@/ee/hooks/use-upgrade-label"; import { getAppUrl } from "@/lib/config.ts"; -import { - IconCheck, - IconCopy, - IconInfoCircle, - IconTrash, -} from "@tabler/icons-react"; +import { IconCheck, IconCopy, IconInfoCircle } from "@tabler/icons-react"; import { CopyButton } from "@/components/common/copy-button.tsx"; -// Mirrors the server rule: an exact https origin, tolerating only a trailing slash. -function parseTrustedOrigin(value: string): string | null { - const input = value.trim().toLowerCase(); - try { - const url = new URL(input); - if (url.protocol !== "https:") return null; - if (input !== url.origin && input !== `${url.origin}/`) return null; - return url.origin; - } catch { - return null; - } -} - export default function McpSettings() { const { t } = useTranslation(); const [workspace, setWorkspace] = useAtom(workspaceAtom); @@ -51,14 +31,7 @@ export default function McpSettings() { const hasAccess = useHasFeature(Feature.MCP); const upgradeLabel = useUpgradeLabel(); - const [newClientName, setNewClientName] = useState(""); - const [newClientOrigin, setNewClientOrigin] = useState(""); - const mcpUrl = `${getAppUrl()}/mcp`; - const storedTrustedClients = workspace?.trustedOauthClients; - const trustedClients = Array.isArray(storedTrustedClients) - ? storedTrustedClients - : []; const handleChange = async (event: React.ChangeEvent) => { const value = event.currentTarget.checked; @@ -74,51 +47,6 @@ export default function McpSettings() { } }; - const saveTrustedClients = async (next: ITrustedOAuthClient[]) => { - try { - const updatedWorkspace = await updateWorkspace({ - trustedOauthClients: next, - }); - setWorkspace(updatedWorkspace); - return true; - } catch (err) { - notifications.show({ - message: err?.response?.data?.message, - color: "red", - }); - return false; - } - }; - - const handleAddTrustedClient = async () => { - const name = newClientName.trim(); - const origin = parseTrustedOrigin(newClientOrigin); - if (!origin) { - notifications.show({ - message: t("Enter the app's callback origin, e.g. https://app.yourcompany.com"), - color: "red", - }); - return; - } - if (trustedClients.some((client) => client.origin.toLowerCase() === origin)) { - notifications.show({ - message: t("This origin is already trusted."), - color: "red", - }); - return; - } - if (await saveTrustedClients([...trustedClients, { origin, name }])) { - setNewClientName(""); - setNewClientOrigin(""); - } - }; - - const handleRemoveTrustedClient = (origin: string) => { - void saveTrustedClients( - trustedClients.filter((client) => client.origin !== origin), - ); - }; - return ( {!hasAccess && ( @@ -180,11 +108,11 @@ export default function McpSettings() { - {t( - "Connect with your Docmost account via OAuth when your client supports it, or use an API key from your account settings.", - )} + {t("Connect AI assistants with your Docmost account via OAuth.")} + +
{t("Supported tools")} @@ -222,83 +150,61 @@ export default function McpSettings() {
- -
- - {t("Trusted applications")} - - - {t( - "Applications with these callback origins are trusted. Members will not see a warning when authorizing them.", - )} - - - {trustedClients.length > 0 && ( - - - {trustedClients.map((client) => ( - - - - {client.name} - - - - - {client.origin} - - - - - handleRemoveTrustedClient(client.origin) - } - > - - - - - ))} - -
- )} - - - - setNewClientName(event.currentTarget.value) - } - placeholder={t("Name")} - aria-label={t("Trusted application name")} - maxLength={64} - style={{ flex: 1 }} - /> - - setNewClientOrigin(event.currentTarget.value) - } - placeholder="https://app.yourcompany.com" - aria-label={t("Trusted application origin")} - style={{ flex: 2 }} - /> - - -
)}
); } + +function McpOauthOnlySetting() { + const { t } = useTranslation(); + const [workspace, setWorkspace] = useAtom(workspaceAtom); + const [checked, setChecked] = useState(workspace?.settings?.ai?.mcpOauthOnly); + const hasAccess = useHasFeature(Feature.MCP_CONTROLS); + const upgradeLabel = useUpgradeLabel(); + + const handleChange = async (event: React.ChangeEvent) => { + const value = event.currentTarget.checked; + try { + const updatedWorkspace = await updateWorkspace({ mcpOauthOnly: value }); + setChecked(value); + setWorkspace(updatedWorkspace); + } catch (err) { + notifications.show({ + message: err?.response?.data?.message, + color: "red", + }); + } + }; + + return ( + +
+ + + {t("Require OAuth")} + + {!hasAccess && ( + + {t("Enterprise")} + + )} + + + {t( + "AI assistants must connect with a Docmost account via OAuth. API keys cannot be used with the MCP server.", + )} + +
+ + + + +
+ ); +} diff --git a/apps/client/src/ee/api-key/pages/user-api-keys.tsx b/apps/client/src/ee/api-key/pages/user-api-keys.tsx index 941bdf7c2..7bec5995a 100644 --- a/apps/client/src/ee/api-key/pages/user-api-keys.tsx +++ b/apps/client/src/ee/api-key/pages/user-api-keys.tsx @@ -74,7 +74,7 @@ export default function UserApiKeys() { }> {t( - "Your workspace has MCP enabled. Connect AI assistants with your Docmost account, or with an API key.", + "Your workspace has MCP enabled. Connect AI assistants with your Docmost account via OAuth.", )}{" "} {t( - "This application is not on your workspace's trusted list. Authorize only if you recognize it.", + "Make sure you trust this application before authorizing it.", )} setAcknowledged(event.currentTarget.checked) } - label={t("I recognize this application and want to continue")} + label={t("I trust this application and want to continue")} /> diff --git a/apps/client/src/features/workspace/types/workspace.types.ts b/apps/client/src/features/workspace/types/workspace.types.ts index 6903d5cd4..1722370ef 100644 --- a/apps/client/src/features/workspace/types/workspace.types.ts +++ b/apps/client/src/features/workspace/types/workspace.types.ts @@ -27,13 +27,13 @@ export interface IWorkspace { mcpEnabled?: boolean; aiChatReadOnly?: boolean; aiChatWorkspaceKnowledgeOnly?: boolean; + mcpOauthOnly?: boolean; trashRetentionDays?: number; restrictApiToAdmins?: boolean; allowMemberTemplates?: boolean; allowPersonalSpaces?: boolean; defaultPageEditMode?: string; isScimEnabled?: boolean; - trustedOauthClients?: ITrustedOAuthClient[]; } export interface IWorkspaceSettings { @@ -45,11 +45,6 @@ export interface IWorkspaceSettings { defaultPageEditMode?: string; } -export interface ITrustedOAuthClient { - origin: string; - name: string; -} - export interface IWorkspaceApiSettings { restrictToAdmins?: boolean; } @@ -58,6 +53,7 @@ export interface IWorkspaceAiSettings { search?: boolean; generative?: boolean; mcp?: boolean; + mcpOauthOnly?: boolean; chat?: boolean; chatReadOnly?: boolean; chatWorkspaceKnowledgeOnly?: boolean; diff --git a/apps/server/src/common/features.ts b/apps/server/src/common/features.ts index e96ce1f48..fcb21d35a 100644 --- a/apps/server/src/common/features.ts +++ b/apps/server/src/common/features.ts @@ -25,6 +25,7 @@ export const Feature = { BASES: 'bases', OAUTH: 'oauth', AI_CONTROLS: 'ai:controls', + MCP_CONTROLS: 'mcp:controls', } as const; export type FeatureKey = (typeof Feature)[keyof typeof Feature]; diff --git a/apps/server/src/core/workspace/dto/update-workspace.dto.ts b/apps/server/src/core/workspace/dto/update-workspace.dto.ts index bdb650097..55b19283d 100644 --- a/apps/server/src/core/workspace/dto/update-workspace.dto.ts +++ b/apps/server/src/core/workspace/dto/update-workspace.dto.ts @@ -1,32 +1,15 @@ import { PartialType } from '@nestjs/mapped-types'; -import { Type } from 'class-transformer'; import { CreateWorkspaceDto } from './create-workspace.dto'; -import { TrustedOAuthClient } from '../workspace.util'; import { - ArrayMaxSize, IsArray, IsBoolean, IsIn, IsInt, - IsNotEmpty, IsOptional, IsString, - MaxLength, Min, - ValidateNested, } from 'class-validator'; -export class TrustedOAuthClientDto { - @IsString() - @IsNotEmpty() - origin: string; - - @IsString() - @IsNotEmpty() - @MaxLength(64) - name: string; -} - export class UpdateWorkspaceDto extends PartialType(CreateWorkspaceDto) { @IsOptional() @IsArray() @@ -86,13 +69,6 @@ export class UpdateWorkspaceDto extends PartialType(CreateWorkspaceDto) { @IsIn(['read', 'edit']) defaultPageEditMode: string; - @IsOptional() - @IsArray() - @ArrayMaxSize(50) - @ValidateNested({ each: true }) - @Type(() => TrustedOAuthClientDto) - trustedOauthClients?: TrustedOAuthClient[]; - @IsOptional() @IsBoolean() aiChatReadOnly: boolean; @@ -100,4 +76,8 @@ export class UpdateWorkspaceDto extends PartialType(CreateWorkspaceDto) { @IsOptional() @IsBoolean() aiChatWorkspaceKnowledgeOnly: boolean; + + @IsOptional() + @IsBoolean() + mcpOauthOnly: boolean; } diff --git a/apps/server/src/core/workspace/services/workspace.service.ts b/apps/server/src/core/workspace/services/workspace.service.ts index 811e67c52..efb10a647 100644 --- a/apps/server/src/core/workspace/services/workspace.service.ts +++ b/apps/server/src/core/workspace/services/workspace.service.ts @@ -30,10 +30,7 @@ import { DomainService } from '../../../integrations/environment/domain.service' import { jsonArrayFrom } from 'kysely/helpers/postgres'; import { addDays } from 'date-fns'; import { DISALLOWED_HOSTNAMES, WorkspaceStatus } from '../workspace.constants'; -import { - isAdminActingOnOwner, - normalizeTrustedOAuthClients, -} from '../workspace.util'; +import { isAdminActingOnOwner } from '../workspace.util'; import { v4 } from 'uuid'; import { InjectQueue } from '@nestjs/bullmq'; import { QueueJob, QueueName } from '../../../integrations/queue/constants'; @@ -317,12 +314,6 @@ export class WorkspaceService { .filter(Boolean); } - if (typeof updateWorkspaceDto.trustedOauthClients !== 'undefined') { - updateWorkspaceDto.trustedOauthClients = normalizeTrustedOAuthClients( - updateWorkspaceDto.trustedOauthClients, - ); - } - if (updateWorkspaceDto.hostname) { const hostname = updateWorkspaceDto.hostname; if (DISALLOWED_HOSTNAMES.includes(hostname)) { @@ -344,9 +335,9 @@ export class WorkspaceService { typeof updateWorkspaceDto.allowMemberTemplates !== 'undefined' || typeof updateWorkspaceDto.isScimEnabled !== 'undefined' || typeof updateWorkspaceDto.allowPersonalSpaces !== 'undefined' || - typeof updateWorkspaceDto.trustedOauthClients !== 'undefined' || typeof updateWorkspaceDto.aiChatReadOnly !== 'undefined' || - typeof updateWorkspaceDto.aiChatWorkspaceKnowledgeOnly !== 'undefined' + typeof updateWorkspaceDto.aiChatWorkspaceKnowledgeOnly !== 'undefined' || + typeof updateWorkspaceDto.mcpOauthOnly !== 'undefined' ) { const ws = await this.db .selectFrom('workspaces') @@ -374,18 +365,6 @@ export class WorkspaceService { } } - if (typeof updateWorkspaceDto.trustedOauthClients !== 'undefined') { - if ( - !this.licenseCheckService.hasFeature( - ws.licenseKey, - Feature.OAUTH, - ws.plan, - ) - ) { - throw new ForbiddenException('This feature requires a valid license'); - } - } - if (typeof updateWorkspaceDto.allowPersonalSpaces !== 'undefined') { if ( !this.licenseCheckService.hasFeature( @@ -413,6 +392,18 @@ export class WorkspaceService { } } + if (typeof updateWorkspaceDto.mcpOauthOnly !== 'undefined') { + if ( + !this.licenseCheckService.hasFeature( + ws.licenseKey, + Feature.MCP_CONTROLS, + ws.plan, + ) + ) { + throw new ForbiddenException('This feature requires a valid license'); + } + } + if ( typeof updateWorkspaceDto.disablePublicSharing !== 'undefined' || typeof updateWorkspaceDto.trashRetentionDays !== 'undefined' || @@ -583,6 +574,20 @@ export class WorkspaceService { ); } + if (typeof updateWorkspaceDto.mcpOauthOnly !== 'undefined') { + const prev = settingsBefore?.ai?.mcpOauthOnly ?? false; + if (prev !== updateWorkspaceDto.mcpOauthOnly) { + before.mcpOauthOnly = prev; + after.mcpOauthOnly = updateWorkspaceDto.mcpOauthOnly; + } + await this.workspaceRepo.updateAiSettings( + workspaceId, + 'mcpOauthOnly', + updateWorkspaceDto.mcpOauthOnly, + trx, + ); + } + if (typeof updateWorkspaceDto.allowPersonalSpaces !== 'undefined') { const prev = settingsBefore?.spaces?.allowPersonal ?? false; if (prev !== updateWorkspaceDto.allowPersonalSpaces) { @@ -622,6 +627,7 @@ export class WorkspaceService { delete updateWorkspaceDto.defaultPageEditMode; delete updateWorkspaceDto.aiChatReadOnly; delete updateWorkspaceDto.aiChatWorkspaceKnowledgeOnly; + delete updateWorkspaceDto.mcpOauthOnly; await this.workspaceRepo.updateWorkspace( updateWorkspaceDto, @@ -661,7 +667,6 @@ export class WorkspaceService { 'enforceMfa', 'emailDomains', 'isScimEnabled', - 'trustedOauthClients', ], updateWorkspaceDto, workspaceBefore, diff --git a/apps/server/src/core/workspace/workspace.util.spec.ts b/apps/server/src/core/workspace/workspace.util.spec.ts deleted file mode 100644 index 7edefd0a2..000000000 --- a/apps/server/src/core/workspace/workspace.util.spec.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { BadRequestException } from '@nestjs/common'; -import { normalizeTrustedOAuthClients } from './workspace.util'; - -describe('normalizeTrustedOAuthClients', () => { - it('lowercases origins and trims names', () => { - expect( - normalizeTrustedOAuthClients([ - { origin: 'https://mcp.acme.com', name: ' Acme MCP ' }, - ]), - ).toEqual([{ origin: 'https://mcp.acme.com', name: 'Acme MCP' }]); - }); - - it('dedupes origins case-insensitively with the last entry winning', () => { - expect( - normalizeTrustedOAuthClients([ - { origin: 'https://mcp.acme.com', name: 'First' }, - { origin: 'https://mcp.acme.com', name: 'Second' }, - ]), - ).toEqual([{ origin: 'https://mcp.acme.com', name: 'Second' }]); - }); - - it.each([ - ['http origin', 'http://mcp.acme.com'], - ['trailing slash', 'https://mcp.acme.com/'], - ['path suffix', 'https://mcp.acme.com/oauth'], - ['uppercase host', 'https://MCP.acme.com'], - ['not a url', 'mcp.acme.com'], - ])('rejects %s naming the origin', (_label, origin) => { - expect(() => - normalizeTrustedOAuthClients([{ origin, name: 'Acme MCP' }]), - ).toThrow(BadRequestException); - expect(() => - normalizeTrustedOAuthClients([{ origin, name: 'Acme MCP' }]), - ).toThrow(origin); - }); - - it.each([ - ['blank', ' '], - ['too long', 'x'.repeat(65)], - ])('rejects a %s name', (_label, name) => { - expect(() => - normalizeTrustedOAuthClients([{ origin: 'https://mcp.acme.com', name }]), - ).toThrow(BadRequestException); - }); - - it('returns an empty array for no entries', () => { - expect(normalizeTrustedOAuthClients([])).toEqual([]); - }); -}); diff --git a/apps/server/src/core/workspace/workspace.util.ts b/apps/server/src/core/workspace/workspace.util.ts index d265c74c1..0d385d04e 100644 --- a/apps/server/src/core/workspace/workspace.util.ts +++ b/apps/server/src/core/workspace/workspace.util.ts @@ -1,4 +1,3 @@ -import { BadRequestException } from '@nestjs/common'; import { UserRole } from '../../common/helpers/types/permission'; export function isAdminActingOnOwner( @@ -8,39 +7,6 @@ export function isAdminActingOnOwner( return authUserRole === UserRole.ADMIN && targetRole === UserRole.OWNER; } -export type TrustedOAuthClient = { origin: string; name: string }; - -// Origins must be exact https origins; duplicates collapse case-insensitively, last entry wins. -export function normalizeTrustedOAuthClients( - entries: { origin: string; name: string }[], -): TrustedOAuthClient[] { - const byOrigin = new Map(); - for (const entry of entries) { - const name = entry.name.trim(); - if (name.length < 1 || name.length > 64) { - throw new BadRequestException( - `Invalid trusted application name for origin: ${entry.origin}`, - ); - } - let parsed: URL; - try { - parsed = new URL(entry.origin); - } catch { - throw new BadRequestException( - `Invalid trusted application origin: ${entry.origin}`, - ); - } - if (parsed.protocol !== 'https:' || parsed.origin !== entry.origin) { - throw new BadRequestException( - `Trusted application origin must be an exact https origin: ${entry.origin}`, - ); - } - const origin = entry.origin.toLowerCase(); - byOrigin.set(origin, { origin, name }); - } - return Array.from(byOrigin.values()); -} - export type PageEditMode = 'read' | 'edit'; export function getWorkspaceDefaultPageEditMode( diff --git a/apps/server/src/database/migrations/20260825T022612-oauth.ts b/apps/server/src/database/migrations/20260825T022612-oauth.ts index 21d135522..0ba5d5937 100644 --- a/apps/server/src/database/migrations/20260825T022612-oauth.ts +++ b/apps/server/src/database/migrations/20260825T022612-oauth.ts @@ -78,17 +78,9 @@ export async function up(db: Kysely): Promise { await db.schema.createIndex('oauth_tokens_access_expires_at_idx').on('oauth_tokens').column('access_expires_at').execute(); await db.schema.createIndex('oauth_tokens_refresh_expires_at_idx').on('oauth_tokens').column('refresh_expires_at').execute(); await db.schema.createIndex('oauth_tokens_revoked_at_idx').on('oauth_tokens').column('revoked_at').execute(); - - await db.schema - .alterTable('workspaces') - .addColumn('trusted_oauth_clients', 'jsonb', (col) => col.defaultTo(sql`'[]'::jsonb`)) - .execute(); } export async function down(db: Kysely): Promise { - await sql`ALTER TABLE workspaces DROP COLUMN IF EXISTS trusted_oauth_clients`.execute( - db, - ); await db.schema.dropTable('oauth_tokens').execute(); await db.schema.dropTable('oauth_grants').execute(); await db.schema.dropTable('oauth_authorization_codes').execute(); diff --git a/apps/server/src/database/repos/workspace/workspace.repo.ts b/apps/server/src/database/repos/workspace/workspace.repo.ts index fa9af749d..a8323d7ce 100644 --- a/apps/server/src/database/repos/workspace/workspace.repo.ts +++ b/apps/server/src/database/repos/workspace/workspace.repo.ts @@ -20,7 +20,6 @@ export class WorkspaceRepo { 'hostname', 'customDomain', 'settings', - 'trustedOauthClients', 'defaultRole', 'emailDomains', 'defaultSpaceId', diff --git a/apps/server/src/database/types/db.d.ts b/apps/server/src/database/types/db.d.ts index aff0682d1..25060c71a 100644 --- a/apps/server/src/database/types/db.d.ts +++ b/apps/server/src/database/types/db.d.ts @@ -460,7 +460,6 @@ export interface Workspaces { status: string | null; stripeCustomerId: string | null; trialEndAt: Timestamp | null; - trustedOauthClients: Generated; updatedAt: Generated; } diff --git a/apps/server/src/ee b/apps/server/src/ee index 1b3f1b90e..70fdfb993 160000 --- a/apps/server/src/ee +++ b/apps/server/src/ee @@ -1 +1 @@ -Subproject commit 1b3f1b90e9a6f5639d408e2288b35aead1693505 +Subproject commit 70fdfb9933083b95d940b5b6df60c30c2e1039de