@lobehub/lobehub 2.0.0-next.146 → 2.0.0-next.147

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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [Version 2.0.0-next.147](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.146...v2.0.0-next.147)
6
+
7
+ <sup>Released on **2025-12-02**</sup>
8
+
9
+ #### ✨ Features
10
+
11
+ - **misc**: Support apple sso auth.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's improved
19
+
20
+ - **misc**: Support apple sso auth, closes [#10563](https://github.com/lobehub/lobe-chat/issues/10563) ([2e50313](https://github.com/lobehub/lobe-chat/commit/2e50313))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
5
30
  ## [Version 2.0.0-next.146](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.145...v2.0.0-next.146)
6
31
 
7
32
  <sup>Released on **2025-12-02**</sup>
package/changelog/v1.json CHANGED
@@ -1,4 +1,13 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "features": [
5
+ "Support apple sso auth."
6
+ ]
7
+ },
8
+ "date": "2025-12-02",
9
+ "version": "2.0.0-next.147"
10
+ },
2
11
  {
3
12
  "children": {
4
13
  "improvements": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/lobehub",
3
- "version": "2.0.0-next.146",
3
+ "version": "2.0.0-next.147",
4
4
  "description": "LobeHub - an open-source,comprehensive AI Agent framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
5
5
  "keywords": [
6
6
  "framework",
@@ -656,7 +656,8 @@ export class SessionModel {
656
656
  const results = await this.db.query.agents.findMany({
657
657
  limit: pageSize,
658
658
  offset,
659
- orderBy: [desc(agents.updatedAt)],
659
+ // Keep deterministic ordering for keyword search results
660
+ orderBy: [asc(agents.id)],
660
661
  where: and(
661
662
  eq(agents.userId, this.userId),
662
663
  or(
package/src/auth.ts CHANGED
@@ -19,6 +19,8 @@ import { EmailService } from '@/server/services/email';
19
19
  const VERIFICATION_LINK_EXPIRES_IN = 3600;
20
20
  const MAGIC_LINK_EXPIRES_IN = 900;
21
21
  const enableMagicLink = authEnv.NEXT_PUBLIC_ENABLE_MAGIC_LINK;
22
+ const APPLE_TRUSTED_ORIGIN = 'https://appleid.apple.com';
23
+ const enabledSSOProviders = parseSSOProviders(authEnv.AUTH_SSO_PROVIDERS);
22
24
 
23
25
  const { socialProviders, genericOAuthProviders } = initBetterAuthSSOProviders();
24
26
 
@@ -56,7 +58,14 @@ const getTrustedOrigins = () => {
56
58
  normalizeOrigin(process.env.VERCEL_URL),
57
59
  ].filter(Boolean) as string[];
58
60
 
59
- return defaults.length > 0 ? Array.from(new Set(defaults)) : undefined;
61
+ const baseTrustedOrigins = defaults.length > 0 ? Array.from(new Set(defaults)) : undefined;
62
+
63
+ if (!enabledSSOProviders.includes('apple')) return baseTrustedOrigins;
64
+
65
+ const mergedOrigins = new Set(baseTrustedOrigins || []);
66
+ mergedOrigins.add(APPLE_TRUSTED_ORIGIN);
67
+
68
+ return Array.from(mergedOrigins);
60
69
  };
61
70
 
62
71
  export const auth = betterAuth({
@@ -64,7 +73,7 @@ export const auth = betterAuth({
64
73
  accountLinking: {
65
74
  allowDifferentEmails: true,
66
75
  enabled: true,
67
- trustedProviders: parseSSOProviders(authEnv.AUTH_SSO_PROVIDERS),
76
+ trustedProviders: enabledSSOProviders,
68
77
  },
69
78
  },
70
79
 
package/src/envs/auth.ts CHANGED
@@ -69,6 +69,10 @@ declare global {
69
69
  AUTH_GOOGLE_ID?: string;
70
70
  AUTH_GOOGLE_SECRET?: string;
71
71
 
72
+ AUTH_APPLE_CLIENT_ID?: string;
73
+ AUTH_APPLE_CLIENT_SECRET?: string;
74
+ AUTH_APPLE_APP_BUNDLE_IDENTIFIER?: string;
75
+
72
76
  AUTH_GITHUB_ID?: string;
73
77
  AUTH_GITHUB_SECRET?: string;
74
78
 
@@ -184,6 +188,10 @@ export const getAuthConfig = () => {
184
188
  AUTH_GOOGLE_ID: z.string().optional(),
185
189
  AUTH_GOOGLE_SECRET: z.string().optional(),
186
190
 
191
+ AUTH_APPLE_CLIENT_ID: z.string().optional(),
192
+ AUTH_APPLE_CLIENT_SECRET: z.string().optional(),
193
+ AUTH_APPLE_APP_BUNDLE_IDENTIFIER: z.string().optional(),
194
+
187
195
  AUTH_GITHUB_ID: z.string().optional(),
188
196
  AUTH_GITHUB_SECRET: z.string().optional(),
189
197
 
@@ -301,6 +309,10 @@ export const getAuthConfig = () => {
301
309
  AUTH_GOOGLE_ID: process.env.AUTH_GOOGLE_ID,
302
310
  AUTH_GOOGLE_SECRET: process.env.AUTH_GOOGLE_SECRET,
303
311
 
312
+ AUTH_APPLE_CLIENT_ID: process.env.AUTH_APPLE_CLIENT_ID,
313
+ AUTH_APPLE_CLIENT_SECRET: process.env.AUTH_APPLE_CLIENT_SECRET,
314
+ AUTH_APPLE_APP_BUNDLE_IDENTIFIER: process.env.AUTH_APPLE_APP_BUNDLE_IDENTIFIER,
315
+
304
316
  AUTH_GITHUB_ID: process.env.AUTH_GITHUB_ID,
305
317
  AUTH_GITHUB_SECRET: process.env.AUTH_GITHUB_SECRET,
306
318
 
@@ -2,7 +2,13 @@
2
2
  * Canonical IDs of Better-Auth built-in social providers.
3
3
  * Keep this list in sync with provider definitions in `src/libs/better-auth/sso/providers`.
4
4
  */
5
- export const BUILTIN_BETTER_AUTH_PROVIDERS = ['google', 'github', 'cognito', 'microsoft'] as const;
5
+ export const BUILTIN_BETTER_AUTH_PROVIDERS = [
6
+ 'apple',
7
+ 'google',
8
+ 'github',
9
+ 'cognito',
10
+ 'microsoft',
11
+ ] as const;
6
12
 
7
13
  /**
8
14
  * Provider alias → canonical ID mapping.
@@ -5,6 +5,7 @@ import { authEnv } from '@/envs/auth';
5
5
  import { BUILTIN_BETTER_AUTH_PROVIDERS } from '@/libs/better-auth/constants';
6
6
  import { parseSSOProviders } from '@/libs/better-auth/utils/server';
7
7
 
8
+ import Apple from './providers/apple';
8
9
  import Auth0 from './providers/auth0';
9
10
  import Authelia from './providers/authelia';
10
11
  import Authentik from './providers/authentik';
@@ -23,6 +24,7 @@ import Wechat from './providers/wechat';
23
24
  import Zitadel from './providers/zitadel';
24
25
 
25
26
  const providerDefinitions = [
27
+ Apple,
26
28
  Google,
27
29
  Github,
28
30
  Cognito,
@@ -0,0 +1,33 @@
1
+ import { authEnv } from '@/envs/auth';
2
+
3
+ import type { BuiltinProviderDefinition } from '../types';
4
+
5
+ const provider: BuiltinProviderDefinition<
6
+ {
7
+ AUTH_APPLE_APP_BUNDLE_IDENTIFIER?: string;
8
+ AUTH_APPLE_CLIENT_ID: string;
9
+ AUTH_APPLE_CLIENT_SECRET: string;
10
+ },
11
+ 'apple'
12
+ > = {
13
+ build: (env) => {
14
+ return {
15
+ appBundleIdentifier: env.AUTH_APPLE_APP_BUNDLE_IDENTIFIER,
16
+ clientId: env.AUTH_APPLE_CLIENT_ID,
17
+ clientSecret: env.AUTH_APPLE_CLIENT_SECRET,
18
+ };
19
+ },
20
+ checkEnvs: () => {
21
+ return !!(authEnv.AUTH_APPLE_CLIENT_ID && authEnv.AUTH_APPLE_CLIENT_SECRET)
22
+ ? {
23
+ AUTH_APPLE_APP_BUNDLE_IDENTIFIER: authEnv.AUTH_APPLE_APP_BUNDLE_IDENTIFIER,
24
+ AUTH_APPLE_CLIENT_ID: authEnv.AUTH_APPLE_CLIENT_ID,
25
+ AUTH_APPLE_CLIENT_SECRET: authEnv.AUTH_APPLE_CLIENT_SECRET,
26
+ }
27
+ : false;
28
+ },
29
+ id: 'apple',
30
+ type: 'builtin',
31
+ };
32
+
33
+ export default provider;