mirror of
https://github.com/lobehub/lobehub.git
synced 2026-03-26 13:19:34 +07:00
♻️ refactor(auth): remove NEXT_PUBLIC_AUTH_URL env variable (#11658)
This commit is contained in:
@@ -307,9 +307,6 @@ OPENAI_API_KEY=sk-xxxxxxxxx
|
||||
# Shared between Better-Auth and Next-Auth
|
||||
# AUTH_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
|
||||
# Auth URL (accessible from browser, optional if same domain)
|
||||
# NEXT_PUBLIC_AUTH_URL=http://localhost:3210
|
||||
|
||||
# Require email verification before allowing users to sign in (default: false)
|
||||
# Set to '1' to force users to verify their email before signing in
|
||||
# NEXT_PUBLIC_AUTH_EMAIL_VERIFICATION=0
|
||||
|
||||
@@ -43,9 +43,6 @@ NEXT_PUBLIC_ENABLE_BETTER_AUTH=1
|
||||
# Better Auth secret for JWT signing (generate with: openssl rand -base64 32)
|
||||
AUTH_SECRET=${UNSAFE_SECRET}
|
||||
|
||||
# Authentication URL
|
||||
NEXT_PUBLIC_AUTH_URL=${APP_URL}
|
||||
|
||||
# SSO providers configuration - using Casdoor for development
|
||||
AUTH_SSO_PROVIDERS=casdoor
|
||||
|
||||
|
||||
@@ -189,8 +189,7 @@ ENV KEY_VAULTS_SECRET="" \
|
||||
|
||||
# Better Auth
|
||||
ENV AUTH_SECRET="" \
|
||||
AUTH_SSO_PROVIDERS="" \
|
||||
NEXT_PUBLIC_AUTH_URL=""
|
||||
AUTH_SSO_PROVIDERS=""
|
||||
|
||||
# Clerk
|
||||
ENV CLERK_SECRET_KEY="" \
|
||||
|
||||
@@ -39,12 +39,11 @@ By setting the environment variables `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` and `CL
|
||||
|
||||
To enable Better Auth in LobeChat, set the following environment variables:
|
||||
|
||||
| Environment Variable | Type | Description |
|
||||
| -------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `NEXT_PUBLIC_ENABLE_BETTER_AUTH` | Required | Set to `1` to enable Better Auth service |
|
||||
| `AUTH_SECRET` | Required | Key used to encrypt session tokens. Generate using: `openssl rand -base64 32` |
|
||||
| `NEXT_PUBLIC_AUTH_URL` | Required | The browser-accessible base URL for Better Auth (e.g., `http://localhost:3010`, `https://lobechat.com`). Optional for Vercel deployments (auto-detected from `VERCEL_URL`) |
|
||||
| `AUTH_SSO_PROVIDERS` | Optional | Comma-separated list of enabled SSO providers, e.g., `google,github,microsoft` |
|
||||
| Environment Variable | Type | Description |
|
||||
| -------------------------------- | -------- | ----------------------------------------------------------------------------- |
|
||||
| `NEXT_PUBLIC_ENABLE_BETTER_AUTH` | Required | Set to `1` to enable Better Auth service |
|
||||
| `AUTH_SECRET` | Required | Key used to encrypt session tokens. Generate using: `openssl rand -base64 32` |
|
||||
| `AUTH_SSO_PROVIDERS` | Optional | Comma-separated list of enabled SSO providers, e.g., `google,github,microsoft`|
|
||||
|
||||
<Callout type={'error'}>
|
||||
**Important**: Better Auth is currently only suitable for **fresh deployments**. If you are already using NextAuth or Clerk and have existing user data in your database, **do not switch to Better Auth yet**, otherwise existing users will not be able to log in.
|
||||
|
||||
@@ -37,12 +37,11 @@ LobeChat 与 Clerk 做了深度集成,能够为用户提供一个更加安全
|
||||
|
||||
要在 LobeChat 中启用 Better Auth,请设置以下环境变量:
|
||||
|
||||
| 环境变量 | 类型 | 描述 |
|
||||
| -------------------------------- | -- | ---------------------------------------------------------------------------------------------------------------- |
|
||||
| `NEXT_PUBLIC_ENABLE_BETTER_AUTH` | 必选 | 设置为 `1` 以启用 Better Auth 服务 |
|
||||
| `AUTH_SECRET` | 必选 | 用于加密会话令牌的密钥。使用以下命令生成:`openssl rand -base64 32` |
|
||||
| `NEXT_PUBLIC_AUTH_URL` | 必选 | 浏览器可访问的 Better Auth 基础 URL(例如 `http://localhost:3010`、`https://lobechat.com`)。Vercel 部署时可选(会自动从 `VERCEL_URL` 获取) |
|
||||
| `AUTH_SSO_PROVIDERS` | 可选 | 启用的 SSO 提供商列表,以逗号分隔,例如 `google,github,microsoft` |
|
||||
| 环境变量 | 类型 | 描述 |
|
||||
| -------------------------------- | -- | ----------------------------------------------------------- |
|
||||
| `NEXT_PUBLIC_ENABLE_BETTER_AUTH` | 必选 | 设置为 `1` 以启用 Better Auth 服务 |
|
||||
| `AUTH_SECRET` | 必选 | 用于加密会话令牌的密钥。使用以下命令生成:`openssl rand -base64 32` |
|
||||
| `AUTH_SSO_PROVIDERS` | 可选 | 启用的 SSO 提供商列表,以逗号分隔,例如 `google,github,microsoft` |
|
||||
|
||||
<Callout type={'error'}>
|
||||
**重要提示**:Better Auth 目前仅适用于**全新部署**的场景。如果你已经使用 NextAuth 或 Clerk 并且数据库中存在用户数据,**请暂时不要切换到 Better Auth**,否则现有用户将无法登录。
|
||||
|
||||
@@ -34,13 +34,6 @@ LobeChat provides a complete authentication service capability when deployed. Th
|
||||
- Default: `-`
|
||||
- Example: `Tfhi2t2pelSMEA8eaV61KaqPNEndFFdMIxDaJnS1CUI=`
|
||||
|
||||
#### `NEXT_PUBLIC_AUTH_URL`
|
||||
|
||||
- Type: Optional
|
||||
- Description: The URL accessible from the browser for Better Auth callbacks. Only set this if the default generated URL is incorrect.
|
||||
- Default: `-`
|
||||
- Example: `https://example.com`
|
||||
|
||||
#### `NEXT_PUBLIC_AUTH_EMAIL_VERIFICATION`
|
||||
|
||||
- Type: Optional
|
||||
|
||||
@@ -32,13 +32,6 @@ LobeChat 在部署时提供了完善的身份验证服务能力,以下是相
|
||||
- 默认值:`-`
|
||||
- 示例:`Tfhi2t2pelSMEA8eaV61KaqPNEndFFdMIxDaJnS1CUI=`
|
||||
|
||||
#### `NEXT_PUBLIC_AUTH_URL`
|
||||
|
||||
- 类型:可选
|
||||
- 描述:浏览器可访问的 Better Auth 回调 URL。仅在默认生成的 URL 不正确时设置。
|
||||
- 默认值:`-`
|
||||
- 示例:`https://example.com`
|
||||
|
||||
#### `NEXT_PUBLIC_AUTH_EMAIL_VERIFICATION`
|
||||
|
||||
- 类型:可选
|
||||
|
||||
@@ -51,10 +51,10 @@ const printEnvInfo = () => {
|
||||
|
||||
// Auth-related env vars
|
||||
console.log('\n Auth Environment Variables:');
|
||||
console.log(` NEXT_PUBLIC_AUTH_URL: ${process.env.NEXT_PUBLIC_AUTH_URL ?? '(not set)'}`);
|
||||
console.log(` NEXTAUTH_URL: ${process.env.NEXTAUTH_URL ?? '(not set)'}`);
|
||||
console.log(` APP_URL: ${process.env.APP_URL ?? '(not set)'}`);
|
||||
console.log(` VERCEL_URL: ${process.env.VERCEL_URL ?? '(not set)'}`);
|
||||
console.log(` VERCEL_BRANCH_URL: ${process.env.VERCEL_BRANCH_URL ?? '(not set)'}`);
|
||||
console.log(` VERCEL_PROJECT_PRODUCTION_URL: ${process.env.VERCEL_PROJECT_PRODUCTION_URL ?? '(not set)'}`);
|
||||
console.log(` AUTH_EMAIL_VERIFICATION: ${process.env.AUTH_EMAIL_VERIFICATION ?? '(not set)'}`);
|
||||
console.log(` ENABLE_MAGIC_LINK: ${process.env.ENABLE_MAGIC_LINK ?? '(not set)'}`);
|
||||
console.log(` AUTH_SECRET: ${process.env.AUTH_SECRET ? '✓ set' : '✗ not set'}`);
|
||||
|
||||
@@ -82,3 +82,84 @@ describe('getServerConfig', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('APP_URL fallback', () => {
|
||||
beforeEach(() => {
|
||||
vi.resetModules();
|
||||
// Clean up all related env vars
|
||||
delete process.env.APP_URL;
|
||||
delete process.env.VERCEL;
|
||||
delete process.env.VERCEL_ENV;
|
||||
delete process.env.VERCEL_URL;
|
||||
delete process.env.VERCEL_BRANCH_URL;
|
||||
delete process.env.VERCEL_PROJECT_PRODUCTION_URL;
|
||||
});
|
||||
|
||||
it('should use APP_URL when explicitly set', async () => {
|
||||
process.env.APP_URL = 'https://custom-app.com';
|
||||
process.env.VERCEL = '1';
|
||||
|
||||
const { getAppConfig } = await import('../app');
|
||||
const config = getAppConfig();
|
||||
expect(config.APP_URL).toBe('https://custom-app.com');
|
||||
});
|
||||
|
||||
describe('Vercel environment', () => {
|
||||
it('should use VERCEL_PROJECT_PRODUCTION_URL in production', async () => {
|
||||
process.env.VERCEL = '1';
|
||||
process.env.VERCEL_ENV = 'production';
|
||||
process.env.VERCEL_PROJECT_PRODUCTION_URL = 'lobechat.vercel.app';
|
||||
process.env.VERCEL_BRANCH_URL = 'lobechat-git-main-org.vercel.app';
|
||||
process.env.VERCEL_URL = 'lobechat-abc123.vercel.app';
|
||||
|
||||
const { getAppConfig } = await import('../app');
|
||||
const config = getAppConfig();
|
||||
expect(config.APP_URL).toBe('https://lobechat.vercel.app');
|
||||
});
|
||||
|
||||
it('should use VERCEL_BRANCH_URL in preview environment', async () => {
|
||||
process.env.VERCEL = '1';
|
||||
process.env.VERCEL_ENV = 'preview';
|
||||
process.env.VERCEL_BRANCH_URL = 'lobechat-git-feature-org.vercel.app';
|
||||
process.env.VERCEL_URL = 'lobechat-abc123.vercel.app';
|
||||
|
||||
const { getAppConfig } = await import('../app');
|
||||
const config = getAppConfig();
|
||||
expect(config.APP_URL).toBe('https://lobechat-git-feature-org.vercel.app');
|
||||
});
|
||||
|
||||
it('should fallback to VERCEL_URL when VERCEL_BRANCH_URL is not set', async () => {
|
||||
process.env.VERCEL = '1';
|
||||
process.env.VERCEL_ENV = 'preview';
|
||||
process.env.VERCEL_URL = 'lobechat-abc123.vercel.app';
|
||||
|
||||
const { getAppConfig } = await import('../app');
|
||||
const config = getAppConfig();
|
||||
expect(config.APP_URL).toBe('https://lobechat-abc123.vercel.app');
|
||||
});
|
||||
});
|
||||
|
||||
describe('local environment', () => {
|
||||
it('should use localhost:3010 in development', async () => {
|
||||
|
||||
vi.stubEnv('NODE_ENV', 'development');
|
||||
|
||||
const { getAppConfig } = await import('../app');
|
||||
const config = getAppConfig();
|
||||
expect(config.APP_URL).toBe('http://localhost:3010');
|
||||
|
||||
|
||||
});
|
||||
|
||||
it('should use localhost:3210 in non-development', async () => {
|
||||
|
||||
vi.stubEnv('NODE_ENV', 'test');
|
||||
|
||||
const { getAppConfig } = await import('../app');
|
||||
const config = getAppConfig();
|
||||
expect(config.APP_URL).toBe('http://localhost:3210');
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,12 +12,24 @@ declare global {
|
||||
}
|
||||
const isInVercel = process.env.VERCEL === '1';
|
||||
|
||||
const vercelUrl = `https://${process.env.VERCEL_URL}`;
|
||||
// Vercel URL fallback order (by stability):
|
||||
// 1. VERCEL_PROJECT_PRODUCTION_URL - project level, most stable
|
||||
// 2. VERCEL_BRANCH_URL - branch level, stable across deployments on same branch
|
||||
// 3. VERCEL_URL - deployment level, changes every deployment
|
||||
const getVercelUrl = () => {
|
||||
if (process.env.VERCEL_ENV === 'production' && process.env.VERCEL_PROJECT_PRODUCTION_URL) {
|
||||
return `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`;
|
||||
}
|
||||
if (process.env.VERCEL_BRANCH_URL) {
|
||||
return `https://${process.env.VERCEL_BRANCH_URL}`;
|
||||
}
|
||||
return `https://${process.env.VERCEL_URL}`;
|
||||
};
|
||||
|
||||
const APP_URL = process.env.APP_URL
|
||||
? process.env.APP_URL
|
||||
: isInVercel
|
||||
? vercelUrl
|
||||
? getVercelUrl()
|
||||
: process.env.NODE_ENV === 'development'
|
||||
? 'http://localhost:3010'
|
||||
: 'http://localhost:3210';
|
||||
|
||||
@@ -44,17 +44,4 @@ describe('getAuthConfig fallbacks', () => {
|
||||
|
||||
expect(config.AUTH_SECRET).toBe('nextauth-secret');
|
||||
});
|
||||
|
||||
it('should fall back to NEXTAUTH_URL origin when NEXT_PUBLIC_AUTH_URL is empty string', () => {
|
||||
process.env.NEXT_PUBLIC_AUTH_URL = '';
|
||||
process.env.NEXTAUTH_URL = 'https://example.com/api/auth';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-expect-error - allow overriding for test
|
||||
globalThis.window = undefined;
|
||||
|
||||
const config = getAuthConfig();
|
||||
|
||||
expect(config.NEXT_PUBLIC_AUTH_URL).toBe('https://example.com');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,43 +2,6 @@
|
||||
import { createEnv } from '@t3-oss/env-nextjs';
|
||||
import { z } from 'zod';
|
||||
|
||||
/**
|
||||
* Resolve public auth URL with compatibility fallbacks for NextAuth and Vercel deployments.
|
||||
*/
|
||||
const resolvePublicAuthUrl = () => {
|
||||
if (process.env.NEXT_PUBLIC_AUTH_URL) return process.env.NEXT_PUBLIC_AUTH_URL;
|
||||
|
||||
if (process.env.NEXTAUTH_URL) {
|
||||
try {
|
||||
return new URL(process.env.NEXTAUTH_URL).origin;
|
||||
} catch {
|
||||
// ignore invalid NEXTAUTH_URL
|
||||
}
|
||||
}
|
||||
|
||||
if (process.env.APP_URL) {
|
||||
try {
|
||||
return new URL(process.env.APP_URL).origin;
|
||||
} catch {
|
||||
// ignore invalid APP_URL
|
||||
}
|
||||
}
|
||||
|
||||
if (process.env.VERCEL_URL) {
|
||||
try {
|
||||
const normalizedVercelUrl = process.env.VERCEL_URL.startsWith('http')
|
||||
? process.env.VERCEL_URL
|
||||
: `https://${process.env.VERCEL_URL}`;
|
||||
|
||||
return new URL(normalizedVercelUrl).origin;
|
||||
} catch {
|
||||
// ignore invalid Vercel URL
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
namespace NodeJS {
|
||||
@@ -50,7 +13,6 @@ declare global {
|
||||
|
||||
// ===== Auth (shared by Better Auth / Next Auth) ===== //
|
||||
AUTH_SECRET?: string;
|
||||
NEXT_PUBLIC_AUTH_URL?: string;
|
||||
AUTH_EMAIL_VERIFICATION?: string;
|
||||
ENABLE_MAGIC_LINK?: string;
|
||||
AUTH_SSO_PROVIDERS?: string;
|
||||
@@ -180,7 +142,6 @@ export const getAuthConfig = () => {
|
||||
|
||||
// ---------------------------------- better auth ----------------------------------
|
||||
NEXT_PUBLIC_ENABLE_BETTER_AUTH: z.boolean().optional(),
|
||||
NEXT_PUBLIC_AUTH_URL: z.string().optional(),
|
||||
|
||||
// ---------------------------------- next auth ----------------------------------
|
||||
NEXT_PUBLIC_ENABLE_NEXT_AUTH: z.boolean().optional(),
|
||||
@@ -310,8 +271,6 @@ export const getAuthConfig = () => {
|
||||
|
||||
// ---------------------------------- better auth ----------------------------------
|
||||
NEXT_PUBLIC_ENABLE_BETTER_AUTH: process.env.NEXT_PUBLIC_ENABLE_BETTER_AUTH === '1',
|
||||
// Fallback to NEXTAUTH_URL origin or Vercel deployment domain for seamless migration from next-auth
|
||||
NEXT_PUBLIC_AUTH_URL: resolvePublicAuthUrl(),
|
||||
// Fallback to NEXT_PUBLIC_* for seamless migration
|
||||
AUTH_EMAIL_VERIFICATION:
|
||||
process.env.AUTH_EMAIL_VERIFICATION === '1' ||
|
||||
|
||||
@@ -7,9 +7,6 @@ import {
|
||||
import { createAuthClient } from 'better-auth/react';
|
||||
|
||||
import type { auth } from '@/auth';
|
||||
import { getAuthConfig } from '@/envs/auth';
|
||||
|
||||
const { NEXT_PUBLIC_AUTH_URL } = getAuthConfig();
|
||||
|
||||
export const {
|
||||
linkSocial,
|
||||
@@ -24,12 +21,6 @@ export const {
|
||||
unlinkAccount,
|
||||
useSession,
|
||||
} = createAuthClient({
|
||||
/** The base URL of the server (optional if you're using the same domain) */
|
||||
...(NEXT_PUBLIC_AUTH_URL
|
||||
? {
|
||||
baseURL: NEXT_PUBLIC_AUTH_URL,
|
||||
}
|
||||
: {}),
|
||||
plugins: [
|
||||
adminClient(),
|
||||
inferAdditionalFields<typeof auth>(),
|
||||
|
||||
@@ -14,6 +14,7 @@ import { admin, emailOTP, genericOAuth, magicLink } from 'better-auth/plugins';
|
||||
import { type BetterAuthPlugin } from 'better-auth/types';
|
||||
|
||||
import { businessEmailValidator } from '@/business/server/better-auth';
|
||||
import { appEnv } from '@/envs/app';
|
||||
import { authEnv } from '@/envs/auth';
|
||||
import {
|
||||
getMagicLinkEmailTemplate,
|
||||
@@ -32,13 +33,13 @@ import { UserService } from '@/server/services/user';
|
||||
const VERIFICATION_LINK_EXPIRES_IN = 3600;
|
||||
|
||||
/**
|
||||
* Safely extract hostname from AUTH_URL for passkey rpID.
|
||||
* Returns undefined if AUTH_URL is not set (e.g., in e2e tests).
|
||||
* Safely extract hostname from APP_URL for passkey rpID.
|
||||
* Returns undefined if APP_URL is not set (e.g., in e2e tests).
|
||||
*/
|
||||
const getPasskeyRpID = (): string | undefined => {
|
||||
if (!authEnv.NEXT_PUBLIC_AUTH_URL) return undefined;
|
||||
if (!appEnv.APP_URL) return undefined;
|
||||
try {
|
||||
return new URL(authEnv.NEXT_PUBLIC_AUTH_URL).hostname;
|
||||
return new URL(appEnv.APP_URL).hostname;
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
@@ -46,14 +47,15 @@ const getPasskeyRpID = (): string | undefined => {
|
||||
|
||||
/**
|
||||
* Get passkey origins array.
|
||||
* Returns undefined if AUTH_URL is not set (e.g., in e2e tests).
|
||||
* Returns undefined if APP_URL is not set (e.g., in e2e tests).
|
||||
*/
|
||||
const getPasskeyOrigins = (): string[] | undefined => {
|
||||
if (!authEnv.NEXT_PUBLIC_AUTH_URL) return undefined;
|
||||
return [
|
||||
// Web origin
|
||||
authEnv.NEXT_PUBLIC_AUTH_URL,
|
||||
];
|
||||
if (!appEnv.APP_URL) return undefined;
|
||||
try {
|
||||
return [new URL(appEnv.APP_URL).origin];
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
const MAGIC_LINK_EXPIRES_IN = 900;
|
||||
// OTP expiration time (in seconds) - 5 minutes for mobile OTP verification
|
||||
@@ -81,8 +83,7 @@ export function defineConfig(customOptions: CustomBetterAuthOptions) {
|
||||
},
|
||||
},
|
||||
|
||||
// Use renamed env vars (fallback to next-auth vars is handled in src/envs/auth.ts)
|
||||
baseURL: authEnv.NEXT_PUBLIC_AUTH_URL,
|
||||
baseURL: appEnv.APP_URL,
|
||||
secret: authEnv.AUTH_SECRET,
|
||||
trustedOrigins: getTrustedOrigins(enabledSSOProviders),
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { GenericOAuthConfig } from 'better-auth/plugins';
|
||||
import type { SocialProviders } from 'better-auth/social-providers';
|
||||
|
||||
import { appEnv } from '@/envs/app';
|
||||
import { authEnv } from '@/envs/auth';
|
||||
import { BUILTIN_BETTER_AUTH_PROVIDERS } from '@/libs/better-auth/constants';
|
||||
import { parseSSOProviders } from '@/libs/better-auth/utils/server';
|
||||
@@ -106,7 +107,7 @@ export const initBetterAuthSSOProviders = () => {
|
||||
if (config) {
|
||||
// the generic oidc callback url is /api/auth/oauth2/callback/{providerId}
|
||||
// different from builtin providers' /api/auth/callback/{providerId}
|
||||
config.redirectURI = `${authEnv.NEXT_PUBLIC_AUTH_URL || ''}/api/auth/callback/${definition.id}`;
|
||||
config.redirectURI = `${appEnv.APP_URL}/api/auth/callback/${definition.id}`;
|
||||
genericOAuthProviders.push(config);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { appEnv } from '@/envs/app';
|
||||
import { authEnv } from '@/envs/auth';
|
||||
import { getRedisConfig } from '@/envs/redis';
|
||||
import { initializeRedis, isRedisEnabled } from '@/libs/redis';
|
||||
@@ -48,8 +49,7 @@ export const getTrustedOrigins = (enabledSSOProviders: string[]) => {
|
||||
}
|
||||
|
||||
const defaults = [
|
||||
authEnv.NEXT_PUBLIC_AUTH_URL,
|
||||
normalizeOrigin(process.env.APP_URL),
|
||||
normalizeOrigin(appEnv.APP_URL),
|
||||
normalizeOrigin(process.env.VERCEL_BRANCH_URL),
|
||||
normalizeOrigin(process.env.VERCEL_URL),
|
||||
MOBILE_APP_SCHEME,
|
||||
|
||||
@@ -237,9 +237,8 @@ export function defineConfig() {
|
||||
// ref: https://authjs.dev/getting-started/session-management/protecting
|
||||
if (isProtected) {
|
||||
logNextAuth('Request a protected route, redirecting to sign-in page');
|
||||
const authUrl = authEnv.NEXT_PUBLIC_AUTH_URL;
|
||||
const callbackUrl = `${authUrl}${req.nextUrl.pathname}${req.nextUrl.search}`;
|
||||
const nextLoginUrl = new URL('/next-auth/signin', authUrl);
|
||||
const callbackUrl = `${appEnv.APP_URL}${req.nextUrl.pathname}${req.nextUrl.search}`;
|
||||
const nextLoginUrl = new URL('/next-auth/signin', appEnv.APP_URL);
|
||||
nextLoginUrl.searchParams.set('callbackUrl', callbackUrl);
|
||||
const hl = req.nextUrl.searchParams.get('hl');
|
||||
if (hl) {
|
||||
@@ -325,9 +324,8 @@ export function defineConfig() {
|
||||
// If request a protected route, redirect to sign-in page
|
||||
if (isProtected) {
|
||||
logBetterAuth('Request a protected route, redirecting to sign-in page');
|
||||
const authUrl = authEnv.NEXT_PUBLIC_AUTH_URL;
|
||||
const callbackUrl = `${authUrl}${req.nextUrl.pathname}${req.nextUrl.search}`;
|
||||
const signInUrl = new URL('/signin', authUrl);
|
||||
const callbackUrl = `${appEnv.APP_URL}${req.nextUrl.pathname}${req.nextUrl.search}`;
|
||||
const signInUrl = new URL('/signin', appEnv.APP_URL);
|
||||
signInUrl.searchParams.set('callbackUrl', callbackUrl);
|
||||
const hl = req.nextUrl.searchParams.get('hl');
|
||||
if (hl) {
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/**
|
||||
* @vitest-environment node
|
||||
*/
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { AgentRuntimeService } from './AgentRuntimeService';
|
||||
@@ -166,7 +169,7 @@ describe('AgentRuntimeService', () => {
|
||||
it('should initialize with default base URL', () => {
|
||||
delete process.env.AGENT_RUNTIME_BASE_URL;
|
||||
const newService = new AgentRuntimeService(mockDb, mockUserId);
|
||||
expect((newService as any).baseURL).toBe('http://localhost:3010/api/agent');
|
||||
expect((newService as any).baseURL).toBe('http://localhost:3210/api/agent');
|
||||
});
|
||||
|
||||
it('should initialize with custom base URL from environment', () => {
|
||||
|
||||
@@ -10,6 +10,7 @@ import urlJoin from 'url-join';
|
||||
|
||||
import { MessageModel } from '@/database/models/message';
|
||||
import { type LobeChatDatabase } from '@/database/type';
|
||||
import { appEnv } from '@/envs/app';
|
||||
import {
|
||||
AgentRuntimeCoordinator,
|
||||
type AgentRuntimeCoordinatorOptions,
|
||||
@@ -126,7 +127,7 @@ export class AgentRuntimeService {
|
||||
private stepCallbacks: Map<string, StepLifecycleCallbacks> = new Map();
|
||||
private get baseURL() {
|
||||
const baseUrl =
|
||||
process.env.AGENT_RUNTIME_BASE_URL || process.env.APP_URL || 'http://localhost:3010';
|
||||
process.env.AGENT_RUNTIME_BASE_URL || appEnv.APP_URL || 'http://localhost:3010';
|
||||
|
||||
return urlJoin(baseUrl, '/api/agent');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user