Implement Single Sign-On (SSO) Feature: Add SSO settings page, integrate OIDC provider registration dialog, and update dependencies for better-auth to version 1.4.18. Enhance user interface with new SSO menu item and improve database schema for SSO providers.

This commit is contained in:
Mauricio Siu
2026-01-29 22:01:48 -06:00
parent 2e7f4dc1a2
commit 7f27601f7f
18 changed files with 9691 additions and 281 deletions

View File

@@ -34,6 +34,5 @@ if (DATABASE_URL) {
Please migrate to Docker Secrets using POSTGRES_PASSWORD_FILE.
Please execute this command in your server: curl -sSL https://dokploy.com/security/0.26.6.sh | bash
`);
dbUrl =
"postgres://dokploy:amukds4wi9001583845717ad2@dokploy-postgres:5432/dokploy";
dbUrl = "postgres://dokploy:amukds4wi9001583845717ad2@localhost:5432/dokploy";
}

View File

@@ -203,3 +203,21 @@ export const apikeyRelations = relations(apikey, ({ one }) => ({
references: [user.id],
}),
}));
export const ssoProvider = pgTable("sso_provider", {
id: text("id").primaryKey(),
issuer: text("issuer").notNull(),
oidcConfig: text("oidc_config"),
samlConfig: text("saml_config"),
userId: text("user_id").references(() => user.id, { onDelete: "cascade" }),
providerId: text("provider_id").notNull().unique(),
organizationId: text("organization_id"),
domain: text("domain").notNull(),
});
export const ssoProviderRelations = relations(ssoProvider, ({ one }) => ({
user: one(user, {
fields: [ssoProvider.userId],
references: [user.id],
}),
}));

View File

@@ -10,7 +10,7 @@ import {
import { createInsertSchema } from "drizzle-zod";
import { nanoid } from "nanoid";
import { z } from "zod";
import { account, apikey, organization } from "./account";
import { account, apikey, organization, ssoProvider } from "./account";
import { backups } from "./backups";
import { projects } from "./project";
import { schedules } from "./schedule";
@@ -69,6 +69,7 @@ export const usersRelations = relations(user, ({ one, many }) => ({
references: [account.userId],
}),
organizations: many(organization),
ssoProviders: many(ssoProvider),
projects: many(projects),
apiKeys: many(apikey),
backups: many(backups),

View File

@@ -1,4 +1,5 @@
import type { IncomingMessage } from "node:http";
import { sso } from "@better-auth/sso";
import * as bcrypt from "bcrypt";
import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
@@ -17,7 +18,7 @@ import { getHubSpotUTK, submitToHubSpot } from "../utils/tracking/hubspot";
import { sendEmail } from "../verification/send-verification-email";
import { getPublicIpWithFallback } from "../wss/utils";
const { handler, api } = betterAuth({
export const { handler, api } = betterAuth({
database: drizzleAdapter(db, {
provider: "pg",
schema: schema,
@@ -240,6 +241,7 @@ const { handler, api } = betterAuth({
apiKey({
enableMetadata: true,
}),
sso(),
twoFactor(),
organization({
async sendInvitationEmail(data, _request) {