From c4df8e25154461f071f2fee3eaf4cc4d60f8c403 Mon Sep 17 00:00:00 2001 From: cy948 Date: Sat, 4 May 2024 16:42:20 +0800 Subject: [PATCH 01/16] :recycle: refactor: move next-auth hooks to store acitons --- .../settings/common/features/Common.tsx | 8 +++++-- src/features/Conversation/Error/OAuthForm.tsx | 9 ++++---- src/libs/next-auth/index.ts | 7 ------ src/store/user/slices/auth/action.ts | 7 ++++++ src/types/next-auth.d.ts | 23 +++++++++++++++++++ 5 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 src/types/next-auth.d.ts diff --git a/src/app/(main)/settings/common/features/Common.tsx b/src/app/(main)/settings/common/features/Common.tsx index 730997a96dce..f1e02a035b13 100644 --- a/src/app/(main)/settings/common/features/Common.tsx +++ b/src/app/(main)/settings/common/features/Common.tsx @@ -3,7 +3,6 @@ import { Form, type ItemGroup } from '@lobehub/ui'; import { App, Button, Input } from 'antd'; import isEqual from 'fast-deep-equal'; -import { signIn, signOut } from 'next-auth/react'; import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; @@ -42,7 +41,12 @@ const Common = memo(({ showAccessCodeConfig, showOAuthLogin const [removeAllFiles] = useFileStore((s) => [s.removeAllFiles]); const removeAllPlugins = useToolStore((s) => s.removeAllPlugins); const settings = useUserStore(settingsSelectors.currentSettings, isEqual); - const [setSettings, resetSettings] = useUserStore((s) => [s.setSettings, s.resetSettings]); + const [setSettings, resetSettings, signIn, signOut] = useUserStore((s) => [ + s.setSettings, + s.resetSettings, + s.login, + s.logout, + ]); const { message, modal } = App.useApp(); diff --git a/src/features/Conversation/Error/OAuthForm.tsx b/src/features/Conversation/Error/OAuthForm.tsx index 4ebde624765e..0020afe9589c 100644 --- a/src/features/Conversation/Error/OAuthForm.tsx +++ b/src/features/Conversation/Error/OAuthForm.tsx @@ -1,20 +1,21 @@ import { Icon } from '@lobehub/ui'; import { App, Button } from 'antd'; import { ScanFace } from 'lucide-react'; -import { signIn, signOut } from 'next-auth/react'; import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { Center, Flexbox } from 'react-layout-kit'; -import { useOAuthSession } from '@/hooks/useOAuthSession'; import { useChatStore } from '@/store/chat'; +import { useUserStore } from '@/store/user'; +import { userProfileSelectors } from '@/store/user/selectors'; import { FormAction } from './style'; const OAuthForm = memo<{ id: string }>(({ id }) => { const { t } = useTranslation('error'); - const { user, isOAuthLoggedIn } = useOAuthSession(); + const [signIn, signOut, isOAuthLoggedIn] = useUserStore((s) => [s.login, s.logout, s.isSignedIn]); + const user = useUserStore(userProfileSelectors.userProfile); const [resend, deleteMessage] = useChatStore((s) => [s.internalResendMessage, s.deleteMessage]); @@ -38,7 +39,7 @@ const OAuthForm = memo<{ id: string }>(({ id }) => { avatar={isOAuthLoggedIn ? '✅' : '🕵️‍♂️'} description={ isOAuthLoggedIn - ? `${t('unlock.oauth.welcome')} ${user?.name}` + ? `${t('unlock.oauth.welcome')} ${user?.fullName || ''}` : t('unlock.oauth.description') } title={isOAuthLoggedIn ? t('unlock.oauth.success') : t('unlock.oauth.title')} diff --git a/src/libs/next-auth/index.ts b/src/libs/next-auth/index.ts index c994a586c4b4..d5e081d1037c 100644 --- a/src/libs/next-auth/index.ts +++ b/src/libs/next-auth/index.ts @@ -46,10 +46,3 @@ export const { handlers: { GET, POST }, auth, } = nextAuth; - -declare module '@auth/core/jwt' { - // Returned by the `jwt` callback and `auth`, when using JWT sessions - interface JWT { - userId?: string; - } -} diff --git a/src/store/user/slices/auth/action.ts b/src/store/user/slices/auth/action.ts index ebd458d44263..f521ae302ea9 100644 --- a/src/store/user/slices/auth/action.ts +++ b/src/store/user/slices/auth/action.ts @@ -1,3 +1,4 @@ +import { signIn, signOut } from 'next-auth/react'; import useSWR, { SWRResponse, mutate } from 'swr'; import { StateCreator } from 'zustand/vanilla'; @@ -38,10 +39,16 @@ export const createAuthSlice: StateCreator< login: async () => { // TODO: 针对开启 next-auth 的场景,需要在这里调用登录方法 console.log(n('login')); + + // TODO: 应该条件调用 next-auth 的登陆 hook + signIn(); }, logout: async () => { // TODO: 针对开启 next-auth 的场景,需要在这里调用登录方法 console.log(n('logout')); + + // TODO: 应该条件调用 next-auth 的登出 hook + signOut(); }, refreshUserConfig: async () => { await mutate([USER_CONFIG_FETCH_KEY, true]); diff --git a/src/types/next-auth.d.ts b/src/types/next-auth.d.ts new file mode 100644 index 000000000000..26dabb419014 --- /dev/null +++ b/src/types/next-auth.d.ts @@ -0,0 +1,23 @@ +import { type DefaultSession } from 'next-auth'; + +declare module 'next-auth' { + /** + * Returned by `useSession`, `auth`, contains information about the active session. + */ + interface Session { + user: { + firstName?: string; + } & DefaultSession['user']; + } + /** + * More types can be extends here + * ref: https://authjs.dev/getting-started/typescript + */ +} + +declare module '@auth/core/jwt' { + /** Returned by the `jwt` callback and `auth`, when using JWT sessions */ + interface JWT { + userId: string; + } +} From 992e82c3b628d6c833e70df1793a7c1a627e1603 Mon Sep 17 00:00:00 2001 From: cy948 Date: Sun, 5 May 2024 14:34:53 +0800 Subject: [PATCH 02/16] :fire: refactor: remove redundant files --- src/hooks/useOAuthSession.ts | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 src/hooks/useOAuthSession.ts diff --git a/src/hooks/useOAuthSession.ts b/src/hooks/useOAuthSession.ts deleted file mode 100644 index 8b86a01d14a8..000000000000 --- a/src/hooks/useOAuthSession.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { User } from '@auth/core/types'; -import { SessionContextValue, useSession } from 'next-auth/react'; -import { useMemo } from 'react'; - -interface OAuthSession { - isOAuthLoggedIn: boolean; - user?: User | null; -} - -export const useOAuthSession = () => { - let authSession: SessionContextValue | null; - try { - // refs: https://github.com/lobehub/lobe-chat/pull/1286 - // eslint-disable-next-line react-hooks/rules-of-hooks - authSession = useSession(); - } catch { - authSession = null; - } - - const { data: session, status } = authSession || {}; - const isOAuthLoggedIn = (status === 'authenticated' && session && !!session.user) || false; - - return useMemo(() => ({ isOAuthLoggedIn, user: session?.user }), [session, status]); -}; From 599c60123512b03ce49c0442f633cf15eb443673 Mon Sep 17 00:00:00 2001 From: cy948 Date: Mon, 6 May 2024 01:25:26 +0800 Subject: [PATCH 03/16] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20add=20ne?= =?UTF-8?q?xt-auth=20hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/features/Conversation/Error/OAuthForm.tsx | 5 ++-- src/store/user/slices/auth/action.ts | 29 ++++++++++--------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/features/Conversation/Error/OAuthForm.tsx b/src/features/Conversation/Error/OAuthForm.tsx index 0020afe9589c..a56aab3df718 100644 --- a/src/features/Conversation/Error/OAuthForm.tsx +++ b/src/features/Conversation/Error/OAuthForm.tsx @@ -7,15 +7,16 @@ import { Center, Flexbox } from 'react-layout-kit'; import { useChatStore } from '@/store/chat'; import { useUserStore } from '@/store/user'; -import { userProfileSelectors } from '@/store/user/selectors'; +import { authSelectors, userProfileSelectors } from '@/store/user/selectors'; import { FormAction } from './style'; const OAuthForm = memo<{ id: string }>(({ id }) => { const { t } = useTranslation('error'); - const [signIn, signOut, isOAuthLoggedIn] = useUserStore((s) => [s.login, s.logout, s.isSignedIn]); + const [signIn, signOut] = useUserStore((s) => [s.openLogin, s.logout]); const user = useUserStore(userProfileSelectors.userProfile); + const isOAuthLoggedIn = useUserStore(authSelectors.isLoginWithAuth); const [resend, deleteMessage] = useChatStore((s) => [s.internalResendMessage, s.deleteMessage]); diff --git a/src/store/user/slices/auth/action.ts b/src/store/user/slices/auth/action.ts index 0d66407b2290..fb32d39f5161 100644 --- a/src/store/user/slices/auth/action.ts +++ b/src/store/user/slices/auth/action.ts @@ -43,10 +43,12 @@ export const createAuthSlice: StateCreator< // TODO: 针对开启 next-auth 的场景,需要在这里调用登录方法 console.log(n('login')); - if (enableNextAuth) { - // TODO: 应该条件调用 next-auth 的登陆 hook - signIn(); - } + // Currently disable the condition to judge the login method + // ref: https://github.com/lobehub/lobe-chat/pull/2364 + // if (enableNextAuth) { + // TODO: 应该条件调用 next-auth 的登陆 hook + signIn(); + // } }, logout: async () => { if (enableClerk) { @@ -55,11 +57,12 @@ export const createAuthSlice: StateCreator< return; } - if (enableNextAuth) { - // TODO: 针对开启 next-auth 的场景,需要在这里调用登录方法 - console.log(n('logout')); - signOut(); - } + // Disable the condition, + // if (enableNextAuth) { + // TODO: 针对开启 next-auth 的场景,需要在这里调用登录方法 + console.log(n('logout')); + signOut(); + // } }, openLogin: async () => { if (enableClerk) { @@ -70,10 +73,10 @@ export const createAuthSlice: StateCreator< return; } - if (enableNextAuth) { - // TODO: 针对开启 next-auth 的场景,需要在这里调用登录方法 - signIn(); - } + // if (enableNextAuth) { + // TODO: 针对开启 next-auth 的场景,需要在这里调用登录方法 + signIn(); + // } }, openUserProfile: async () => { if (enableClerk) { From da3600a2edadfffa2369f95659d594225cb3b02f Mon Sep 17 00:00:00 2001 From: cy948 Date: Mon, 6 May 2024 13:02:38 +0800 Subject: [PATCH 04/16] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20add=20en?= =?UTF-8?q?v=20`NEXT=5FPUBLIC=5FENABLE=5FNEXT=5FAUTH`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config/auth.ts | 3 ++- src/store/user/slices/auth/action.ts | 29 +++++++++++++--------------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/config/auth.ts b/src/config/auth.ts index 01a1b6ec7a2c..d26a1719b63f 100644 --- a/src/config/auth.ts +++ b/src/config/auth.ts @@ -16,6 +16,7 @@ declare global { * @deprecated */ ENABLE_OAUTH_SSO?: string; + NEXT_PUBLIC_ENABLE_NEXT_AUTH?: string; NEXT_AUTH_SECRET?: string; /** * @deprecated @@ -112,7 +113,7 @@ export const getAuthConfig = () => { CLERK_SECRET_KEY: process.env.CLERK_SECRET_KEY, // Next Auth - NEXT_PUBLIC_ENABLE_NEXT_AUTH: !!process.env.NEXT_AUTH_SECRET || process.env.ENABLE_OAUTH_SSO, + NEXT_PUBLIC_ENABLE_NEXT_AUTH: !!process.env.NEXT_PUBLIC_ENABLE_NEXT_AUTH, NEXT_AUTH_SSO_PROVIDERS: process.env.NEXT_AUTH_SSO_PROVIDERS || process.env.SSO_PROVIDERS, NEXT_AUTH_SECRET: process.env.NEXT_AUTH_SECRET, diff --git a/src/store/user/slices/auth/action.ts b/src/store/user/slices/auth/action.ts index fb32d39f5161..0d66407b2290 100644 --- a/src/store/user/slices/auth/action.ts +++ b/src/store/user/slices/auth/action.ts @@ -43,12 +43,10 @@ export const createAuthSlice: StateCreator< // TODO: 针对开启 next-auth 的场景,需要在这里调用登录方法 console.log(n('login')); - // Currently disable the condition to judge the login method - // ref: https://github.com/lobehub/lobe-chat/pull/2364 - // if (enableNextAuth) { - // TODO: 应该条件调用 next-auth 的登陆 hook - signIn(); - // } + if (enableNextAuth) { + // TODO: 应该条件调用 next-auth 的登陆 hook + signIn(); + } }, logout: async () => { if (enableClerk) { @@ -57,12 +55,11 @@ export const createAuthSlice: StateCreator< return; } - // Disable the condition, - // if (enableNextAuth) { - // TODO: 针对开启 next-auth 的场景,需要在这里调用登录方法 - console.log(n('logout')); - signOut(); - // } + if (enableNextAuth) { + // TODO: 针对开启 next-auth 的场景,需要在这里调用登录方法 + console.log(n('logout')); + signOut(); + } }, openLogin: async () => { if (enableClerk) { @@ -73,10 +70,10 @@ export const createAuthSlice: StateCreator< return; } - // if (enableNextAuth) { - // TODO: 针对开启 next-auth 的场景,需要在这里调用登录方法 - signIn(); - // } + if (enableNextAuth) { + // TODO: 针对开启 next-auth 的场景,需要在这里调用登录方法 + signIn(); + } }, openUserProfile: async () => { if (enableClerk) { From dcd2c315d3896b24b9d246b96fc1408584d883a6 Mon Sep 17 00:00:00 2001 From: cy948 Date: Mon, 6 May 2024 13:20:29 +0800 Subject: [PATCH 05/16] :memo: docs: update docs for new NextAuth env --- docs/self-hosting/advanced/authentication.mdx | 10 ++++++++++ docs/self-hosting/advanced/authentication.zh-CN.mdx | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/docs/self-hosting/advanced/authentication.mdx b/docs/self-hosting/advanced/authentication.mdx index 02570c1ffcf5..65d548c4bb82 100644 --- a/docs/self-hosting/advanced/authentication.mdx +++ b/docs/self-hosting/advanced/authentication.mdx @@ -25,6 +25,16 @@ By setting the environment variables NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY and CLERK ## Next Auth +Before using NextAuth, please set the following variables in LobeChat's environment variables: + +| Environment Variable | Type | Description | +| --- | --- | --- | +| `NEXT_PUBLIC_ENABLE_NEXT_AUTH` | Required | Enable NextAuth for LobeChat. Set to `1` to enable NextAuth. | +| `NEXT_AUTH_SECRET` | Required | The key used to encrypt Auth.js session tokens. You can use the following command: `openssl rand -base64 32`, or visit `https://generate-secret.vercel.app/32` to generate the key. | +| `ACCESS_CODE` | Required | Add a password to access this service. You can set a sufficiently long random password to "disable" access code authorization. | +| `NEXTAUTH_URL` | Optional | This URL specifies the callback address for Auth.js when performing OAuth verification. Set this only if the default generated redirect address is incorrect. `https://example.com/api/auth` | +| `NEXT_AUTH_SSO_PROVIDERS` | Optional | This environment variable is used to enable multiple identity verification sources simultaneously, separated by commas, for example, `auth0,azure-ad,authentik`. | + Currently supported identity verification services include: diff --git a/docs/self-hosting/advanced/authentication.zh-CN.mdx b/docs/self-hosting/advanced/authentication.zh-CN.mdx index 3bbd5cb91f11..50058f23234d 100644 --- a/docs/self-hosting/advanced/authentication.zh-CN.mdx +++ b/docs/self-hosting/advanced/authentication.zh-CN.mdx @@ -22,6 +22,16 @@ LobeChat 与 Clerk 做了深度集成,能够为用户提供一个更加安全 ## Next Auth +在使用 NextAuth 之前,请先在 LobeChat 的环境变量中设置以下变量: + +| 环境变量 | 类型 | 描述 | +| --- | --- | --- | +| `NEXT_PUBLIC_ENABLE_NEXT_AUTH` | 必选 | 为 LobeChat 启用 NextAuth。设置为 `1` 以启用单点登录。 | +| `NEXT_AUTH_SECRET` | 必选 | 用于加密 Auth.js 会话令牌的密钥。您可以使用以下命令: `openssl rand -base64 32`,或者访问 `https://generate-secret.vercel.app/32` 生成秘钥。 | +| `ACCESS_CODE` | 必选 | 添加访问此服务的密码,你可以设置一个足够长的随机密码以 “禁用” 访问码授权 | +| `NEXTAUTH_URL` | 可选 | 该 URL 用于指定 Auth.js 在执行 OAuth 验证时的回调地址,当默认生成的重定向地址发生不正确时才需要设置。`https://example.com/api/auth` | +| `NEXT_AUTH_SSO_PROVIDERS` | 可选 | 该环境变量用于同时启用多个身份验证源,以逗号 `,` 分割,例如 `auth0,azure-ad,authentik`。 | + 目前支持的身份验证服务有: From 5eac550c4e7742027af94c340772d00f1fbeb15a Mon Sep 17 00:00:00 2001 From: cy948 Date: Mon, 6 May 2024 14:00:32 +0800 Subject: [PATCH 06/16] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20remove?= =?UTF-8?q?=20`login`=20in=20auth=20actions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../(main)/settings/common/features/Common.tsx | 2 +- src/config/auth.ts | 5 +---- src/store/user/slices/auth/action.ts | 16 ++-------------- 3 files changed, 4 insertions(+), 19 deletions(-) diff --git a/src/app/(main)/settings/common/features/Common.tsx b/src/app/(main)/settings/common/features/Common.tsx index c46b8980d027..8ce921d0b638 100644 --- a/src/app/(main)/settings/common/features/Common.tsx +++ b/src/app/(main)/settings/common/features/Common.tsx @@ -44,7 +44,7 @@ const Common = memo(({ showAccessCodeConfig, showOAuthLogin const [setSettings, resetSettings, signIn, signOut] = useUserStore((s) => [ s.setSettings, s.resetSettings, - s.login, + s.openLogin, s.logout, ]); diff --git a/src/config/auth.ts b/src/config/auth.ts index cf1aeb25cb48..d26a1719b63f 100644 --- a/src/config/auth.ts +++ b/src/config/auth.ts @@ -113,10 +113,7 @@ export const getAuthConfig = () => { CLERK_SECRET_KEY: process.env.CLERK_SECRET_KEY, // Next Auth - NEXT_PUBLIC_ENABLE_NEXT_AUTH: - !!process.env.NEXT_PUBLIC_ENABLE_NEXT_AUTH || - !!process.env.NEXT_AUTH_SECRET || - !!process.env.ENABLE_OAUTH_SSO, + NEXT_PUBLIC_ENABLE_NEXT_AUTH: !!process.env.NEXT_PUBLIC_ENABLE_NEXT_AUTH, NEXT_AUTH_SSO_PROVIDERS: process.env.NEXT_AUTH_SSO_PROVIDERS || process.env.SSO_PROVIDERS, NEXT_AUTH_SECRET: process.env.NEXT_AUTH_SECRET, diff --git a/src/store/user/slices/auth/action.ts b/src/store/user/slices/auth/action.ts index 0d66407b2290..1520aa2c2d2b 100644 --- a/src/store/user/slices/auth/action.ts +++ b/src/store/user/slices/auth/action.ts @@ -1,4 +1,3 @@ -import { signIn, signOut } from 'next-auth/react'; import useSWR, { SWRResponse, mutate } from 'swr'; import { StateCreator } from 'zustand/vanilla'; @@ -15,7 +14,6 @@ const USER_CONFIG_FETCH_KEY = 'fetchUserConfig'; export interface UserAuthAction { getUserConfig: () => void; - login: () => Promise; /** * universal logout method */ @@ -39,15 +37,6 @@ export const createAuthSlice: StateCreator< getUserConfig: () => { console.log(n('userconfig')); }, - login: async () => { - // TODO: 针对开启 next-auth 的场景,需要在这里调用登录方法 - console.log(n('login')); - - if (enableNextAuth) { - // TODO: 应该条件调用 next-auth 的登陆 hook - signIn(); - } - }, logout: async () => { if (enableClerk) { get().clerkSignOut?.({ redirectUrl: location.toString() }); @@ -56,8 +45,7 @@ export const createAuthSlice: StateCreator< } if (enableNextAuth) { - // TODO: 针对开启 next-auth 的场景,需要在这里调用登录方法 - console.log(n('logout')); + const { signOut } = await import('next-auth/react'); signOut(); } }, @@ -71,7 +59,7 @@ export const createAuthSlice: StateCreator< } if (enableNextAuth) { - // TODO: 针对开启 next-auth 的场景,需要在这里调用登录方法 + const { signIn } = await import('next-auth/react'); signIn(); } }, From 8b692d70cdf1fd09aadab64a1e5816399dc7ff8a Mon Sep 17 00:00:00 2001 From: cy948 Date: Mon, 6 May 2024 16:13:11 +0800 Subject: [PATCH 07/16] =?UTF-8?q?=20=F0=9F=90=9Bfix:=20login=20buttion=20n?= =?UTF-8?q?ot=20shown=20on=20settings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/(main)/settings/common/index.tsx | 7 ++----- src/config/auth.ts | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/app/(main)/settings/common/index.tsx b/src/app/(main)/settings/common/index.tsx index 5017da805f48..3380ffedd521 100644 --- a/src/app/(main)/settings/common/index.tsx +++ b/src/app/(main)/settings/common/index.tsx @@ -1,5 +1,5 @@ -import { authEnv } from '@/config/auth'; import { getServerConfig } from '@/config/server'; +import { enableAuth } from '@/const/auth'; import Common from './features/Common'; import Theme from './features/Theme'; @@ -10,10 +10,7 @@ const Page = () => { return ( <> - + ); }; diff --git a/src/config/auth.ts b/src/config/auth.ts index d26a1719b63f..f14f3ad882a3 100644 --- a/src/config/auth.ts +++ b/src/config/auth.ts @@ -53,7 +53,7 @@ declare global { export const getAuthConfig = () => { if (process.env.ENABLE_OAUTH_SSO) { console.warn( - '`ENABLE_OAUTH_SSO` is deprecated and will be removed in LobeChat 1.0. just set `NEXT_AUTH_SECRET` enough', + '`ENABLE_OAUTH_SSO` is deprecated and will be removed in LobeChat 1.0. Please set `NEXT_PUBLIC_ENABLE_NEXT_AUTH` instead.', ); } From 0eaf64bd65627fc7ed862ab8efc9f629b8a70b00 Mon Sep 17 00:00:00 2001 From: cy948 Date: Mon, 6 May 2024 18:10:58 +0800 Subject: [PATCH 08/16] :white_check_mark: test: hooks in auth actions --- src/store/user/slices/auth/action.test.ts | 61 +++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/src/store/user/slices/auth/action.test.ts b/src/store/user/slices/auth/action.test.ts index eaba91fa5b50..fed43eaa5889 100644 --- a/src/store/user/slices/auth/action.test.ts +++ b/src/store/user/slices/auth/action.test.ts @@ -43,6 +43,16 @@ afterEach(() => { enableClerk = false; }); +/** + * Mock nextauth 库相关方法 + */ +vi.mock('next-auth/react', async () => { + return { + signIn: vi.fn(), + signOut: vi.fn(), + }; +}); + describe('createAuthSlice', () => { describe('refreshUserConfig', () => { it('should refresh user config', async () => { @@ -162,6 +172,32 @@ describe('createAuthSlice', () => { expect(clerkSignOutMock).not.toHaveBeenCalled(); }); + + it('should call next-auth signOut when NextAuth is enabled', async () => { + enableNextAuth = true; + + const { result } = renderHook(() => useUserStore()); + + await act(async () => { + await result.current.logout(); + }); + + const { signOut } = await import('next-auth/react'); + + expect(signOut).toHaveBeenCalled(); + }); + + it('should not call next-auth signOut when NextAuth is disabled', async () => { + const { result } = renderHook(() => useUserStore()); + + await act(async () => { + await result.current.logout(); + }); + + const { signOut } = await import('next-auth/react'); + + expect(signOut).not.toHaveBeenCalled(); + }); }); describe('openLogin', () => { @@ -190,6 +226,31 @@ describe('createAuthSlice', () => { expect(clerkSignInMock).not.toHaveBeenCalled(); }); + + it('should call next-auth signIn when NextAuth is enabled', async () => { + enableNextAuth = true; + + const { result } = renderHook(() => useUserStore()); + + await act(async () => { + await result.current.openLogin(); + }); + + const { signIn } = await import('next-auth/react'); + + expect(signIn).toHaveBeenCalled(); + }); + it('should not call next-auth signIn when NextAuth is disabled', async () => { + const { result } = renderHook(() => useUserStore()); + + await act(async () => { + await result.current.openLogin(); + }); + + const { signIn } = await import('next-auth/react'); + + expect(signIn).not.toHaveBeenCalled(); + }); }); describe('openUserProfile', () => { From e1a5fec825310ac4f89e46b791f1d211d7430083 Mon Sep 17 00:00:00 2001 From: cy948 Date: Mon, 6 May 2024 23:37:36 +0800 Subject: [PATCH 09/16] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20change?= =?UTF-8?q?=20button=20show=20condition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/(main)/settings/common/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/(main)/settings/common/index.tsx b/src/app/(main)/settings/common/index.tsx index 3380ffedd521..2314656d5ccc 100644 --- a/src/app/(main)/settings/common/index.tsx +++ b/src/app/(main)/settings/common/index.tsx @@ -1,5 +1,5 @@ import { getServerConfig } from '@/config/server'; -import { enableAuth } from '@/const/auth'; +import { enableNextAuth } from '@/const/auth'; import Common from './features/Common'; import Theme from './features/Theme'; @@ -10,7 +10,7 @@ const Page = () => { return ( <> - + ); }; From ce7491c032ffbff579fb638fe49c7362b2eb3f2c Mon Sep 17 00:00:00 2001 From: cy948 Date: Wed, 8 May 2024 19:19:23 +0800 Subject: [PATCH 10/16] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20use=20se?= =?UTF-8?q?rver=20config=20to=20show=20oauth=20button?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/(main)/settings/common/index.tsx | 9 +++++---- src/server/globalConfig/index.ts | 2 ++ src/store/serverConfig/selectors.ts | 1 + src/types/serverConfig.ts | 1 + 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/app/(main)/settings/common/index.tsx b/src/app/(main)/settings/common/index.tsx index 2314656d5ccc..6a8fe54b263f 100644 --- a/src/app/(main)/settings/common/index.tsx +++ b/src/app/(main)/settings/common/index.tsx @@ -1,16 +1,17 @@ -import { getServerConfig } from '@/config/server'; -import { enableNextAuth } from '@/const/auth'; +import { useServerConfigStore } from '@/store/serverConfig'; +import { serverConfigSelectors } from '@/store/serverConfig/selectors'; import Common from './features/Common'; import Theme from './features/Theme'; const Page = () => { - const { SHOW_ACCESS_CODE_CONFIG } = getServerConfig(); + const isEnableAccessCode = useServerConfigStore(serverConfigSelectors.enabledAccessCode); + const isEnabledOAuth = useServerConfigStore(serverConfigSelectors.enabledOAuthSSO); return ( <> - + ); }; diff --git a/src/server/globalConfig/index.ts b/src/server/globalConfig/index.ts index f95d36f14654..ee0ad9becbff 100644 --- a/src/server/globalConfig/index.ts +++ b/src/server/globalConfig/index.ts @@ -13,6 +13,7 @@ import { parseAgentConfig } from './parseDefaultAgent'; export const getServerGlobalConfig = () => { const { + ACCESS_CODES, ENABLE_LANGFUSE, DEFAULT_AGENT_CONFIG, @@ -48,6 +49,7 @@ export const getServerGlobalConfig = () => { config: parseAgentConfig(DEFAULT_AGENT_CONFIG), }, + enabledAccessCode: ACCESS_CODES?.length > 0, enabledOAuthSSO: enableNextAuth, languageModel: { anthropic: { diff --git a/src/store/serverConfig/selectors.ts b/src/store/serverConfig/selectors.ts index 8d2e3130ae3b..b4be747c7f4d 100644 --- a/src/store/serverConfig/selectors.ts +++ b/src/store/serverConfig/selectors.ts @@ -6,6 +6,7 @@ export const featureFlagsSelectors = (s: ServerConfigStore) => mapFeatureFlagsEnvToState(s.featureFlags); export const serverConfigSelectors = { + enabledAccessCode: (s: ServerConfigStore) => !!s.serverConfig?.enabledAccessCode, enabledOAuthSSO: (s: ServerConfigStore) => s.serverConfig.enabledOAuthSSO, enabledTelemetryChat: (s: ServerConfigStore) => s.serverConfig.telemetry.langfuse || false, isMobile: (s: ServerConfigStore) => s.isMobile || false, diff --git a/src/types/serverConfig.ts b/src/types/serverConfig.ts index 031e88e772b2..0e90b4af9373 100644 --- a/src/types/serverConfig.ts +++ b/src/types/serverConfig.ts @@ -15,6 +15,7 @@ export interface ServerModelProviderConfig { export interface GlobalServerConfig { defaultAgent?: DeepPartial; + enabledAccessCode?: boolean; enabledOAuthSSO?: boolean; languageModel?: Partial>; telemetry: { From 17cc3ee314b52d22c638424c4e01d1975436cc2b Mon Sep 17 00:00:00 2001 From: cy948 Date: Wed, 8 May 2024 21:03:34 +0800 Subject: [PATCH 11/16] =?UTF-8?q?=F0=9F=90=9Bfix:=20context=20error=20in?= =?UTF-8?q?=20settings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/(main)/settings/common/features/Common.tsx | 11 +++++------ src/app/(main)/settings/common/index.tsx | 8 +------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/app/(main)/settings/common/features/Common.tsx b/src/app/(main)/settings/common/features/Common.tsx index 8ce921d0b638..7a68e32d8e8e 100644 --- a/src/app/(main)/settings/common/features/Common.tsx +++ b/src/app/(main)/settings/common/features/Common.tsx @@ -11,6 +11,8 @@ import { FORM_STYLE } from '@/const/layoutTokens'; import { DEFAULT_SETTINGS } from '@/const/settings'; import { useChatStore } from '@/store/chat'; import { useFileStore } from '@/store/file'; +import { useServerConfigStore } from '@/store/serverConfig'; +import { serverConfigSelectors } from '@/store/serverConfig/selectors'; import { useSessionStore } from '@/store/session'; import { useToolStore } from '@/store/tool'; import { useUserStore } from '@/store/user'; @@ -18,16 +20,13 @@ import { settingsSelectors, userProfileSelectors } from '@/store/user/selectors' type SettingItemGroup = ItemGroup; -export interface SettingsCommonProps { - showAccessCodeConfig: boolean; - showOAuthLogin?: boolean; -} - -const Common = memo(({ showAccessCodeConfig, showOAuthLogin }) => { +const Common = memo(() => { const { t } = useTranslation('setting'); const [form] = Form.useForm(); const isSignedIn = useUserStore((s) => s.isSignedIn); + const showAccessCodeConfig = useServerConfigStore(serverConfigSelectors.enabledAccessCode); + const showOAuthLogin = useServerConfigStore(serverConfigSelectors.enabledOAuthSSO); const user = useUserStore(userProfileSelectors.userProfile, isEqual); const [clearSessions, clearSessionGroups] = useSessionStore((s) => [ diff --git a/src/app/(main)/settings/common/index.tsx b/src/app/(main)/settings/common/index.tsx index 6a8fe54b263f..5cd7510c01c7 100644 --- a/src/app/(main)/settings/common/index.tsx +++ b/src/app/(main)/settings/common/index.tsx @@ -1,17 +1,11 @@ -import { useServerConfigStore } from '@/store/serverConfig'; -import { serverConfigSelectors } from '@/store/serverConfig/selectors'; - import Common from './features/Common'; import Theme from './features/Theme'; const Page = () => { - const isEnableAccessCode = useServerConfigStore(serverConfigSelectors.enabledAccessCode); - const isEnabledOAuth = useServerConfigStore(serverConfigSelectors.enabledOAuthSSO); - return ( <> - + ); }; From d8da7f816b8439199f6f2b6a0dca977cd2235289 Mon Sep 17 00:00:00 2001 From: cy948 Date: Fri, 10 May 2024 19:36:20 +0800 Subject: [PATCH 12/16] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20use=20se?= =?UTF-8?q?rver=20config=20store=20to=20enable=20auth?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/self-hosting/advanced/authentication.mdx | 1 - .../advanced/authentication.zh-CN.mdx | 1 - src/config/auth.ts | 3 ++- .../User/__tests__/UserAvatar.test.tsx | 11 +++++++--- src/store/user/slices/auth/action.test.ts | 4 ++-- src/store/user/slices/auth/action.ts | 17 +++++++++++++--- src/store/user/slices/auth/selectors.test.ts | 20 +++++++++++++++++-- src/store/user/slices/auth/selectors.ts | 7 +++---- 8 files changed, 47 insertions(+), 17 deletions(-) diff --git a/docs/self-hosting/advanced/authentication.mdx b/docs/self-hosting/advanced/authentication.mdx index 65d548c4bb82..c8517740365f 100644 --- a/docs/self-hosting/advanced/authentication.mdx +++ b/docs/self-hosting/advanced/authentication.mdx @@ -29,7 +29,6 @@ Before using NextAuth, please set the following variables in LobeChat's environm | Environment Variable | Type | Description | | --- | --- | --- | -| `NEXT_PUBLIC_ENABLE_NEXT_AUTH` | Required | Enable NextAuth for LobeChat. Set to `1` to enable NextAuth. | | `NEXT_AUTH_SECRET` | Required | The key used to encrypt Auth.js session tokens. You can use the following command: `openssl rand -base64 32`, or visit `https://generate-secret.vercel.app/32` to generate the key. | | `ACCESS_CODE` | Required | Add a password to access this service. You can set a sufficiently long random password to "disable" access code authorization. | | `NEXTAUTH_URL` | Optional | This URL specifies the callback address for Auth.js when performing OAuth verification. Set this only if the default generated redirect address is incorrect. `https://example.com/api/auth` | diff --git a/docs/self-hosting/advanced/authentication.zh-CN.mdx b/docs/self-hosting/advanced/authentication.zh-CN.mdx index 50058f23234d..df69d357f6d4 100644 --- a/docs/self-hosting/advanced/authentication.zh-CN.mdx +++ b/docs/self-hosting/advanced/authentication.zh-CN.mdx @@ -26,7 +26,6 @@ LobeChat 与 Clerk 做了深度集成,能够为用户提供一个更加安全 | 环境变量 | 类型 | 描述 | | --- | --- | --- | -| `NEXT_PUBLIC_ENABLE_NEXT_AUTH` | 必选 | 为 LobeChat 启用 NextAuth。设置为 `1` 以启用单点登录。 | | `NEXT_AUTH_SECRET` | 必选 | 用于加密 Auth.js 会话令牌的密钥。您可以使用以下命令: `openssl rand -base64 32`,或者访问 `https://generate-secret.vercel.app/32` 生成秘钥。 | | `ACCESS_CODE` | 必选 | 添加访问此服务的密码,你可以设置一个足够长的随机密码以 “禁用” 访问码授权 | | `NEXTAUTH_URL` | 可选 | 该 URL 用于指定 Auth.js 在执行 OAuth 验证时的回调地址,当默认生成的重定向地址发生不正确时才需要设置。`https://example.com/api/auth` | diff --git a/src/config/auth.ts b/src/config/auth.ts index f14f3ad882a3..0bc2dd5a134a 100644 --- a/src/config/auth.ts +++ b/src/config/auth.ts @@ -113,7 +113,8 @@ export const getAuthConfig = () => { CLERK_SECRET_KEY: process.env.CLERK_SECRET_KEY, // Next Auth - NEXT_PUBLIC_ENABLE_NEXT_AUTH: !!process.env.NEXT_PUBLIC_ENABLE_NEXT_AUTH, + NEXT_PUBLIC_ENABLE_NEXT_AUTH: + !!process.env.NEXT_AUTH_SECRET || !!process.env.ENABLE_OAUTH_SSO, NEXT_AUTH_SSO_PROVIDERS: process.env.NEXT_AUTH_SSO_PROVIDERS || process.env.SSO_PROVIDERS, NEXT_AUTH_SECRET: process.env.NEXT_AUTH_SECRET, diff --git a/src/features/User/__tests__/UserAvatar.test.tsx b/src/features/User/__tests__/UserAvatar.test.tsx index 18e5ada92bb2..5052c35bc84d 100644 --- a/src/features/User/__tests__/UserAvatar.test.tsx +++ b/src/features/User/__tests__/UserAvatar.test.tsx @@ -30,6 +30,7 @@ describe('UserAvatar', () => { act(() => { useUserStore.setState({ + enableAuth: () => true, isSignedIn: true, user: { avatar: mockAvatar, id: 'abc', username: mockUsername }, }); @@ -45,7 +46,11 @@ describe('UserAvatar', () => { const mockUsername = 'testuser'; act(() => { - useUserStore.setState({ isSignedIn: true, user: { id: 'bbb', username: mockUsername } }); + useUserStore.setState({ + enableAuth: () => true, + isSignedIn: true, + user: { id: 'bbb', username: mockUsername }, + }); }); render(); @@ -54,7 +59,7 @@ describe('UserAvatar', () => { it('should show LobeChat and default avatar when the user is not logged in and enable auth', () => { act(() => { - useUserStore.setState({ isSignedIn: false, user: undefined }); + useUserStore.setState({ enableAuth: () => true, isSignedIn: false, user: undefined }); }); render(); @@ -67,7 +72,7 @@ describe('UserAvatar', () => { it('should show LobeChat and default avatar when the user is not logged in and disabled auth', () => { enableAuth = false; act(() => { - useUserStore.setState({ isSignedIn: false, user: undefined }); + useUserStore.setState({ enableAuth: () => false, isSignedIn: false, user: undefined }); }); render(); diff --git a/src/store/user/slices/auth/action.test.ts b/src/store/user/slices/auth/action.test.ts index fed43eaa5889..dc1866a9d63d 100644 --- a/src/store/user/slices/auth/action.test.ts +++ b/src/store/user/slices/auth/action.test.ts @@ -174,7 +174,7 @@ describe('createAuthSlice', () => { }); it('should call next-auth signOut when NextAuth is enabled', async () => { - enableNextAuth = true; + useUserStore.setState({ enabledNextAuth: () => true }); const { result } = renderHook(() => useUserStore()); @@ -228,7 +228,7 @@ describe('createAuthSlice', () => { }); it('should call next-auth signIn when NextAuth is enabled', async () => { - enableNextAuth = true; + useUserStore.setState({ enabledNextAuth: () => true }); const { result } = renderHook(() => useUserStore()); diff --git a/src/store/user/slices/auth/action.ts b/src/store/user/slices/auth/action.ts index 1520aa2c2d2b..6b2f58761b89 100644 --- a/src/store/user/slices/auth/action.ts +++ b/src/store/user/slices/auth/action.ts @@ -1,7 +1,7 @@ import useSWR, { SWRResponse, mutate } from 'swr'; import { StateCreator } from 'zustand/vanilla'; -import { enableClerk, enableNextAuth } from '@/const/auth'; +import { enableClerk } from '@/const/auth'; import { UserConfig, userService } from '@/services/user'; import { switchLang } from '@/utils/client/switchLang'; import { setNamespace } from '@/utils/storeDebug'; @@ -13,6 +13,8 @@ const n = setNamespace('auth'); const USER_CONFIG_FETCH_KEY = 'fetchUserConfig'; export interface UserAuthAction { + enableAuth: () => boolean; + enabledNextAuth: () => boolean; getUserConfig: () => void; /** * universal logout method @@ -23,8 +25,8 @@ export interface UserAuthAction { */ openLogin: () => Promise; openUserProfile: () => Promise; - refreshUserConfig: () => Promise; + refreshUserConfig: () => Promise; useFetchUserConfig: (initServer: boolean) => SWRResponse; } @@ -34,6 +36,12 @@ export const createAuthSlice: StateCreator< [], UserAuthAction > = (set, get) => ({ + enableAuth: () => { + return enableClerk || get()?.enabledNextAuth(); + }, + enabledNextAuth: () => { + return !!get()?.serverConfig.enabledOAuthSSO; + }, getUserConfig: () => { console.log(n('userconfig')); }, @@ -44,6 +52,7 @@ export const createAuthSlice: StateCreator< return; } + const enableNextAuth = get().enabledNextAuth(); if (enableNextAuth) { const { signOut } = await import('next-auth/react'); signOut(); @@ -58,11 +67,13 @@ export const createAuthSlice: StateCreator< return; } + const enableNextAuth = get().enabledNextAuth(); if (enableNextAuth) { const { signIn } = await import('next-auth/react'); signIn(); } }, + openUserProfile: async () => { if (enableClerk) { get().clerkOpenUserProfile?.(); @@ -70,6 +81,7 @@ export const createAuthSlice: StateCreator< return; } + const enableNextAuth = get().enabledNextAuth(); if (enableNextAuth) { // TODO: 针对开启 next-auth 的场景,需要在这里调用打开 profile 页 // NextAuht 没有 profile 页,未来应该隐藏 Profile Button @@ -81,7 +93,6 @@ export const createAuthSlice: StateCreator< // when get the user config ,refresh the model provider list to the latest get().refreshModelProviderList(); }, - useFetchUserConfig: (initServer) => useSWR( [USER_CONFIG_FETCH_KEY, initServer], diff --git a/src/store/user/slices/auth/selectors.test.ts b/src/store/user/slices/auth/selectors.test.ts index b3b95de3f2e8..0faed5cc2c0c 100644 --- a/src/store/user/slices/auth/selectors.test.ts +++ b/src/store/user/slices/auth/selectors.test.ts @@ -31,6 +31,7 @@ describe('userProfileSelectors', () => { const store: UserStore = { isSignedIn: false, user: null, + enableAuth: () => false, } as unknown as UserStore; expect(userProfileSelectors.nickName(store)).toBe('userPanel.defaultNickname'); @@ -43,6 +44,7 @@ describe('userProfileSelectors', () => { const store: UserStore = { isSignedIn: true, user: { fullName: 'John Doe' }, + enableAuth: () => true, } as UserStore; expect(userProfileSelectors.nickName(store)).toBe('John Doe'); @@ -52,6 +54,7 @@ describe('userProfileSelectors', () => { const store: UserStore = { isSignedIn: true, user: { username: 'johndoe' }, + enableAuth: () => true, } as UserStore; expect(userProfileSelectors.nickName(store)).toBe('johndoe'); @@ -60,7 +63,11 @@ describe('userProfileSelectors', () => { it('should return anonymous nickname when not signed in', () => { enableAuth = true; - const store: UserStore = { isSignedIn: false, user: null } as unknown as UserStore; + const store: UserStore = { + enableAuth: () => true, + isSignedIn: false, + user: null, + } as unknown as UserStore; expect(userProfileSelectors.nickName(store)).toBe('userPanel.anonymousNickName'); expect(t).toHaveBeenCalledWith('userPanel.anonymousNickName', { ns: 'common' }); @@ -74,6 +81,7 @@ describe('userProfileSelectors', () => { const store: UserStore = { isSignedIn: false, user: null, + enableAuth: () => false, } as unknown as UserStore; expect(userProfileSelectors.username(store)).toBe('LobeChat'); @@ -83,13 +91,18 @@ describe('userProfileSelectors', () => { const store: UserStore = { isSignedIn: true, user: { username: 'johndoe' }, + enableAuth: () => true, } as UserStore; expect(userProfileSelectors.username(store)).toBe('johndoe'); }); it('should return "anonymous" when not signed in', () => { - const store: UserStore = { isSignedIn: false, user: null } as unknown as UserStore; + const store: UserStore = { + enableAuth: () => true, + isSignedIn: false, + user: null, + } as unknown as UserStore; expect(userProfileSelectors.username(store)).toBe('anonymous'); }); @@ -103,6 +116,7 @@ describe('authSelectors', () => { const store: UserStore = { isSignedIn: false, + enableAuth: () => false, } as UserStore; expect(authSelectors.isLogin(store)).toBe(true); @@ -111,6 +125,7 @@ describe('authSelectors', () => { it('should return true when signed in', () => { const store: UserStore = { isSignedIn: true, + enableAuth: () => true, } as UserStore; expect(authSelectors.isLogin(store)).toBe(true); @@ -119,6 +134,7 @@ describe('authSelectors', () => { it('should return false when not signed in and auth is enabled', () => { const store: UserStore = { isSignedIn: false, + enableAuth: () => true, } as UserStore; expect(authSelectors.isLogin(store)).toBe(false); diff --git a/src/store/user/slices/auth/selectors.ts b/src/store/user/slices/auth/selectors.ts index f550d4a86e82..b52efffce753 100644 --- a/src/store/user/slices/auth/selectors.ts +++ b/src/store/user/slices/auth/selectors.ts @@ -1,13 +1,12 @@ import { t } from 'i18next'; -import { enableAuth } from '@/const/auth'; import { UserStore } from '@/store/user'; import { LobeUser } from '@/types/user'; const DEFAULT_USERNAME = 'LobeChat'; const nickName = (s: UserStore) => { - if (!enableAuth) return t('userPanel.defaultNickname', { ns: 'common' }); + if (!s.enableAuth()) return t('userPanel.defaultNickname', { ns: 'common' }); if (s.isSignedIn) return s.user?.fullName || s.user?.username; @@ -15,7 +14,7 @@ const nickName = (s: UserStore) => { }; const username = (s: UserStore) => { - if (!enableAuth) return DEFAULT_USERNAME; + if (!s.enableAuth()) return DEFAULT_USERNAME; if (s.isSignedIn) return s.user?.username; @@ -35,7 +34,7 @@ export const userProfileSelectors = { */ const isLogin = (s: UserStore) => { // 如果没有开启鉴权,说明不需要登录,默认是登录态 - if (!enableAuth) return true; + if (!s.enableAuth()) return true; return s.isSignedIn; }; From dde83fc9f7340c929a05b786a19902694397b739 Mon Sep 17 00:00:00 2001 From: cy948 Date: Sun, 12 May 2024 10:50:53 +0800 Subject: [PATCH 13/16] :speech_balloon: refactor: remove tips --- src/config/auth.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/auth.ts b/src/config/auth.ts index 0bc2dd5a134a..0a90cfbcdbc8 100644 --- a/src/config/auth.ts +++ b/src/config/auth.ts @@ -53,7 +53,7 @@ declare global { export const getAuthConfig = () => { if (process.env.ENABLE_OAUTH_SSO) { console.warn( - '`ENABLE_OAUTH_SSO` is deprecated and will be removed in LobeChat 1.0. Please set `NEXT_PUBLIC_ENABLE_NEXT_AUTH` instead.', + '`ENABLE_OAUTH_SSO` is deprecated and will be removed in LobeChat 1.0. just set `NEXT_AUTH_SECRET` enough', ); } From 23a3a13000f626bee6d3cf61c4e596e3b97532fe Mon Sep 17 00:00:00 2001 From: cy948 Date: Sun, 12 May 2024 10:59:29 +0800 Subject: [PATCH 14/16] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20remove?= =?UTF-8?q?=20env=20`NEXT=5FPUBLIC=5FENABLE=5FNEXT=5FAUTH`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config/auth.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/config/auth.ts b/src/config/auth.ts index 0a90cfbcdbc8..9e67600a9622 100644 --- a/src/config/auth.ts +++ b/src/config/auth.ts @@ -16,7 +16,6 @@ declare global { * @deprecated */ ENABLE_OAUTH_SSO?: string; - NEXT_PUBLIC_ENABLE_NEXT_AUTH?: string; NEXT_AUTH_SECRET?: string; /** * @deprecated From d5a07d495650dcabec4b96b920cbe80865298367 Mon Sep 17 00:00:00 2001 From: cy948 Date: Mon, 13 May 2024 23:12:15 +0800 Subject: [PATCH 15/16] :fire: refactor: remove open profile in store auth actions --- src/store/user/slices/auth/action.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/store/user/slices/auth/action.ts b/src/store/user/slices/auth/action.ts index 6b2f58761b89..24b2080c9967 100644 --- a/src/store/user/slices/auth/action.ts +++ b/src/store/user/slices/auth/action.ts @@ -80,12 +80,6 @@ export const createAuthSlice: StateCreator< return; } - - const enableNextAuth = get().enabledNextAuth(); - if (enableNextAuth) { - // TODO: 针对开启 next-auth 的场景,需要在这里调用打开 profile 页 - // NextAuht 没有 profile 页,未来应该隐藏 Profile Button - } }, refreshUserConfig: async () => { await mutate([USER_CONFIG_FETCH_KEY, true]); From 4006a59d25a16fdd11e9999f1e70462e5a48a2b7 Mon Sep 17 00:00:00 2001 From: cy948 Date: Mon, 13 May 2024 23:23:26 +0800 Subject: [PATCH 16/16] :white_check_mark: test(useMenu): change states --- src/features/User/__tests__/useMenu.test.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/features/User/__tests__/useMenu.test.tsx b/src/features/User/__tests__/useMenu.test.tsx index c186ae831c44..9ec0377df96e 100644 --- a/src/features/User/__tests__/useMenu.test.tsx +++ b/src/features/User/__tests__/useMenu.test.tsx @@ -64,7 +64,7 @@ afterEach(() => { describe('useMenu', () => { it('should provide correct menu items when user is logged in with auth', () => { act(() => { - useUserStore.setState({ isSignedIn: true }); + useUserStore.setState({ isSignedIn: true, enableAuth: () => true }); }); enableAuth = true; enableClerk = false; @@ -104,7 +104,7 @@ describe('useMenu', () => { it('should provide correct menu items when user is logged in without auth', () => { act(() => { - useUserStore.setState({ isSignedIn: false }); + useUserStore.setState({ isSignedIn: false, enableAuth: () => false }); }); enableAuth = false; @@ -123,7 +123,7 @@ describe('useMenu', () => { it('should provide correct menu items when user is not logged in', () => { act(() => { - useUserStore.setState({ isSignedIn: false }); + useUserStore.setState({ isSignedIn: false, enableAuth: () => true }); }); enableAuth = true;