From 9e5bbb6467d9423d2477f00cb9d9472aa0f25521 Mon Sep 17 00:00:00 2001 From: SkyHuang <906268297@qq.com> Date: Sat, 29 Jun 2024 15:04:10 +0800 Subject: [PATCH] feat: space invitation setting (#679) * feat: add option to allow space invitation for admin setting * chore: db migration * chore: publish 1.2.1-beta.0 release * fix: await missing * fix: ci * fix: isAdmin does not exist --- apps/nestjs-backend/package.json | 2 +- .../src/features/auth/auth.service.ts | 2 +- .../auth/strategies/access-token.strategy.ts | 1 + .../auth/strategies/session.strategy.ts | 1 + .../features/invitation/invitation.service.ts | 15 +++++++++++ .../src/features/setting/setting.service.ts | 1 + .../src/features/space/space.service.ts | 23 +++++++++-------- .../src/features/user/user.service.ts | 12 ++++++--- apps/nestjs-backend/src/types/cls.ts | 1 + apps/nextjs-app/package.json | 2 +- .../app/blocks/admin/setting/SettingPage.tsx | 19 +++++++++++--- .../features/app/blocks/space/SpaceCard.tsx | 4 ++- .../app/blocks/space/SpaceInnerPage.tsx | 4 +++ .../features/app/blocks/space/SpacePage.tsx | 3 ++- .../space/space-side-bar/SpaceSideBar.tsx | 4 +-- .../app/components/space/SpaceActionBar.tsx | 24 +++++++++++++----- .../src/features/app/hooks/useSetting.ts | 7 +++++- .../src/features/auth/pages/LoginPage.tsx | 25 +++++-------------- package.json | 2 +- packages/common-i18n/package.json | 2 +- .../common-i18n/src/locales/en/common.json | 4 ++- .../common-i18n/src/locales/en/token.json | 2 +- .../common-i18n/src/locales/zh/common.json | 2 ++ packages/core/package.json | 2 +- packages/db-main-prisma/package.json | 2 +- .../migration.sql | 2 ++ .../prisma/postgres/schema.prisma | 7 +++--- .../migration.sql | 2 +- .../migration.sql | 2 ++ .../prisma/sqlite/schema.prisma | 7 +++--- .../db-main-prisma/prisma/template.prisma | 7 +++--- packages/eslint-config-bases/package.json | 2 +- packages/icons/package.json | 2 +- packages/openapi/package.json | 2 +- packages/openapi/src/setting/get.ts | 1 + packages/openapi/src/setting/update.ts | 1 + packages/sdk/package.json | 2 +- packages/ui-lib/package.json | 2 +- 38 files changed, 134 insertions(+), 71 deletions(-) create mode 100644 packages/db-main-prisma/prisma/postgres/migrations/20240628115120_add_space_invitation/migration.sql create mode 100644 packages/db-main-prisma/prisma/sqlite/migrations/20240628115107_add_space_invitation/migration.sql diff --git a/apps/nestjs-backend/package.json b/apps/nestjs-backend/package.json index 81c4df563..0f80e1ae9 100644 --- a/apps/nestjs-backend/package.json +++ b/apps/nestjs-backend/package.json @@ -1,6 +1,6 @@ { "name": "@teable/backend", - "version": "1.2.0-beta.0", + "version": "1.2.1-beta.0", "license": "AGPL-3.0", "private": true, "main": "dist/index.js", diff --git a/apps/nestjs-backend/src/features/auth/auth.service.ts b/apps/nestjs-backend/src/features/auth/auth.service.ts index d52af444c..2fa50ebc0 100644 --- a/apps/nestjs-backend/src/features/auth/auth.service.ts +++ b/apps/nestjs-backend/src/features/auth/auth.service.ts @@ -80,7 +80,7 @@ export class AuthService { }, }); } - return await this.userService.createUser({ + return await this.userService.createUserWithSettingCheck({ id: generateUserId(), name: email.split('@')[0], email, diff --git a/apps/nestjs-backend/src/features/auth/strategies/access-token.strategy.ts b/apps/nestjs-backend/src/features/auth/strategies/access-token.strategy.ts index c3c5ef0d7..e195223bc 100644 --- a/apps/nestjs-backend/src/features/auth/strategies/access-token.strategy.ts +++ b/apps/nestjs-backend/src/features/auth/strategies/access-token.strategy.ts @@ -39,6 +39,7 @@ export class AccessTokenStrategy extends PassportStrategy(PassportAccessTokenStr this.cls.set('user.id', user.id); this.cls.set('user.name', user.name); this.cls.set('user.email', user.email); + this.cls.set('user.isAdmin', user.isAdmin); this.cls.set('accessTokenId', accessTokenId); return pickUserMe(user); } diff --git a/apps/nestjs-backend/src/features/auth/strategies/session.strategy.ts b/apps/nestjs-backend/src/features/auth/strategies/session.strategy.ts index 87a22fdfa..59b1cb07b 100644 --- a/apps/nestjs-backend/src/features/auth/strategies/session.strategy.ts +++ b/apps/nestjs-backend/src/features/auth/strategies/session.strategy.ts @@ -31,6 +31,7 @@ export class SessionStrategy extends PassportStrategy(PassportSessionStrategy) { this.cls.set('user.id', user.id); this.cls.set('user.name', user.name); this.cls.set('user.email', user.email); + this.cls.set('user.isAdmin', user.isAdmin); return pickUserMe(user); } } diff --git a/apps/nestjs-backend/src/features/invitation/invitation.service.ts b/apps/nestjs-backend/src/features/invitation/invitation.service.ts index 788381b1b..93a9f45fb 100644 --- a/apps/nestjs-backend/src/features/invitation/invitation.service.ts +++ b/apps/nestjs-backend/src/features/invitation/invitation.service.ts @@ -53,6 +53,21 @@ export class InvitationService { async emailInvitationBySpace(spaceId: string, data: EmailSpaceInvitationRo) { const user = this.cls.get('user'); + + if (!user?.isAdmin) { + const setting = await this.prismaService.setting.findFirst({ + select: { + disallowSpaceInvitation: true, + }, + }); + + if (setting?.disallowSpaceInvitation) { + throw new ForbiddenException( + 'The current instance disallow space invitation by the administrator' + ); + } + } + const space = await this.prismaService.space.findFirst({ select: { name: true }, where: { id: spaceId, deletedTime: null }, diff --git a/apps/nestjs-backend/src/features/setting/setting.service.ts b/apps/nestjs-backend/src/features/setting/setting.service.ts index 68ecc9346..e439070a4 100644 --- a/apps/nestjs-backend/src/features/setting/setting.service.ts +++ b/apps/nestjs-backend/src/features/setting/setting.service.ts @@ -13,6 +13,7 @@ export class SettingService { instanceId: true, disallowSignUp: true, disallowSpaceCreation: true, + disallowSpaceInvitation: true, }, }) .catch(() => { diff --git a/apps/nestjs-backend/src/features/space/space.service.ts b/apps/nestjs-backend/src/features/space/space.service.ts index 31cbec147..cac1917f2 100644 --- a/apps/nestjs-backend/src/features/space/space.service.ts +++ b/apps/nestjs-backend/src/features/space/space.service.ts @@ -98,17 +98,20 @@ export class SpaceService { async createSpace(createSpaceRo: ICreateSpaceRo) { const userId = this.cls.get('user.id'); - const setting = await this.prismaService.setting.findFirst({ - select: { - disallowSignUp: true, - disallowSpaceCreation: true, - }, - }); + const isAdmin = this.cls.get('user.isAdmin'); - if (setting?.disallowSpaceCreation) { - throw new ForbiddenException( - 'The current instance disallow space creation by the administrator' - ); + if (!isAdmin) { + const setting = await this.prismaService.setting.findFirst({ + select: { + disallowSpaceCreation: true, + }, + }); + + if (setting?.disallowSpaceCreation) { + throw new ForbiddenException( + 'The current instance disallow space creation by the administrator' + ); + } } const spaceList = await this.prismaService.space.findMany({ diff --git a/apps/nestjs-backend/src/features/user/user.service.ts b/apps/nestjs-backend/src/features/user/user.service.ts index 75a4f7e69..ec2600bf0 100644 --- a/apps/nestjs-backend/src/features/user/user.service.ts +++ b/apps/nestjs-backend/src/features/user/user.service.ts @@ -78,14 +78,13 @@ export class UserService { return space; } - async createUser( + async createUserWithSettingCheck( user: Omit & { name?: string }, account?: Omit ) { const setting = await this.prismaService.setting.findFirst({ select: { disallowSignUp: true, - disallowSpaceCreation: true, }, }); @@ -93,6 +92,13 @@ export class UserService { throw new BadRequestException('The current instance disallow sign up by the administrator'); } + return await this.createUser(user, account); + } + + async createUser( + user: Omit & { name?: string }, + account?: Omit + ) { // defaults const defaultNotifyMeta: IUserNotifyMeta = { email: true, @@ -292,7 +298,7 @@ export class UserService { if (avatarUrl) { avatar = await this.uploadAvatarByUrl(userId, avatarUrl); } - return await this.createUser( + return await this.createUserWithSettingCheck( { id: userId, email, name, avatar }, { provider, providerId, type } ); diff --git a/apps/nestjs-backend/src/types/cls.ts b/apps/nestjs-backend/src/types/cls.ts index d40cf3e7a..b6e7fb9a6 100644 --- a/apps/nestjs-backend/src/types/cls.ts +++ b/apps/nestjs-backend/src/types/cls.ts @@ -8,6 +8,7 @@ export interface IClsStore extends ClsStore { id: string; name: string; email: string; + isAdmin?: boolean | null; }; accessTokenId?: string; entry?: { diff --git a/apps/nextjs-app/package.json b/apps/nextjs-app/package.json index 3b65453b8..69be6fada 100644 --- a/apps/nextjs-app/package.json +++ b/apps/nextjs-app/package.json @@ -1,6 +1,6 @@ { "name": "@teable/app", - "version": "1.2.0-beta.0", + "version": "1.2.1-beta.0", "license": "AGPL-3.0", "private": true, "main": "main/index.js", diff --git a/apps/nextjs-app/src/features/app/blocks/admin/setting/SettingPage.tsx b/apps/nextjs-app/src/features/app/blocks/admin/setting/SettingPage.tsx index b7ca44ae3..0a9a94d68 100644 --- a/apps/nextjs-app/src/features/app/blocks/admin/setting/SettingPage.tsx +++ b/apps/nextjs-app/src/features/app/blocks/admin/setting/SettingPage.tsx @@ -32,7 +32,7 @@ export const SettingPage = (props: ISettingPageProps) => { if (!setting) return null; - const { instanceId, disallowSignUp, disallowSpaceCreation } = setting; + const { instanceId, disallowSignUp, disallowSpaceCreation, disallowSpaceInvitation } = setting; return (
@@ -42,7 +42,7 @@ export const SettingPage = (props: ISettingPageProps) => {
-
+
@@ -55,7 +55,20 @@ export const SettingPage = (props: ISettingPageProps) => { onCheckedChange={(checked) => onCheckedChange('disallowSignUp', !checked)} />
-
+
+
+ +
+ {t('admin.setting.allowSpaceInvitationDescription')} +
+
+ onCheckedChange('disallowSpaceInvitation', !checked)} + /> +
+
diff --git a/apps/nextjs-app/src/features/app/blocks/space/SpaceCard.tsx b/apps/nextjs-app/src/features/app/blocks/space/SpaceCard.tsx index 646a18adc..772c6bf9d 100644 --- a/apps/nextjs-app/src/features/app/blocks/space/SpaceCard.tsx +++ b/apps/nextjs-app/src/features/app/blocks/space/SpaceCard.tsx @@ -18,9 +18,10 @@ interface ISpaceCard { space: IGetSpaceVo; bases?: IGetBaseVo[]; subscription?: ISubscriptionSummaryVo; + disallowSpaceInvitation?: boolean | null; } export const SpaceCard: FC = (props) => { - const { space, bases, subscription } = props; + const { space, bases, subscription, disallowSpaceInvitation } = props; const router = useRouter(); const isCloud = useIsCloud(); const queryClient = useQueryClient(); @@ -91,6 +92,7 @@ export const SpaceCard: FC = (props) => { buttonSize="xs" space={space} invQueryFilters={ReactQueryKeys.baseAll() as unknown as string[]} + disallowSpaceInvitation={disallowSpaceInvitation} onDelete={() => deleteSpaceMutator(space.id)} onRename={() => setRenaming(true)} onSpaceSetting={onSpaceSetting} diff --git a/apps/nextjs-app/src/features/app/blocks/space/SpaceInnerPage.tsx b/apps/nextjs-app/src/features/app/blocks/space/SpaceInnerPage.tsx index a74aecbef..3b3cb12bb 100644 --- a/apps/nextjs-app/src/features/app/blocks/space/SpaceInnerPage.tsx +++ b/apps/nextjs-app/src/features/app/blocks/space/SpaceInnerPage.tsx @@ -16,6 +16,7 @@ import { Collaborators } from '../../components/collaborator-manage/space-inner/ import { SpaceActionBar } from '../../components/space/SpaceActionBar'; import { SpaceRenaming } from '../../components/space/SpaceRenaming'; import { useIsCloud } from '../../hooks/useIsCloud'; +import { useSetting } from '../../hooks/useSetting'; import { DraggableBaseGrid } from './DraggableBaseGrid'; import { StarButton } from './space-side-bar/StarButton'; import { useBaseList } from './useBaseList'; @@ -38,6 +39,8 @@ export const SpaceInnerPage: React.FC = () => { const bases = useBaseList(); + const { disallowSpaceInvitation } = useSetting(); + const basesInSpace = useMemo(() => { return bases?.filter((base) => base.spaceId === spaceId); }, [bases, spaceId]); @@ -124,6 +127,7 @@ export const SpaceInnerPage: React.FC = () => { space={space} buttonSize={'xs'} invQueryFilters={ReactQueryKeys.baseAll() as unknown as string[]} + disallowSpaceInvitation={disallowSpaceInvitation} onDelete={() => deleteSpaceMutator(space.id)} onRename={() => setRenaming(true)} onSpaceSetting={onSpaceSetting} diff --git a/apps/nextjs-app/src/features/app/blocks/space/SpacePage.tsx b/apps/nextjs-app/src/features/app/blocks/space/SpacePage.tsx index e5ae74ffc..2be31c729 100644 --- a/apps/nextjs-app/src/features/app/blocks/space/SpacePage.tsx +++ b/apps/nextjs-app/src/features/app/blocks/space/SpacePage.tsx @@ -34,7 +34,7 @@ export const SpacePage: FC = () => { enabled: isCloud, }); - const { disallowSpaceCreation } = useSetting(); + const { disallowSpaceCreation, disallowSpaceInvitation } = useSetting(); const { mutate: createSpaceMutator, isLoading } = useMutation({ mutationFn: createSpace, @@ -77,6 +77,7 @@ export const SpacePage: FC = () => { space={space} bases={baseList?.filter(({ spaceId }) => spaceId === space.id)} subscription={subscriptionMap[space.id]} + disallowSpaceInvitation={disallowSpaceInvitation} /> ))}
diff --git a/apps/nextjs-app/src/features/app/blocks/space/space-side-bar/SpaceSideBar.tsx b/apps/nextjs-app/src/features/app/blocks/space/space-side-bar/SpaceSideBar.tsx index a72da9407..3d4e79d57 100644 --- a/apps/nextjs-app/src/features/app/blocks/space/space-side-bar/SpaceSideBar.tsx +++ b/apps/nextjs-app/src/features/app/blocks/space/space-side-bar/SpaceSideBar.tsx @@ -4,7 +4,6 @@ import { Button } from '@teable/ui-lib/shadcn/ui/button'; import Link from 'next/link'; import { useRouter } from 'next/router'; import { useTranslation } from 'next-i18next'; -import { useIsCloud } from '@/features/app/hooks/useIsCloud'; import { spaceConfig } from '@/features/i18n/space.config'; import { PinList } from './PinList'; import { SpaceList } from './SpaceList'; @@ -12,7 +11,6 @@ import { SpaceList } from './SpaceList'; export const SpaceSideBar = (props: { isAdmin?: boolean | null }) => { const { isAdmin } = props; const router = useRouter(); - const isCloud = useIsCloud(); const { t } = useTranslation(spaceConfig.i18nNamespaces); const pageRoutes: { @@ -30,7 +28,7 @@ export const SpaceSideBar = (props: { isAdmin?: boolean | null }) => { href: '/admin/setting', text: t('noun.adminPanel'), Icon: Admin, - hidden: isCloud || !isAdmin, + hidden: !isAdmin, }, ]; return ( diff --git a/apps/nextjs-app/src/features/app/components/space/SpaceActionBar.tsx b/apps/nextjs-app/src/features/app/components/space/SpaceActionBar.tsx index d62202d1f..c59d5a982 100644 --- a/apps/nextjs-app/src/features/app/components/space/SpaceActionBar.tsx +++ b/apps/nextjs-app/src/features/app/components/space/SpaceActionBar.tsx @@ -16,13 +16,22 @@ interface ActionBarProps { invQueryFilters: string[]; className?: string; buttonSize?: ButtonProps['size']; + disallowSpaceInvitation?: boolean | null; onRename?: () => void; onDelete?: () => void; onSpaceSetting?: () => void; } export const SpaceActionBar: React.FC = (props) => { - const { space, className, buttonSize = 'default', onRename, onDelete, onSpaceSetting } = props; + const { + space, + className, + buttonSize = 'default', + disallowSpaceInvitation, + onRename, + onDelete, + onSpaceSetting, + } = props; const { t } = useTranslation(spaceConfig.i18nNamespaces); return ( @@ -34,11 +43,14 @@ export const SpaceActionBar: React.FC = (props) => { )} - - - + {!disallowSpaceInvitation && ( + + + + )} + { queryFn: () => getSetting().then(({ data }) => data), }); - const { disallowSignUp = false, disallowSpaceCreation = false } = setting ?? {}; + const { + disallowSignUp = false, + disallowSpaceCreation = false, + disallowSpaceInvitation = false, + } = setting ?? {}; return { disallowSignUp, disallowSpaceCreation: !user.isAdmin && (isLoading || disallowSpaceCreation), + disallowSpaceInvitation: !user.isAdmin && (isLoading || disallowSpaceInvitation), }; }; diff --git a/apps/nextjs-app/src/features/auth/pages/LoginPage.tsx b/apps/nextjs-app/src/features/auth/pages/LoginPage.tsx index 36019f0ff..15399d316 100644 --- a/apps/nextjs-app/src/features/auth/pages/LoginPage.tsx +++ b/apps/nextjs-app/src/features/auth/pages/LoginPage.tsx @@ -1,6 +1,4 @@ -import { useQuery } from '@tanstack/react-query'; import { TeableNew } from '@teable/icons'; -import { getSetting } from '@teable/openapi'; import { Tabs, TabsList, TabsTrigger } from '@teable/ui-lib/shadcn'; import { useRouter } from 'next/router'; import { useTranslation } from 'next-i18next'; @@ -20,13 +18,6 @@ export const LoginPage: FC = () => { window.location.href = redirect ? decodeURIComponent(redirect) : '/space'; }, [redirect]); - const { data: setting } = useQuery({ - queryKey: ['setting'], - queryFn: () => getSetting().then(({ data }) => data), - }); - - const { disallowSignUp = false } = setting ?? {}; - return ( <> @@ -36,16 +27,12 @@ export const LoginPage: FC = () => { {t('common:brand')}
- {disallowSignUp ? ( - t('auth:button.signin') - ) : ( - setSignType(val as ISignForm['type'])}> - - {t('auth:button.signin')} - {t('auth:button.signup')} - - - )} + setSignType(val as ISignForm['type'])}> + + {t('auth:button.signin')} + {t('auth:button.signup')} + +
diff --git a/package.json b/package.json index 6f1ba6b7c..a38492610 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@teable/teable", - "version": "1.2.0-beta.0", + "version": "1.2.1-beta.0", "license": "AGPL-3.0", "private": true, "homepage": "https://github.com/teableio/teable", diff --git a/packages/common-i18n/package.json b/packages/common-i18n/package.json index 32ee56a0a..6fb67214d 100644 --- a/packages/common-i18n/package.json +++ b/packages/common-i18n/package.json @@ -1,6 +1,6 @@ { "name": "@teable/common-i18n", - "version": "1.2.0-beta.0", + "version": "1.2.1-beta.0", "license": "AGPL-3.0", "homepage": "https://github.com/teableio/teable", "private": false, diff --git a/packages/common-i18n/src/locales/en/common.json b/packages/common-i18n/src/locales/en/common.json index e4b2975f9..3a0514be1 100644 --- a/packages/common-i18n/src/locales/en/common.json +++ b/packages/common-i18n/src/locales/en/common.json @@ -184,7 +184,9 @@ "description": "Change the settings for your current instance", "allowSignUp": "Allow creating new accounts", "allowSignUpDescription": "Disabling this option will prohibit new user registrations, and the register button will no longer appear on the login page.", - "allowSpaceCreation": "Allow everyone to create new workspaces", + "allowSpaceInvitation": "Allow sending space invitations", + "allowSpaceInvitationDescription": "Disabling this option will prevent users other than administrators from inviting others to join spaces. Enabling this option will allow directly invited users to create an account even if new account registration is disabled.", + "allowSpaceCreation": "Allow everyone to create new spaces", "allowSpaceCreationDescription": "Disabling this option will prevent users other than administrators from creating new spaces." } } diff --git a/packages/common-i18n/src/locales/en/token.json b/packages/common-i18n/src/locales/en/token.json index 01b7322b1..07bb50bef 100644 --- a/packages/common-i18n/src/locales/en/token.json +++ b/packages/common-i18n/src/locales/en/token.json @@ -17,7 +17,7 @@ "new": { "headerTitle": "Create new token", "title": "Personal access tokens are required to use the Teable API.", - "description": "This token will grant access to the data in the selected workspaces and bases. This token will also allow usage of other, non-workspace/base API endpoints. Only use this token for your own development. Don’t share it with third-party services and applications.", + "description": "This token will grant access to the data in the selected spaces and bases. This token will also allow usage of other, non-space/base API endpoints. Only use this token for your own development. Don’t share it with third-party services and applications.", "button": "Create new token", "success": { "title": "Token successfully generated", diff --git a/packages/common-i18n/src/locales/zh/common.json b/packages/common-i18n/src/locales/zh/common.json index 3d99e8223..133dea1db 100644 --- a/packages/common-i18n/src/locales/zh/common.json +++ b/packages/common-i18n/src/locales/zh/common.json @@ -183,6 +183,8 @@ "description": "更改当前实例的设置", "allowSignUp": "允许新用户注册", "allowSignUpDescription": "关闭此选项将禁止新用户注册,登录页面将不再显示注册按钮。", + "allowSpaceInvitation": "允许发送空间邀请", + "allowSpaceInvitationDescription": "关闭此选项将禁止除管理员以外的用户邀请他人加入空间。开启此选项后,即使新账户注册已被禁用,仍允许被直接邀请的用户创建账户。", "allowSpaceCreation": "允许所有人创建新的空间", "allowSpaceCreationDescription": "关闭此选项将禁止除管理员以外的用户创建新的空间。" } diff --git a/packages/core/package.json b/packages/core/package.json index 3495015f5..1a6e6e0a2 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@teable/core", - "version": "1.2.0-beta.0", + "version": "1.2.1-beta.0", "license": "AGPL-3.0", "homepage": "https://github.com/teableio/teable", "publishConfig": { diff --git a/packages/db-main-prisma/package.json b/packages/db-main-prisma/package.json index d549fcf35..4bb7826ee 100644 --- a/packages/db-main-prisma/package.json +++ b/packages/db-main-prisma/package.json @@ -1,6 +1,6 @@ { "name": "@teable/db-main-prisma", - "version": "1.2.0-beta.0", + "version": "1.2.1-beta.0", "license": "AGPL-3.0", "homepage": "https://github.com/teableio/teable", "private": true, diff --git a/packages/db-main-prisma/prisma/postgres/migrations/20240628115120_add_space_invitation/migration.sql b/packages/db-main-prisma/prisma/postgres/migrations/20240628115120_add_space_invitation/migration.sql new file mode 100644 index 000000000..89e53a53f --- /dev/null +++ b/packages/db-main-prisma/prisma/postgres/migrations/20240628115120_add_space_invitation/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "setting" ADD COLUMN "disallow_space_invitation" BOOLEAN; diff --git a/packages/db-main-prisma/prisma/postgres/schema.prisma b/packages/db-main-prisma/prisma/postgres/schema.prisma index 2506b6df1..450679c29 100644 --- a/packages/db-main-prisma/prisma/postgres/schema.prisma +++ b/packages/db-main-prisma/prisma/postgres/schema.prisma @@ -324,9 +324,10 @@ model AccessToken { } model Setting { - instanceId String @id @default(cuid()) @map("instance_id") - disallowSignUp Boolean? @map("disallow_sign_up") - disallowSpaceCreation Boolean? @map("disallow_space_creation") + instanceId String @id @default(cuid()) @map("instance_id") + disallowSignUp Boolean? @map("disallow_sign_up") + disallowSpaceCreation Boolean? @map("disallow_space_creation") + disallowSpaceInvitation Boolean? @map("disallow_space_invitation") @@map("setting") } \ No newline at end of file diff --git a/packages/db-main-prisma/prisma/sqlite/migrations/20240626072703_add_setting_table/migration.sql b/packages/db-main-prisma/prisma/sqlite/migrations/20240626072703_add_setting_table/migration.sql index 2a74341b9..fdcbc7b1c 100644 --- a/packages/db-main-prisma/prisma/sqlite/migrations/20240626072703_add_setting_table/migration.sql +++ b/packages/db-main-prisma/prisma/sqlite/migrations/20240626072703_add_setting_table/migration.sql @@ -8,4 +8,4 @@ CREATE TABLE "setting" ( ); -- Insert initial record -INSERT INTO "setting" ("instance_id", "disallow_sign_up", "disallow_space_creation") VALUES (gen_random_uuid(), NULL, NULL); +INSERT INTO "setting" ("instance_id", "disallow_sign_up", "disallow_space_creation") VALUES ("instance-id", NULL, NULL); diff --git a/packages/db-main-prisma/prisma/sqlite/migrations/20240628115107_add_space_invitation/migration.sql b/packages/db-main-prisma/prisma/sqlite/migrations/20240628115107_add_space_invitation/migration.sql new file mode 100644 index 000000000..2bc61e923 --- /dev/null +++ b/packages/db-main-prisma/prisma/sqlite/migrations/20240628115107_add_space_invitation/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "setting" ADD COLUMN "disallow_space_invitation" BOOLEAN; diff --git a/packages/db-main-prisma/prisma/sqlite/schema.prisma b/packages/db-main-prisma/prisma/sqlite/schema.prisma index 43f7c60a9..7b77cb0ae 100644 --- a/packages/db-main-prisma/prisma/sqlite/schema.prisma +++ b/packages/db-main-prisma/prisma/sqlite/schema.prisma @@ -324,9 +324,10 @@ model AccessToken { } model Setting { - instanceId String @id @default(cuid()) @map("instance_id") - disallowSignUp Boolean? @map("disallow_sign_up") - disallowSpaceCreation Boolean? @map("disallow_space_creation") + instanceId String @id @default(cuid()) @map("instance_id") + disallowSignUp Boolean? @map("disallow_sign_up") + disallowSpaceCreation Boolean? @map("disallow_space_creation") + disallowSpaceInvitation Boolean? @map("disallow_space_invitation") @@map("setting") } \ No newline at end of file diff --git a/packages/db-main-prisma/prisma/template.prisma b/packages/db-main-prisma/prisma/template.prisma index 0d21c5326..c74e4ae9a 100644 --- a/packages/db-main-prisma/prisma/template.prisma +++ b/packages/db-main-prisma/prisma/template.prisma @@ -324,9 +324,10 @@ model AccessToken { } model Setting { - instanceId String @id @default(cuid()) @map("instance_id") - disallowSignUp Boolean? @map("disallow_sign_up") - disallowSpaceCreation Boolean? @map("disallow_space_creation") + instanceId String @id @default(cuid()) @map("instance_id") + disallowSignUp Boolean? @map("disallow_sign_up") + disallowSpaceCreation Boolean? @map("disallow_space_creation") + disallowSpaceInvitation Boolean? @map("disallow_space_invitation") @@map("setting") } \ No newline at end of file diff --git a/packages/eslint-config-bases/package.json b/packages/eslint-config-bases/package.json index 475231681..708db4ae6 100644 --- a/packages/eslint-config-bases/package.json +++ b/packages/eslint-config-bases/package.json @@ -1,6 +1,6 @@ { "name": "@teable/eslint-config-bases", - "version": "1.2.0-beta.0", + "version": "1.2.1-beta.0", "license": "AGPL-3.0", "private": true, "homepage": "https://github.com/teableio/teable", diff --git a/packages/icons/package.json b/packages/icons/package.json index 6eaccec72..f550bda88 100644 --- a/packages/icons/package.json +++ b/packages/icons/package.json @@ -1,6 +1,6 @@ { "name": "@teable/icons", - "version": "1.2.0-beta.0", + "version": "1.2.1-beta.0", "license": "AGPL-3.0", "homepage": "https://github.com/teableio/teable", "publishConfig": { diff --git a/packages/openapi/package.json b/packages/openapi/package.json index b4a5014a6..b030b21a2 100644 --- a/packages/openapi/package.json +++ b/packages/openapi/package.json @@ -1,6 +1,6 @@ { "name": "@teable/openapi", - "version": "1.2.0-beta.0", + "version": "1.2.1-beta.0", "license": "AGPL-3.0", "homepage": "https://github.com/teableio/teable", "publishConfig": { diff --git a/packages/openapi/src/setting/get.ts b/packages/openapi/src/setting/get.ts index 3428718f1..370fed18d 100644 --- a/packages/openapi/src/setting/get.ts +++ b/packages/openapi/src/setting/get.ts @@ -7,6 +7,7 @@ export const settingVoSchema = z.object({ instanceId: z.string(), disallowSignUp: z.boolean().nullable(), disallowSpaceCreation: z.boolean().nullable(), + disallowSpaceInvitation: z.boolean().nullable(), }); export type ISettingVo = z.infer; diff --git a/packages/openapi/src/setting/update.ts b/packages/openapi/src/setting/update.ts index 24b3dd42a..03fb1afa2 100644 --- a/packages/openapi/src/setting/update.ts +++ b/packages/openapi/src/setting/update.ts @@ -6,6 +6,7 @@ import { registerRoute } from '../utils'; export const updateSettingRoSchema = z.object({ disallowSignUp: z.boolean().optional(), disallowSpaceCreation: z.boolean().optional(), + disallowSpaceInvitation: z.boolean().optional(), }); export type IUpdateSettingRo = z.infer; diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 906b2bcab..5edef346c 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@teable/sdk", - "version": "1.2.0-beta.0", + "version": "1.2.1-beta.0", "license": "AGPL-3.0", "homepage": "https://github.com/teableio/teable", "publishConfig": { diff --git a/packages/ui-lib/package.json b/packages/ui-lib/package.json index 3c49ea686..23cd15b22 100644 --- a/packages/ui-lib/package.json +++ b/packages/ui-lib/package.json @@ -1,6 +1,6 @@ { "name": "@teable/ui-lib", - "version": "1.2.0-beta.0", + "version": "1.2.1-beta.0", "license": "AGPL-3.0", "homepage": "https://github.com/teableio/teable", "publishConfig": {