@lobehub/lobehub 2.0.0-next.343 → 2.0.0-next.345

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/.cursor/rules/i18n.mdc +1 -1
  2. package/.cursor/rules/modal-imperative.mdc +162 -0
  3. package/.cursor/rules/rules-index.mdc +1 -0
  4. package/.env.example +0 -14
  5. package/.eslintrc.js +8 -1
  6. package/CHANGELOG.md +66 -0
  7. package/Dockerfile +3 -13
  8. package/README.md +3 -5
  9. package/README.zh-CN.md +3 -5
  10. package/changelog/v1.json +24 -0
  11. package/docs/self-hosting/advanced/auth/clerk-to-betterauth.mdx +11 -42
  12. package/docs/self-hosting/advanced/auth/clerk-to-betterauth.zh-CN.mdx +10 -41
  13. package/e2e/src/support/webServer.ts +2 -0
  14. package/locales/ar/error.json +0 -4
  15. package/locales/bg-BG/error.json +0 -4
  16. package/locales/de-DE/error.json +0 -4
  17. package/locales/en-US/error.json +0 -4
  18. package/locales/es-ES/error.json +0 -4
  19. package/locales/fa-IR/error.json +0 -4
  20. package/locales/fr-FR/error.json +0 -4
  21. package/locales/it-IT/error.json +0 -4
  22. package/locales/ja-JP/error.json +0 -4
  23. package/locales/ko-KR/error.json +0 -4
  24. package/locales/nl-NL/error.json +0 -4
  25. package/locales/pl-PL/error.json +0 -4
  26. package/locales/pt-BR/error.json +0 -4
  27. package/locales/ru-RU/error.json +0 -4
  28. package/locales/tr-TR/error.json +0 -4
  29. package/locales/vi-VN/error.json +0 -4
  30. package/locales/zh-CN/error.json +0 -4
  31. package/locales/zh-TW/error.json +0 -4
  32. package/package.json +7 -9
  33. package/packages/builtin-agents/package.json +2 -0
  34. package/packages/builtin-agents/src/agents/agent-builder/index.ts +4 -2
  35. package/packages/builtin-agents/src/agents/group-agent-builder/index.ts +4 -2
  36. package/packages/builtin-agents/src/agents/page-agent/index.ts +5 -2
  37. package/packages/builtin-tool-cloud-sandbox/src/ExecutionRuntime/index.ts +161 -12
  38. package/packages/context-engine/src/engine/messages/MessagesEngine.ts +9 -9
  39. package/packages/context-engine/src/providers/GroupContextInjector.ts +19 -33
  40. package/packages/context-engine/src/providers/__tests__/GroupContextInjector.test.ts +79 -43
  41. package/packages/context-engine/src/providers/__tests__/__snapshots__/GroupContextInjector.test.ts.snap +5 -15
  42. package/packages/database/src/repositories/userMemory/__tests__/UserMemoryTopicRepository.test.ts +24 -3
  43. package/packages/model-bank/src/modelProviders/comfyui.ts +0 -1
  44. package/packages/model-bank/src/modelProviders/fal.ts +0 -1
  45. package/packages/types/src/fetch.ts +1 -2
  46. package/packages/utils/src/server/__tests__/auth.test.ts +0 -47
  47. package/packages/utils/src/server/auth.ts +1 -9
  48. package/scripts/_shared/checkDeprecatedClerkEnv.js +42 -0
  49. package/scripts/changelogWorkflow/buildStaticChangelog.ts +2 -1
  50. package/scripts/clerk-to-betterauth/_internal/types.ts +53 -20
  51. package/scripts/clerk-to-betterauth/export-clerk-users-with-api.ts +43 -36
  52. package/scripts/countEnWord.ts +1 -1
  53. package/scripts/electronWorkflow/modifiers/appCode.mts +2 -131
  54. package/scripts/i18nWorkflow/protectedPatterns.ts +1 -2
  55. package/scripts/prebuild.mts +10 -8
  56. package/scripts/serverLauncher/startServer.js +23 -5
  57. package/src/app/(backend)/middleware/auth/index.test.ts +8 -4
  58. package/src/app/(backend)/middleware/auth/index.ts +0 -15
  59. package/src/app/(backend)/middleware/auth/utils.test.ts +0 -28
  60. package/src/app/(backend)/middleware/auth/utils.ts +2 -17
  61. package/src/app/(backend)/webapi/chat/[provider]/route.test.ts +3 -51
  62. package/src/app/(backend)/webapi/models/[provider]/route.test.ts +8 -4
  63. package/src/app/[variants]/(auth)/next-auth/signin/AuthSignInBox.tsx +7 -6
  64. package/src/app/[variants]/(auth)/signup/[[...signup]]/page.tsx +1 -16
  65. package/src/app/[variants]/(main)/home/_layout/Body/Agent/List/index.tsx +1 -1
  66. package/src/app/[variants]/(main)/home/features/InputArea/SkillInstallBanner.tsx +13 -13
  67. package/src/app/[variants]/(main)/home/features/RecentPage/Item.tsx +2 -2
  68. package/src/app/[variants]/(main)/settings/hooks/useCategory.tsx +3 -21
  69. package/src/app/[variants]/(main)/settings/profile/features/AvatarRow.tsx +1 -2
  70. package/src/app/[variants]/(main)/settings/security/index.tsx +1 -22
  71. package/src/app/[variants]/(main)/settings/skill/features/KlavisSkillItem.tsx +12 -14
  72. package/src/app/[variants]/(main)/settings/skill/features/LobehubSkillItem.tsx +8 -14
  73. package/src/app/[variants]/(main)/settings/skill/index.tsx +7 -5
  74. package/src/app/[variants]/(mobile)/me/(home)/__tests__/UserBanner.test.tsx +2 -35
  75. package/src/app/[variants]/(mobile)/me/(home)/__tests__/useCategory.test.tsx +0 -20
  76. package/src/app/[variants]/(mobile)/me/(home)/features/UserBanner.tsx +1 -2
  77. package/src/app/[variants]/(mobile)/me/profile/features/Category.tsx +3 -13
  78. package/src/app/[variants]/(mobile)/settings/_layout/Header.tsx +2 -3
  79. package/src/app/[variants]/share/t/[id]/_layout/index.tsx +1 -1
  80. package/src/app/[variants]/share/t/[id]/index.tsx +1 -1
  81. package/src/app/robots.tsx +1 -1
  82. package/src/envs/auth.ts +2 -27
  83. package/src/envs/llm.ts +2 -2
  84. package/src/features/AgentSetting/AgentPlugin/index.tsx +9 -12
  85. package/src/features/ChatInput/ActionBar/Tools/index.tsx +7 -5
  86. package/src/features/ChatMiniMap/utils.ts +1 -1
  87. package/src/features/CommandMenu/SearchResults.tsx +1 -1
  88. package/src/features/Conversation/ChatList/components/AutoScroll/DebugInspector.tsx +166 -0
  89. package/src/features/Conversation/ChatList/components/AutoScroll/index.tsx +86 -0
  90. package/src/features/Conversation/ChatList/components/VirtualizedList.tsx +11 -17
  91. package/src/features/Conversation/Messages/AgentCouncil/components/AutoScrollShadow.tsx +25 -14
  92. package/src/features/Conversation/Messages/AgentCouncil/components/CouncilMember.tsx +1 -1
  93. package/src/features/IntegrationDetailModal/IntegrationDetailContent.tsx +305 -0
  94. package/src/features/IntegrationDetailModal/index.tsx +21 -283
  95. package/src/features/MCPPluginDetail/Deployment/index.tsx +1 -1
  96. package/src/features/MCPPluginDetail/Schema/Prompts.tsx +1 -1
  97. package/src/features/MCPPluginDetail/Schema/Tools.tsx +1 -1
  98. package/src/features/ProfileEditor/AgentTool.tsx +14 -20
  99. package/src/features/ResourceManager/components/Explorer/MasonryView/MasonryFileItem/NoteFileItem.tsx +1 -1
  100. package/src/features/SkillStore/LobeHubList/index.tsx +50 -87
  101. package/src/features/SkillStore/Search/index.tsx +1 -1
  102. package/src/features/SkillStore/{Content.tsx → SkillStoreContent.tsx} +3 -8
  103. package/src/features/SkillStore/index.tsx +15 -33
  104. package/src/features/User/UserPanel/PanelContent.tsx +0 -8
  105. package/src/features/User/__tests__/PanelContent.test.tsx +1 -35
  106. package/src/features/User/__tests__/UserAvatar.test.tsx +30 -57
  107. package/src/features/User/__tests__/useMenu.test.tsx +2 -43
  108. package/src/layout/AuthProvider/index.tsx +0 -5
  109. package/src/libs/next/config/define-config.ts +6 -0
  110. package/src/libs/next/proxy/createRouteMatcher.test.ts +121 -0
  111. package/src/libs/next/proxy/createRouteMatcher.ts +18 -0
  112. package/src/libs/next/proxy/define-config.ts +4 -53
  113. package/src/libs/next-auth/adapter/index.ts +1 -2
  114. package/src/libs/oidc-provider/provider.test.ts +5 -316
  115. package/src/libs/trpc/lambda/context.test.ts +0 -13
  116. package/src/libs/trpc/lambda/context.ts +3 -22
  117. package/src/libs/trpc/middleware/userAuth.ts +2 -4
  118. package/src/libs/trusted-client/getSessionUser.ts +2 -17
  119. package/src/locales/default/error.ts +0 -6
  120. package/src/locales/default/index.ts +0 -2
  121. package/src/proxy.ts +0 -1
  122. package/src/server/routers/lambda/__tests__/user.test.ts +0 -71
  123. package/src/server/routers/lambda/user.ts +6 -63
  124. package/src/server/services/changelog/index.test.ts +3 -2
  125. package/src/server/services/changelog/index.ts +1 -1
  126. package/src/server/services/user/index.ts +0 -83
  127. package/src/services/chat/index.ts +1 -2
  128. package/src/services/chat/mecha/agentConfigResolver.test.ts +43 -0
  129. package/src/services/chat/mecha/agentConfigResolver.ts +3 -1
  130. package/src/store/chat/slices/aiChat/actions/__tests__/streamingExecutor.test.ts +58 -14
  131. package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +10 -2
  132. package/src/store/user/slices/auth/action.test.ts +1 -81
  133. package/src/store/user/slices/auth/action.ts +3 -28
  134. package/src/store/user/slices/auth/initialState.ts +1 -18
  135. package/src/store/user/slices/auth/selectors.test.ts +2 -127
  136. package/src/store/user/slices/auth/selectors.ts +1 -21
  137. package/src/utils/errorResponse.ts +1 -4
  138. package/src/utils/markdownToTxt.ts +20 -0
  139. package/locales/ar/clerk.json +0 -545
  140. package/locales/bg-BG/clerk.json +0 -545
  141. package/locales/de-DE/clerk.json +0 -545
  142. package/locales/en-US/clerk.json +0 -545
  143. package/locales/es-ES/clerk.json +0 -545
  144. package/locales/fa-IR/clerk.json +0 -545
  145. package/locales/fr-FR/clerk.json +0 -545
  146. package/locales/it-IT/clerk.json +0 -545
  147. package/locales/ja-JP/clerk.json +0 -545
  148. package/locales/ko-KR/clerk.json +0 -545
  149. package/locales/nl-NL/clerk.json +0 -545
  150. package/locales/pl-PL/clerk.json +0 -545
  151. package/locales/pt-BR/clerk.json +0 -545
  152. package/locales/ru-RU/clerk.json +0 -545
  153. package/locales/tr-TR/clerk.json +0 -545
  154. package/locales/vi-VN/clerk.json +0 -545
  155. package/locales/zh-CN/clerk.json +0 -545
  156. package/locales/zh-TW/clerk.json +0 -545
  157. package/src/app/(backend)/api/webhooks/clerk/__tests__/fixtures/createUser.json +0 -73
  158. package/src/app/(backend)/api/webhooks/clerk/route.ts +0 -95
  159. package/src/app/(backend)/api/webhooks/clerk/validateRequest.ts +0 -22
  160. package/src/app/[variants]/(auth)/login/[[...login]]/page.tsx +0 -27
  161. package/src/app/[variants]/(main)/settings/security/features/ClerkProfile.tsx +0 -67
  162. package/src/features/Conversation/ChatList/components/AutoScroll.tsx +0 -25
  163. package/src/layout/AuthProvider/Clerk/UserUpdater.tsx +0 -40
  164. package/src/layout/AuthProvider/Clerk/index.tsx +0 -54
  165. package/src/layout/AuthProvider/Clerk/useAppearance.ts +0 -133
  166. package/src/libs/clerk-auth/index.test.ts +0 -216
  167. package/src/libs/clerk-auth/index.ts +0 -80
  168. package/src/locales/default/clerk.ts +0 -677
  169. package/src/server/services/user/index.test.ts +0 -220
@@ -1,73 +0,0 @@
1
- {
2
- "backup_code_enabled": false,
3
- "banned": false,
4
- "create_organization_enabled": true,
5
- "created_at": 1713709987911,
6
- "delete_self_enabled": true,
7
- "email_addresses": [
8
- {
9
- "created_at": 1713709977919,
10
- "email_address": "arvinx@foxmail.com",
11
- "id": "idn_2fPkD9X1lfzSn5lJVDGyochYq8k",
12
- "linked_to": [],
13
- "object": "email_address",
14
- "reserved": false,
15
- "updated_at": 1713709987951,
16
- "verification": []
17
- }
18
- ],
19
- "external_accounts": [
20
- {
21
- "approved_scopes": "read:user user:email",
22
- "avatar_url": "https://avatars.githubusercontent.com/u/28616219?v=4",
23
- "created_at": 1713709542104,
24
- "email_address": "arvinx@foxmail.com",
25
- "first_name": "Arvin",
26
- "id": "eac_2fPjKROeJ1bBs8Uxa6RFMxKogTB",
27
- "identification_id": "idn_2fPjyV3sqtQJZUbEzdK2y23a1bq",
28
- "image_url": "https://img.clerk.com/eyJ0eXBlIjoicHJveHkiLCJzcmMiOiJodHRwczovL2F2YXRhcnMuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3UvMjg2MTYyMTk/dj00IiwicyI6IkhCeHE5NmdlRk85ekRxMjJlR05EalUrbVFBbmVDZjRVQkpwNGYxcW5JajQifQ",
29
- "label": null,
30
- "last_name": "Xu",
31
- "object": "external_account",
32
- "provider": "oauth_github",
33
- "provider_user_id": "28616219",
34
- "public_metadata": {},
35
- "updated_at": 1713709542104,
36
- "username": "arvinxx",
37
- "verification": {
38
- "attempts": null,
39
- "expire_at": 1713710140131,
40
- "status": "verified",
41
- "strategy": "oauth_github"
42
- }
43
- }
44
- ],
45
- "external_id": null,
46
- "first_name": "Arvin",
47
- "has_image": true,
48
- "id": "user_2fPkELglwI48WpZVwwdAxBKBPK6",
49
- "image_url": "https://img.clerk.com/eyJ0eXBlIjoicHJveHkiLCJzcmMiOiJodHRwczovL2ltYWdlcy5jbGVyay5kZXYvb2F1dGhfZ2l0aHViL2ltZ18yZlBrRU1adVpwdlpvZFBHcVREdHJnTzJJM3cifQ",
50
- "last_active_at": 1713709987902,
51
- "last_name": "Xu",
52
- "last_sign_in_at": null,
53
- "locked": false,
54
- "lockout_expires_in_seconds": null,
55
- "object": "user",
56
- "passkeys": [],
57
- "password_enabled": false,
58
- "phone_numbers": [],
59
- "primary_email_address_id": "idn_2fPkD9X1lfzSn5lJVDGyochYq8k",
60
- "primary_phone_number_id": null,
61
- "primary_web3_wallet_id": null,
62
- "private_metadata": {},
63
- "profile_image_url": "https://images.clerk.dev/oauth_github/img_2fPkEMZuZpvZodPGqTDtrgO2I3w",
64
- "public_metadata": {},
65
- "saml_accounts": [],
66
- "totp_enabled": false,
67
- "two_factor_enabled": false,
68
- "unsafe_metadata": {},
69
- "updated_at": 1713709987972,
70
- "username": "arvinxx",
71
- "verification_attempts_remaining": 100,
72
- "web3_wallets": []
73
- }
@@ -1,95 +0,0 @@
1
- import { NextResponse } from 'next/server';
2
-
3
- import { serverDB } from '@/database/server';
4
- import { authEnv } from '@/envs/auth';
5
- import { pino } from '@/libs/logger';
6
- import { UserService } from '@/server/services/user';
7
-
8
- import { validateRequest } from './validateRequest';
9
-
10
- if (authEnv.NEXT_PUBLIC_ENABLE_CLERK_AUTH && !authEnv.CLERK_WEBHOOK_SECRET) {
11
- throw new Error('`CLERK_WEBHOOK_SECRET` environment variable is missing');
12
- }
13
-
14
- export const POST = async (req: Request): Promise<NextResponse> => {
15
- const payload = await validateRequest(req, authEnv.CLERK_WEBHOOK_SECRET!);
16
-
17
- if (!payload) {
18
- return NextResponse.json(
19
- { error: 'webhook verification failed or payload was malformed' },
20
- { status: 400 },
21
- );
22
- }
23
-
24
- const { type, data } = payload;
25
-
26
- pino.trace(`clerk webhook payload: ${{ data, type }}`);
27
-
28
- const userService = new UserService(serverDB);
29
- switch (type) {
30
- case 'user.created': {
31
- pino.info('creating user due to clerk webhook');
32
- const result = await userService.createUser(data.id, data);
33
-
34
- return NextResponse.json(result, { status: 200 });
35
- }
36
-
37
- case 'user.deleted': {
38
- if (!data.id) {
39
- pino.warn('clerk sent a delete user request, but no user ID was included in the payload');
40
- return NextResponse.json({ message: 'ok' }, { status: 200 });
41
- }
42
-
43
- pino.info('delete user due to clerk webhook');
44
-
45
- await userService.deleteUser(data.id);
46
-
47
- return NextResponse.json({ message: 'user deleted' }, { status: 200 });
48
- }
49
-
50
- case 'user.updated': {
51
- const result = await userService.updateUser(data.id, data);
52
-
53
- return NextResponse.json(result, { status: 200 });
54
- }
55
-
56
- default: {
57
- pino.warn(
58
- `${req.url} received event type "${type}", but no handler is defined for this type`,
59
- );
60
- return NextResponse.json({ error: `unrecognised payload type: ${type}` }, { status: 400 });
61
- }
62
- // case 'user.updated':
63
- // break;
64
- // case 'session.created':
65
- // break;
66
- // case 'session.ended':
67
- // break;
68
- // case 'session.removed':
69
- // break;
70
- // case 'session.revoked':
71
- // break;
72
- // case 'email.created':
73
- // break;
74
- // case 'sms.created':
75
- // break;
76
- // case 'organization.created':
77
- // break;
78
- // case 'organization.updated':
79
- // break;
80
- // case 'organization.deleted':
81
- // break;
82
- // case 'organizationMembership.created':
83
- // break;
84
- // case 'organizationMembership.deleted':
85
- // break;
86
- // case 'organizationMembership.updated':
87
- // break;
88
- // case 'organizationInvitation.accepted':
89
- // break;
90
- // case 'organizationInvitation.created':
91
- // break;
92
- // case 'organizationInvitation.revoked':
93
- // break;
94
- }
95
- };
@@ -1,22 +0,0 @@
1
- import { type WebhookEvent } from '@clerk/nextjs/server';
2
- import { headers } from 'next/headers';
3
- import { Webhook } from 'svix';
4
-
5
- export const validateRequest = async (request: Request, secret: string) => {
6
- const payloadString = await request.text();
7
- const headerPayload = await headers();
8
-
9
- const svixHeaders = {
10
- 'svix-id': headerPayload.get('svix-id')!,
11
- 'svix-signature': headerPayload.get('svix-signature')!,
12
- 'svix-timestamp': headerPayload.get('svix-timestamp')!,
13
- };
14
- const wh = new Webhook(secret);
15
-
16
- try {
17
- return wh.verify(payloadString, svixHeaders) as WebhookEvent;
18
- } catch {
19
- console.error('incoming webhook failed verification');
20
- return;
21
- }
22
- };
@@ -1,27 +0,0 @@
1
- import { SignIn } from '@clerk/nextjs';
2
- import { BRANDING_NAME } from '@lobechat/business-const';
3
-
4
- import { enableClerk } from '@/envs/auth';
5
- import { notFound } from '@/libs/next/navigation';
6
- import { metadataModule } from '@/server/metadata';
7
- import { translation } from '@/server/translation';
8
- import { type DynamicLayoutProps } from '@/types/next';
9
- import { RouteVariants } from '@/utils/server/routeVariants';
10
-
11
- export const generateMetadata = async (props: DynamicLayoutProps) => {
12
- const locale = await RouteVariants.getLocale(props);
13
- const { t } = await translation('clerk', locale);
14
- return metadataModule.generate({
15
- description: t('signIn.start.subtitle'),
16
- title: t('signIn.start.title', { applicationName: BRANDING_NAME }),
17
- url: '/login',
18
- });
19
- };
20
-
21
- const Page = () => {
22
- if (!enableClerk) return notFound();
23
-
24
- return <SignIn path="/login" />;
25
- };
26
-
27
- export default Page;
@@ -1,67 +0,0 @@
1
- 'use client';
2
-
3
- import { UserProfile } from '@clerk/nextjs';
4
- import { type ElementsConfig } from '@clerk/types';
5
- import { createStaticStyles, responsive } from 'antd-style';
6
- import { memo } from 'react';
7
-
8
- export const styles = createStaticStyles(
9
- ({ css, cssVar }) =>
10
- ({
11
- cardBox: css`
12
- width: 100%;
13
- min-width: 100%;
14
- background: transparent;
15
- `,
16
- footer: css`
17
- display: none !important;
18
- `,
19
- headerTitle: css`
20
- ${responsive.sm} {
21
- margin: 0;
22
- padding: 16px;
23
-
24
- font-size: 14px;
25
- font-weight: 400;
26
- line-height: 24px;
27
-
28
- opacity: 0.5;
29
- }
30
- `,
31
- navbar: css`
32
- display: none !important;
33
- `,
34
- navbarMobileMenuRow: css`
35
- display: none !important;
36
- `,
37
- pageScrollBox: css`
38
- padding: 0;
39
- `,
40
- profileSection: css`
41
- ${responsive.sm} {
42
- padding-inline: 16px;
43
- background: ${cssVar.colorBgContainer};
44
- }
45
- `,
46
- rootBox: css`
47
- width: 100%;
48
- height: 100%;
49
- `,
50
- scrollBox: css`
51
- background: transparent !important;
52
- `,
53
- }) as Partial<Record<keyof ElementsConfig, any>>,
54
- );
55
-
56
- const Client = memo(() => {
57
- return (
58
- <UserProfile
59
- appearance={{
60
- elements: styles,
61
- }}
62
- path={'/profile'}
63
- />
64
- );
65
- });
66
-
67
- export default Client;
@@ -1,25 +0,0 @@
1
- 'use client';
2
-
3
- import { memo, useEffect } from 'react';
4
-
5
- import { messageStateSelectors, useConversationStore, virtuaListSelectors } from '../../store';
6
- import BackBottom from './BackBottom';
7
-
8
- const AutoScroll = memo(() => {
9
- const atBottom = useConversationStore(virtuaListSelectors.atBottom);
10
- const isScrolling = useConversationStore(virtuaListSelectors.isScrolling);
11
- const isGenerating = useConversationStore(messageStateSelectors.isAIGenerating);
12
- const scrollToBottom = useConversationStore((s) => s.scrollToBottom);
13
-
14
- useEffect(() => {
15
- if (atBottom && isGenerating && !isScrolling) {
16
- scrollToBottom(false);
17
- }
18
- }, [atBottom, isGenerating, isScrolling, scrollToBottom]);
19
-
20
- return <BackBottom onScrollToBottom={() => scrollToBottom(true)} visible={!atBottom} />;
21
- });
22
-
23
- AutoScroll.displayName = 'ConversationAutoScroll';
24
-
25
- export default AutoScroll;
@@ -1,40 +0,0 @@
1
- 'use client';
2
-
3
- import { useClerk, useUser } from '@clerk/nextjs';
4
- import { memo } from 'react';
5
- import { createStoreUpdater } from 'zustand-utils';
6
-
7
- import { useUserStore } from '@/store/user';
8
- import { type LobeUser } from '@/types/user';
9
-
10
- // update the user data into the context
11
- const UserUpdater = memo(() => {
12
- const { isLoaded, user, isSignedIn } = useUser();
13
-
14
- const { session, openUserProfile, signOut, openSignIn } = useClerk();
15
-
16
- const useStoreUpdater = createStoreUpdater(useUserStore);
17
-
18
- const lobeUser = {
19
- avatar: user?.imageUrl,
20
- firstName: user?.firstName,
21
- fullName: user?.fullName,
22
- id: user?.id,
23
- latestName: user?.lastName,
24
- username: user?.username,
25
- } as LobeUser;
26
-
27
- useStoreUpdater('isLoaded', isLoaded);
28
- useStoreUpdater('user', lobeUser);
29
- useStoreUpdater('isSignedIn', isSignedIn);
30
-
31
- useStoreUpdater('clerkUser', user!);
32
- useStoreUpdater('clerkSession', session!);
33
- useStoreUpdater('clerkSignIn', openSignIn);
34
- useStoreUpdater('clerkOpenUserProfile', openUserProfile);
35
- useStoreUpdater('clerkSignOut', signOut);
36
-
37
- return null;
38
- });
39
-
40
- export default UserUpdater;
@@ -1,54 +0,0 @@
1
- 'use client';
2
-
3
- import { ClerkProvider } from '@clerk/nextjs';
4
- import { type PropsWithChildren, memo, useEffect, useMemo, useState, useTransition } from 'react';
5
- import { useTranslation } from 'react-i18next';
6
-
7
- import UserUpdater from './UserUpdater';
8
- import { useAppearance } from './useAppearance';
9
-
10
- const Clerk = memo(({ children }: PropsWithChildren) => {
11
- const appearance = useAppearance();
12
- const {
13
- i18n: { language, getResourceBundle },
14
- } = useTranslation('clerk');
15
-
16
- const localization = useMemo(() => getResourceBundle(language, 'clerk'), [language]);
17
-
18
- // When useAppearance returns different result during SSR vs. client-side (when theme mode is auto), the appearance is not applied
19
- // It's because Clerk internally re-applies SSR props after transition which overrides client-side props, see https://github.com/clerk/javascript/blob/main/packages/nextjs/src/app-router/client/ClerkProvider.tsx
20
- // This re-renders the provider after transition to make sure client-side props are always applied
21
- const [count, setCount] = useState(0);
22
- const [isPending, startTransition] = useTransition();
23
- useEffect(() => {
24
- if (count || isPending) return;
25
- startTransition(() => {
26
- setCount((count) => count + 1);
27
- });
28
- }, [count, setCount, isPending, startTransition]);
29
-
30
- const allowedRedirectOrigins = useMemo(() => {
31
- const rawOrigins = process.env.NEXT_PUBLIC_CLERK_AUTH_ALLOW_ORIGINS;
32
- if (!rawOrigins) return undefined;
33
-
34
- const origins = rawOrigins
35
- .split(',')
36
- .map((origin) => origin.trim())
37
- .filter(Boolean);
38
- return origins.length ? origins : undefined;
39
- }, []);
40
-
41
- return (
42
- <ClerkProvider
43
- allowedRedirectOrigins={allowedRedirectOrigins}
44
- appearance={appearance}
45
- localization={localization}
46
- signUpUrl="/signup"
47
- >
48
- {children}
49
- <UserUpdater />
50
- </ClerkProvider>
51
- );
52
- });
53
-
54
- export default Clerk;
@@ -1,133 +0,0 @@
1
- 'use client';
2
-
3
- import { dark } from '@clerk/themes';
4
- import { type ElementsConfig, type Theme } from '@clerk/types';
5
- import { BRANDING_URL } from '@lobechat/business-const';
6
- import { createStaticStyles, cssVar, cx } from 'antd-style';
7
-
8
- import { useIsDark } from '@/hooks/useIsDark';
9
-
10
- const prefixCls = 'cl';
11
-
12
- const styles = createStaticStyles(({ css, cssVar }) => ({
13
- avatarBox: css`
14
- width: 40px;
15
- height: 40px;
16
- `,
17
- cardBox: css`
18
- border-radius: ${cssVar.borderRadiusLG}px;
19
- background: ${cssVar.colorBgContainer};
20
- box-shadow: 0 0 0 1px ${cssVar.colorBorderSecondary};
21
- `,
22
- header: css`
23
- gap: 1em;
24
- `,
25
- logoBox: css`
26
- height: 48px;
27
- `,
28
- modalBackdrop: css`
29
- background: ${cssVar.colorBgMask};
30
- `,
31
- modalContent: css`
32
- &.${prefixCls}-modalContent {
33
- .${prefixCls}-cardBox {
34
- border: 1px solid ${cssVar.colorSplit} !important;
35
- border-radius: ${cssVar.borderRadiusLG}px !important;
36
- box-shadow: ${cssVar.boxShadow} !important;
37
- }
38
-
39
- .${prefixCls}-userProfile-root {
40
- width: min(80vw, 55rem);
41
- height: min(80vh, 44rem);
42
- }
43
- }
44
- `,
45
- navbar: css`
46
- background: ${cssVar.colorFillTertiary};
47
-
48
- @media (max-width: 768px) {
49
- background: ${cssVar.colorBgContainer};
50
- }
51
- `,
52
- navbarButton: css`
53
- line-height: 2;
54
- `,
55
- navbar_dark: css`
56
- background: ${cssVar.colorBgContainer};
57
- `,
58
- pageScrollBox: css`
59
- align-self: center;
60
- width: 100%;
61
- max-width: 1024px;
62
- `,
63
- rootBox: css`
64
- &.${prefixCls}-userProfile-root {
65
- width: 100%;
66
- height: 100%;
67
-
68
- .${prefixCls}-cardBox {
69
- width: 100%;
70
- height: 100%;
71
- border: unset;
72
- border-radius: unset;
73
-
74
- box-shadow: unset;
75
- }
76
- }
77
- `,
78
- scrollBox: css`
79
- border: unset;
80
- border-radius: unset;
81
- background: ${cssVar.colorBgElevated};
82
- box-shadow: 0 1px 0 1px ${cssVar.colorFillTertiary};
83
- `,
84
- scrollBox_dark: css`
85
- background: ${cssVar.colorFillQuaternary};
86
- `,
87
- socialButtons: css`
88
- display: flex;
89
- flex-direction: column;
90
- `,
91
- socialButtonsBlockButton__github: css`
92
- order: 1;
93
- `,
94
- socialButtonsBlockButton__google: css`
95
- order: -1;
96
- `,
97
- })) as Partial<Record<keyof ElementsConfig, any>>;
98
-
99
- export const useAppearance = () => {
100
- const isDarkMode = useIsDark();
101
-
102
- const navbarStyle = cx(styles.navbar, isDarkMode && (styles as any).navbar_dark);
103
- const scrollBoxStyle = cx(styles.scrollBox, isDarkMode && (styles as any).scrollBox_dark);
104
-
105
- const elements = {
106
- ...styles,
107
- navbar: navbarStyle,
108
- scrollBox: scrollBoxStyle,
109
- } as Partial<Record<keyof ElementsConfig, any>>;
110
-
111
- return {
112
- baseTheme: isDarkMode ? dark : undefined,
113
- elements,
114
- layout: {
115
- helpPageUrl: BRANDING_URL.help ?? 'https://lobehub.com/docs',
116
- privacyPageUrl: BRANDING_URL.privacy ?? 'https://lobehub.com/privacy',
117
- socialButtonsVariant: 'blockButton',
118
- termsPageUrl: BRANDING_URL.terms ?? 'https://lobehub.com/terms',
119
- },
120
- variables: {
121
- borderRadius: cssVar.borderRadius,
122
- colorBackground: cssVar.colorBgContainer,
123
- colorDanger: cssVar.colorError,
124
- colorInputBackground: cssVar.colorFillTertiary,
125
- colorNeutral: cssVar.colorText,
126
- colorSuccess: cssVar.colorSuccess,
127
- colorText: cssVar.colorText,
128
- colorTextSecondary: cssVar.colorTextDescription,
129
- colorWarning: cssVar.colorWarning,
130
- fontSize: cssVar.fontSize,
131
- },
132
- } as Theme;
133
- };