Compare commits

...

12 Commits

Author SHA1 Message Date
Jamie Stivala f8ab18d8da Merge pull request #47 from jaworldwideorg/test/includes
🔨 tests - Updated tests to use deep array matching
2025-03-19 13:50:09 +01:00
Jamie Stivala 965d2829eb Updated tests to use deep array matching 2025-03-19 13:37:31 +01:00
Jamie Stivala 33e9767c16 Merge pull request #44 from jaworldwideorg/chore/ci-updates
📝 docs & 🔨 chore: Added a way to run Docker Local Development and Fixed CI/CD to work with Azure ACR
2025-03-19 11:58:55 +01:00
Jamie Stivala 70e54c98bf Updated package.json reference 2025-03-19 11:56:36 +01:00
Jamie Stivala 49f1b97b67 Merge pull request #43 from jaworldwideorg/feat/okta-oidc
 feat - Added Okta as an OIDC Provider
2025-03-19 11:52:52 +01:00
Jamie Stivala 0ed5a6b5ec Updated Lighthouse repo branch 2025-03-19 11:48:13 +01:00
Jamie Stivala bec44875f7 Updated docker-database builder location 2025-03-19 11:47:53 +01:00
Jamie Stivala f849d0e102 Fixed syncing upstream branch 2025-03-19 11:47:35 +01:00
Jamie Stivala 15102da85d Remove NPM from Semantic Release 2025-03-19 11:47:04 +01:00
Jamie Stivala 7eee6d1cb2 Added a way to run local development 2025-03-19 11:42:22 +01:00
Jamie Stivala b0e8c4fbb8 Updated documentation 2025-03-19 11:15:23 +01:00
Jamie Stivala f1468b7d5a Added Okta as an SSO Provider 2025-03-19 11:14:41 +01:00
15 changed files with 490 additions and 22 deletions
+8 -5
View File
@@ -12,7 +12,8 @@ concurrency:
cancel-in-progress: true
env:
REGISTRY_IMAGE: lobehub/lobe-chat-database
REGISTRY_URL: onejaacr.azurecr.io
REGISTRY_IMAGE: onejaacr.azurecr.io/ai/oneja-bot-database
PR_TAG_PREFIX: pr-
jobs:
@@ -70,8 +71,9 @@ jobs:
- name: Docker login
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_REGISTRY_USER }}
password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
registry: ${{ env.REGISTRY_URL }}
username: ${{ secrets.CONTAINER_REGISTRY_USER }}
password: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }}
- name: Get commit SHA
if: github.ref == 'refs/heads/main'
@@ -147,8 +149,9 @@ jobs:
- name: Docker login
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_REGISTRY_USER }}
password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
registry: ${{ env.REGISTRY_URL }}
username: ${{ secrets.CONTAINER_REGISTRY_USER }}
password: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }}
- name: Create manifest list and push
working-directory: /tmp/digests
+1 -1
View File
@@ -2,7 +2,7 @@ name: Lighthouse Badger
env:
TOKEN_NAME: 'GH_TOKEN'
REPO_BRANCH: 'lobehub/lobe-chat lighthouse'
REPO_BRANCH: 'jaworldwideorg/OneJA-Bot lighthouse'
USER_NAME: 'lobehubbot'
USER_EMAIL: 'i@lobehub.com'
AUDIT_TYPE: 'both'
+1 -1
View File
@@ -31,7 +31,7 @@ jobs:
with:
upstream_sync_repo: lobehub/lobe-chat
upstream_sync_branch: main
target_sync_branch: main
target_sync_branch: upstream
target_repo_token: ${{ secrets.GITHUB_TOKEN }} # automatically generated, no need to set
test_mode: false
+5
View File
@@ -1,5 +1,10 @@
const config = require('@lobehub/lint').semanticRelease;
// Remove NPM publishing by excluding "@semantic-release/npm" plugin
// Keep or add other plugins like GitHub Releases
config.plugins = config.plugins.filter((plugin) => plugin !== '@semantic-release/npm');
// Add GitHub only if required
config.plugins.push([
'@semantic-release/exec',
{
+41
View File
@@ -0,0 +1,41 @@
# Proxy, if you need it
# HTTP_PROXY=http://localhost:7890
# HTTPS_PROXY=http://localhost:7890
# Other environment variables, as needed. You can refer to the environment variables configuration for the client version, making sure not to have ACCESS_CODE.
# OPENAI_API_KEY=sk-xxxx
# OPENAI_PROXY_URL=https://api.openai.com/v1
# OPENAI_MODEL_LIST=...
# ===========================
# ====== Preset config ======
# ===========================
# if no special requirements, no need to change
LOBE_PORT=3210
CASDOOR_PORT=8000
MINIO_PORT=9000
APP_URL=http://localhost:3210
AUTH_URL=http://localhost:3210/api/auth
# Postgres related, which are the necessary environment variables for DB
LOBE_DB_NAME=lobechat
POSTGRES_PASSWORD=uWNZugjBqixf8dxC
# MinIO S3 configuration
MINIO_ROOT_USER=admin
MINIO_ROOT_PASSWORD=YOUR_MINIO_PASSWORD
# Configure the bucket information of MinIO
S3_PUBLIC_DOMAIN=http://localhost:9000
S3_ENDPOINT=http://localhost:9000
MINIO_LOBE_BUCKET=lobe
#Configure OIDC
NEXT_AUTH_SSO_PROVIDERS=okta
NEXTAUTH_URL=http://localhost:3210/api/auth
AUTH_OKTA_ID=ndfvkndfk3489349
AUTH_OKTA_SECRET=-98494-8d093498d_njkefiuJKSAK-KJ9843JNDSiud78932-JKDSU929
AUTH_OKTA_ISSUER=https://dev1234.okta.com
@@ -0,0 +1,220 @@
## Set global build ENV
ARG NODEJS_VERSION="22"
## Base image for all stages
FROM node:${NODEJS_VERSION}-slim AS base
ARG USE_CN_MIRROR
ARG NEXT_PUBLIC_BASE_PATH
ARG NEXT_PUBLIC_SERVICE_MODE
ARG NEXT_PUBLIC_ENABLE_NEXT_AUTH
ARG NEXT_PUBLIC_SENTRY_DSN
ARG NEXT_PUBLIC_ANALYTICS_POSTHOG
ARG NEXT_PUBLIC_POSTHOG_HOST
ARG NEXT_PUBLIC_POSTHOG_KEY
ARG NEXT_PUBLIC_ANALYTICS_UMAMI
ARG NEXT_PUBLIC_UMAMI_SCRIPT_URL
ARG NEXT_PUBLIC_UMAMI_WEBSITE_ID
ENV DEBIAN_FRONTEND="noninteractive"
ENV NEXT_PUBLIC_BASE_PATH="${NEXT_PUBLIC_BASE_PATH}"
ENV NEXT_PUBLIC_SERVICE_MODE="${NEXT_PUBLIC_SERVICE_MODE:-server}" \
NEXT_PUBLIC_ENABLE_NEXT_AUTH="${NEXT_PUBLIC_ENABLE_NEXT_AUTH:-1}" \
APP_URL="http://app.com" \
DATABASE_DRIVER="node" \
DATABASE_URL="postgres://postgres:password@localhost:5432/postgres" \
KEY_VAULTS_SECRET="use-for-build"
# Sentry
ENV NEXT_PUBLIC_SENTRY_DSN="${NEXT_PUBLIC_SENTRY_DSN}" \
SENTRY_ORG="" \
SENTRY_PROJECT=""
# Posthog
ENV NEXT_PUBLIC_ANALYTICS_POSTHOG="${NEXT_PUBLIC_ANALYTICS_POSTHOG}" \
NEXT_PUBLIC_POSTHOG_HOST="${NEXT_PUBLIC_POSTHOG_HOST}" \
NEXT_PUBLIC_POSTHOG_KEY="${NEXT_PUBLIC_POSTHOG_KEY}"
# Umami
ENV NEXT_PUBLIC_ANALYTICS_UMAMI="${NEXT_PUBLIC_ANALYTICS_UMAMI}" \
NEXT_PUBLIC_UMAMI_SCRIPT_URL="${NEXT_PUBLIC_UMAMI_SCRIPT_URL}" \
NEXT_PUBLIC_UMAMI_WEBSITE_ID="${NEXT_PUBLIC_UMAMI_WEBSITE_ID}"
# Node
ENV NODE_OPTIONS="--max-old-space-size=8192"
WORKDIR /app
COPY package.json pnpm-workspace.yaml ./
COPY .npmrc ./
COPY packages ./packages
RUN \
# If you want to build docker in China, build with --build-arg USE_CN_MIRROR=true
if [ "${USE_CN_MIRROR:-false}" = "true" ]; then \
sed -i "s/deb.debian.org/mirrors.ustc.edu.cn/g" "/etc/apt/sources.list.d/debian.sources"; \
fi \
# Add required package
&& apt update \
&& apt install ca-certificates proxychains-ng -qy
RUN \
# If you want to build docker in China, build with --build-arg USE_CN_MIRROR=true
if [ "${USE_CN_MIRROR:-false}" = "true" ]; then \
export SENTRYCLI_CDNURL="https://npmmirror.com/mirrors/sentry-cli"; \
npm config set registry "https://registry.npmmirror.com/"; \
echo 'canvas_binary_host_mirror=https://npmmirror.com/mirrors/canvas' >> .npmrc; \
fi \
# Set the registry for corepack
&& export COREPACK_NPM_REGISTRY=$(npm config get registry | sed 's/\/$//') \
# Update corepack to latest (nodejs/corepack#612)
&& npm i -g corepack@latest \
# Enable corepack
&& corepack enable \
# Use pnpm for corepack
&& corepack use $(sed -n 's/.*"packageManager": "\(.*\)".*/\1/p' package.json) \
# Install the dependencies
&& pnpm i \
# Add db migration dependencies
&& mkdir -p /deps \
&& cd /deps \
&& pnpm init \
&& pnpm add pg drizzle-orm
COPY . .
ENV NODE_ENV="development" \
NODE_OPTIONS="--dns-result-order=ipv4first --use-openssl-ca" \
NODE_EXTRA_CA_CERTS="" \
NODE_TLS_REJECT_UNAUTHORIZED="" \
SSL_CERT_DIR="/etc/ssl/certs/ca-certificates.crt"
# Make the middleware rewrite through local as default
# refs: https://github.com/lobehub/lobe-chat/issues/5876
ENV MIDDLEWARE_REWRITE_THROUGH_LOCAL="1"
# set hostname to localhost
ENV HOSTNAME="0.0.0.0" \
PORT="3210"
# General Variables
ENV ACCESS_CODE="" \
APP_URL="" \
API_KEY_SELECT_MODE="" \
DEFAULT_AGENT_CONFIG="" \
SYSTEM_AGENT="" \
FEATURE_FLAGS="" \
PROXY_URL=""
# Database
ENV KEY_VAULTS_SECRET="" \
DATABASE_DRIVER="node" \
DATABASE_URL=""
# Next Auth
ENV NEXT_AUTH_SECRET="" \
NEXT_AUTH_SSO_PROVIDERS="" \
NEXTAUTH_URL=""
# S3
ENV NEXT_PUBLIC_S3_DOMAIN="" \
S3_PUBLIC_DOMAIN="" \
S3_ACCESS_KEY_ID="" \
S3_BUCKET="" \
S3_ENDPOINT="" \
S3_SECRET_ACCESS_KEY=""
# Model Variables
ENV \
# AI21
AI21_API_KEY="" AI21_MODEL_LIST="" \
# Ai360
AI360_API_KEY="" AI360_MODEL_LIST="" \
# Anthropic
ANTHROPIC_API_KEY="" ANTHROPIC_MODEL_LIST="" ANTHROPIC_PROXY_URL="" \
# Amazon Bedrock
AWS_ACCESS_KEY_ID="" AWS_SECRET_ACCESS_KEY="" AWS_REGION="" AWS_BEDROCK_MODEL_LIST="" \
# Azure OpenAI
AZURE_API_KEY="" AZURE_API_VERSION="" AZURE_ENDPOINT="" AZURE_MODEL_LIST="" \
# Baichuan
BAICHUAN_API_KEY="" BAICHUAN_MODEL_LIST="" \
# Cloudflare
CLOUDFLARE_API_KEY="" CLOUDFLARE_BASE_URL_OR_ACCOUNT_ID="" CLOUDFLARE_MODEL_LIST="" \
# DeepSeek
DEEPSEEK_API_KEY="" DEEPSEEK_MODEL_LIST="" \
# Fireworks AI
FIREWORKSAI_API_KEY="" FIREWORKSAI_MODEL_LIST="" \
# Gitee AI
GITEE_AI_API_KEY="" GITEE_AI_MODEL_LIST="" \
# GitHub
GITHUB_TOKEN="" GITHUB_MODEL_LIST="" \
# Google
GOOGLE_API_KEY="" GOOGLE_MODEL_LIST="" GOOGLE_PROXY_URL="" \
# Groq
GROQ_API_KEY="" GROQ_MODEL_LIST="" GROQ_PROXY_URL="" \
# Higress
HIGRESS_API_KEY="" HIGRESS_MODEL_LIST="" HIGRESS_PROXY_URL="" \
# HuggingFace
HUGGINGFACE_API_KEY="" HUGGINGFACE_MODEL_LIST="" HUGGINGFACE_PROXY_URL="" \
# Hunyuan
HUNYUAN_API_KEY="" HUNYUAN_MODEL_LIST="" \
# InternLM
INTERNLM_API_KEY="" INTERNLM_MODEL_LIST="" \
# Jina
JINA_API_KEY="" JINA_MODEL_LIST="" JINA_PROXY_URL="" \
# Minimax
MINIMAX_API_KEY="" MINIMAX_MODEL_LIST="" \
# Mistral
MISTRAL_API_KEY="" MISTRAL_MODEL_LIST="" \
# Moonshot
MOONSHOT_API_KEY="" MOONSHOT_MODEL_LIST="" MOONSHOT_PROXY_URL="" \
# Novita
NOVITA_API_KEY="" NOVITA_MODEL_LIST="" \
# Nvidia NIM
NVIDIA_API_KEY="" NVIDIA_MODEL_LIST="" NVIDIA_PROXY_URL="" \
# Ollama
ENABLED_OLLAMA="" OLLAMA_MODEL_LIST="" OLLAMA_PROXY_URL="" \
# OpenAI
OPENAI_API_KEY="" OPENAI_MODEL_LIST="" OPENAI_PROXY_URL="" \
# OpenRouter
OPENROUTER_API_KEY="" OPENROUTER_MODEL_LIST="" \
# Perplexity
PERPLEXITY_API_KEY="" PERPLEXITY_MODEL_LIST="" PERPLEXITY_PROXY_URL="" \
# PPIO
PPIO_API_KEY="" PPIO_MODEL_LIST="" \
# Qwen
QWEN_API_KEY="" QWEN_MODEL_LIST="" QWEN_PROXY_URL="" \
# SambaNova
SAMBANOVA_API_KEY="" SAMBANOVA_MODEL_LIST="" \
# SenseNova
SENSENOVA_API_KEY="" SENSENOVA_MODEL_LIST="" \
# SiliconCloud
SILICONCLOUD_API_KEY="" SILICONCLOUD_MODEL_LIST="" SILICONCLOUD_PROXY_URL="" \
# Spark
SPARK_API_KEY="" SPARK_MODEL_LIST="" \
# Stepfun
STEPFUN_API_KEY="" STEPFUN_MODEL_LIST="" \
# Taichu
TAICHU_API_KEY="" TAICHU_MODEL_LIST="" \
# TogetherAI
TOGETHERAI_API_KEY="" TOGETHERAI_MODEL_LIST="" \
# Upstage
UPSTAGE_API_KEY="" UPSTAGE_MODEL_LIST="" \
# vLLM
VLLM_API_KEY="" VLLM_MODEL_LIST="" VLLM_PROXY_URL="" \
# Wenxin
WENXIN_API_KEY="" WENXIN_MODEL_LIST="" \
# xAI
XAI_API_KEY="" XAI_MODEL_LIST="" XAI_PROXY_URL="" \
# 01.AI
ZEROONE_API_KEY="" ZEROONE_MODEL_LIST="" \
# Zhipu
ZHIPU_API_KEY="" ZHIPU_MODEL_LIST="" \
# Tencent Cloud
TENCENT_CLOUD_API_KEY="" TENCENT_CLOUD_MODEL_LIST=""
EXPOSE 3210/tcp
ENTRYPOINT ["sh", "-c", "npm run db:migrate && npm run dev -- --turbopack -p 3210"]
@@ -0,0 +1,99 @@
name: LobeChat-Database-Barebones
services:
network-service:
image: alpine
container_name: lobe-network
restart: always
ports:
- '${MINIO_PORT}:${MINIO_PORT}' # MinIO API
- '9001:9001' # MinIO Console
- '${CASDOOR_PORT}:${CASDOOR_PORT}' # Casdoor
- '${LOBE_PORT}:3210' # LobeChat
command: tail -f /dev/null
networks:
- lobe-network
postgresql:
image: pgvector/pgvector:pg17
container_name: lobe-postgres
ports:
- '5432:5432'
volumes:
- './data:/var/lib/postgresql/data'
environment:
- 'POSTGRES_DB=${LOBE_DB_NAME}'
- 'POSTGRES_PASSWORD=${POSTGRES_PASSWORD}'
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U postgres']
interval: 5s
timeout: 5s
retries: 5
restart: always
networks:
- lobe-network
minio:
image: minio/minio
container_name: lobe-minio
network_mode: 'service:network-service'
volumes:
- './s3_data:/etc/minio/data'
environment:
- 'MINIO_API_CORS_ALLOW_ORIGIN=*'
env_file:
- .env
restart: always
entrypoint: >
/bin/sh -c "
minio server /etc/minio/data --address ':${MINIO_PORT}' --console-address ':9001' &
MINIO_PID=\$!
while ! curl -s http://localhost:${MINIO_PORT}/minio/health/live; do
echo 'Waiting for MinIO to start...'
sleep 1
done
sleep 5
mc alias set myminio http://localhost:${MINIO_PORT} ${MINIO_ROOT_USER} ${MINIO_ROOT_PASSWORD}
echo 'Creating bucket ${MINIO_LOBE_BUCKET}'
mc mb myminio/${MINIO_LOBE_BUCKET}
wait \$MINIO_PID
"
lobe:
build:
context: ../../
dockerfile: docker-compose/barebones/Dockerfile.database
container_name: lobe-chat
network_mode: 'service:network-service'
depends_on:
postgresql:
condition: service_healthy
network-service:
condition: service_started
minio:
condition: service_started
environment:
- 'NEXT_PUBLIC_ENABLE_NEXT_AUTH=1'
- 'KEY_VAULTS_SECRET=Kix2wcUONd4CX51E/ZPAd36BqM4wzJgKjPtz2sGztqQ='
- 'NEXT_AUTH_SECRET=NX2kaPE923dt6BL2U8e9oSre5RfoT7hg'
- 'DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgresql:5432/${LOBE_DB_NAME}'
- 'S3_BUCKET=${MINIO_LOBE_BUCKET}'
- 'S3_ENABLE_PATH_STYLE=1'
- 'S3_ACCESS_KEY=${MINIO_ROOT_USER}'
- 'S3_ACCESS_KEY_ID=${MINIO_ROOT_USER}'
- 'S3_SECRET_ACCESS_KEY=${MINIO_ROOT_PASSWORD}'
- 'LLM_VISION_IMAGE_USE_BASE64=1'
- 'S3_SET_ACL=0'
env_file:
- .env
restart: always
volumes:
data:
driver: local
s3_data:
driver: local
networks:
lobe-network:
driver: bridge
@@ -39,9 +39,9 @@ LobeChat provides a complete authentication service capability when deployed. Th
#### `NEXT_AUTH_SSO_PROVIDERS`
- Type: Optional
- Description: Select the single sign-on provider for LoboChat. For multiple SSO Providers separating them with commas, for example, `auth0,microsoft-entra-id,authentik`.
- Description: Select the single sign-on provider for LobeChat. For multiple SSO Providers separating them with commas, for example, `auth0,microsoft-entra-id,authentik`.
- Default: `auth0`
- Example: `auth0,microsoft-entra-id,authentik`
- Example: `auth0,microsoft-entra-id,authentik,okta`
#### `NEXTAUTH_URL`
@@ -250,6 +250,29 @@ LobeChat provides a complete authentication service capability when deployed. Th
- Default: `-`
- Example: `https://your-instance-abc123.zitadel.cloud`
### OKTA
#### `AUTH_OKTA_ID`
- Type: Required
- Description: Client ID of the OKTA application. This can be found under your application in the OKTA console.
- Default: `-`
- Example: `evCnOJP1UX8FMnXR9Xkj5t0NyFn5p70P`
#### `AUTH_OKTA_SECRET`
- Type: Required
- Description: Client Secret of the OKTA application.
- Default: `-`
- Example: `wnX7UbZg85ZUzF6ioxPLnJVEQa1Elbs7aqBUSF16xleBS5AdkVfASS49-fQIC8Rm`
#### `AUTH_OKTA_ISSUER`
- Type: Required
- Description: Issuer/domain of the OKTA application.
- Default: `-`
- Example: `https://dev1234.okta.com`
### Generic OIDC
#### `AUTH_GENERIC_OIDC_ID`
+9 -9
View File
@@ -1,7 +1,7 @@
{
"name": "@lobehub/chat",
"name": "@jaworldwide/oneja/ai",
"version": "1.72.1",
"description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
"description": "OneJA AI powered by Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
"keywords": [
"framework",
"chatbot",
@@ -14,27 +14,27 @@
"tts",
"stt"
],
"homepage": "https://github.com/lobehub/lobe-chat",
"homepage": "https://github.com/jaworldwideorg/oneja-bot",
"bugs": {
"url": "https://github.com/lobehub/lobe-chat/issues/new/choose"
"url": "https://github.com/jaworldwideorg/oneja-bot/issues/new/choose"
},
"repository": {
"type": "git",
"url": "https://github.com/lobehub/lobe-chat.git"
"url": "https://github.com/jaworldwideorg/OneJA-Bot.git"
},
"license": "MIT",
"author": "LobeHub <i@lobehub.com>",
"author": "LobeHub <i@lobehub.com>, Jamie Stivala <jamie.stivala@jaworldwide.org>",
"sideEffects": false,
"workspaces": [
"packages/*"
],
"scripts": {
"build": "next build",
"build:analyze": "ANALYZE=true next build",
"build:docker": "DOCKER=true next build && npm run build-sitemap",
"postbuild": "npm run build-sitemap && npm run build-migrate-db",
"build-migrate-db": "bun run db:migrate",
"build-sitemap": "tsx ./scripts/buildSitemapIndex/index.ts",
"build:analyze": "ANALYZE=true next build",
"build:docker": "DOCKER=true next build && npm run build-sitemap",
"db:generate": "drizzle-kit generate && npm run db:generate-client && npm run workflow:dbml",
"db:generate-client": "tsx ./scripts/migrateClientDB/compile-migrations.ts",
"db:migrate": "MIGRATION_DB=1 tsx ./scripts/migrateServerDB/index.ts",
@@ -63,11 +63,11 @@
"start": "next start -p 3210",
"stylelint": "stylelint \"src/**/*.{js,jsx,ts,tsx}\" --fix",
"test": "npm run test-app && npm run test-server",
"test:update": "vitest -u",
"test-app": "vitest run --config vitest.config.ts",
"test-app:coverage": "vitest run --config vitest.config.ts --coverage",
"test-server": "TEST_SERVER_DB=1 vitest run --config vitest.server.config.ts",
"test-server:coverage": "TEST_SERVER_DB=1 vitest run --config vitest.server.config.ts --coverage",
"test:update": "vitest -u",
"type-check": "tsc --noEmit",
"webhook:ngrok": "ngrok http http://localhost:3011",
"workflow:cdn": "tsx ./scripts/cdnWorkflow/index.ts",
+19
View File
@@ -196,5 +196,24 @@ describe('getAuthConfig', () => {
);
});
});
it('should warn about Okta deprecated environment variables', () => {
// Set all deprecated environment variables
process.env.OKTA_CLIENT_ID = 'okta_client_id';
process.env.OKTA_CLIENT_SECRET = 'okta_client_secret';
process.env.OKTA_ISSUER = 'okta_issuer';
// Call the function
getAuthConfig();
// Check that the spyConsoleWarn function was called for each deprecated environment variable
expect(spyConsoleWarn).toHaveBeenCalledWith(
expect.stringMatching(/OKTA_CLIENT_ID.*AUTH_OKTA_ID/),
);
expect(spyConsoleWarn).toHaveBeenCalledWith(
expect.stringMatching(/OKTA_CLIENT_SECRET.*AUTH_OKTA_SECRET/),
);
expect(spyConsoleWarn).toHaveBeenCalledWith(
expect.stringMatching(/OKTA_ISSUER.*AUTH_OKTA_ISSUER/),
);
});
// Remove end
});
+24
View File
@@ -40,6 +40,11 @@ declare global {
ZITADEL_CLIENT_ID?: string;
ZITADEL_CLIENT_SECRET?: string;
ZITADEL_ISSUER?: string;
//Okta
OKTA_CLIENT_ID?: string;
OKTA_CLIENT_SECRET?: string;
OKTA_ISSUER?: string;
}
}
}
@@ -138,6 +143,15 @@ export const getAuthConfig = () => {
if (process.env.ZITADEL_ISSUER) {
console.warn(removeTipsTemplate('ZITADEL_ISSUER', 'AUTH_ZITADEL_ISSUER'));
}
if (process.env.OKTA_CLIENT_ID) {
console.warn(removeTipsTemplate('OKTA_CLIENT_ID', 'AUTH_OKTA_ID'));
}
if (process.env.OKTA_CLIENT_SECRET) {
console.warn(removeTipsTemplate('OKTA_CLIENT_SECRET', 'AUTH_OKTA_SECRET'));
}
if (process.env.OKTA_ISSUER) {
console.warn(removeTipsTemplate('OKTA_ISSUER', 'AUTH_OKTA_ISSUER'));
}
// End
return createEnv({
@@ -199,6 +213,11 @@ export const getAuthConfig = () => {
ZITADEL_CLIENT_SECRET: z.string().optional(),
ZITADEL_ISSUER: z.string().optional(),
// Okta
OKTA_CLIENT_ID: z.string().optional(),
OKTA_CLIENT_SECRET: z.string().optional(),
OKTA_ISSUER: z.string().optional(),
// LOGTO
LOGTO_CLIENT_ID: z.string().optional(),
LOGTO_CLIENT_SECRET: z.string().optional(),
@@ -261,6 +280,11 @@ export const getAuthConfig = () => {
ZITADEL_CLIENT_SECRET: process.env.ZITADEL_CLIENT_SECRET,
ZITADEL_ISSUER: process.env.ZITADEL_ISSUER,
// Okta
OKTA_CLIENT_ID: process.env.OKTA_CLIENT_ID,
OKTA_CLIENT_SECRET: process.env.OKTA_CLIENT_SECRET,
OKTA_ISSUER: process.env.OKTA_ISSUER,
// LOGTO
LOGTO_CLIENT_ID: process.env.LOGTO_CLIENT_ID,
LOGTO_CLIENT_SECRET: process.env.LOGTO_CLIENT_SECRET,
@@ -100,8 +100,10 @@ describe('AiProviderModel', () => {
const userGroups = await aiProviderModel.query();
expect(userGroups).toHaveLength(2);
expect(userGroups[0].id).toBe('aihubmix-2');
expect(userGroups[1].id).toBe('aihubmix');
expect(userGroups.map((group) => group.id)).toEqual(
expect.arrayContaining(['aihubmix', 'aihubmix-2']),
);
});
});
@@ -97,8 +97,10 @@ describe('KnowledgeBaseModel', () => {
const userGroups = await knowledgeBaseModel.query();
expect(userGroups).toHaveLength(2);
expect(userGroups[0].name).toBe('Test Group 2');
expect(userGroups[1].name).toBe('Test Group 1');
expect(userGroups.map((group) => group.name)).toEqual(
expect.arrayContaining(['Test Group 1', 'Test Group 2']),
);
});
});
@@ -8,6 +8,7 @@ import GenericOIDC from './generic-oidc';
import Github from './github';
import Logto from './logto';
import MicrosoftEntraID from './microsoft-entra-id';
import Okta from './okta';
import WeChat from './wechat';
import Zitadel from './zitadel';
@@ -24,4 +25,5 @@ export const ssoProviders = [
Casdoor,
MicrosoftEntraID,
WeChat,
Okta,
];
+28
View File
@@ -0,0 +1,28 @@
import Okta from 'next-auth/providers/okta';
import { authEnv } from '@/config/auth';
import { CommonProviderConfig } from './sso.config';
const provider = {
id: 'okta',
provider: Okta({
...CommonProviderConfig,
authorization: { params: { scope: 'openid email profile' } },
clientId: authEnv.OKTA_CLIENT_ID ?? process.env.AUTH_OKTA_ID,
clientSecret: authEnv.OKTA_CLIENT_SECRET ?? process.env.AUTH_OKTA_SECRET,
issuer: authEnv.OKTA_ISSUER ?? process.env.AUTH_OKTA_ISSUER,
// Remove End
profile(profile) {
return {
email: profile.email,
id: profile.sub,
image: profile.picture,
name: profile.name ?? profile.preferred_username,
providerAccountId: profile.sub,
};
},
}),
};
export default provider;