feat: remove start.sh script and add appearance preferences management

- Deleted the start.sh script for container management.
- Added AGENTS.md for project guidelines and development principles.
- Introduced new SQL migration files for user appearance preferences and platform settings.
- Implemented appearance provider to manage user interface themes and preferences.
- Created branding utility to define and manage branding-related constants and types.

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
2026-04-27 22:12:16 -04:00
parent b582b6c88e
commit fbeca7cfee
39 changed files with 3388 additions and 977 deletions
+53 -45
View File
@@ -5,55 +5,63 @@ import { genericOAuth } from "better-auth/plugins";
import { db } from "~/server/db";
import * as schema from "~/server/db/schema";
const authentikEnabled = Boolean(
process.env.AUTHENTIK_ISSUER &&
process.env.AUTHENTIK_CLIENT_ID &&
process.env.AUTHENTIK_CLIENT_SECRET,
);
export const auth = betterAuth({
database: drizzleAdapter(db, {
provider: "pg",
schema: {
user: schema.users,
session: schema.sessions,
account: schema.accounts,
verification: schema.verificationTokens,
ssoProvider: schema.ssoProviders,
},
}),
trustedOrigins: [
"https://beenvoice.soconnor.dev",
"https://auth.soconnor.dev", // Authentik IdP for OIDC discovery
],
database: drizzleAdapter(db, {
provider: "pg",
schema: {
user: schema.users,
session: schema.sessions,
account: schema.accounts,
verification: schema.verificationTokens,
ssoProvider: schema.ssoProviders,
},
}),
trustedOrigins: [
"https://beenvoice.soconnor.dev",
...(process.env.AUTHENTIK_ORIGIN ? [process.env.AUTHENTIK_ORIGIN] : []),
],
...(authentikEnabled && {
accountLinking: {
enabled: true,
trustedProviders: ["authentik"],
enabled: true,
trustedProviders: ["authentik"],
},
emailAndPassword: {
enabled: true,
password: {
hash: async (password) => {
const bcrypt = await import("bcryptjs");
return bcrypt.hash(password, 12);
},
verify: async ({ hash, password }) => {
const bcrypt = await import("bcryptjs");
return bcrypt.compare(password, hash);
},
},
}),
emailAndPassword: {
enabled: true,
password: {
hash: async (password) => {
const bcrypt = await import("bcryptjs");
return bcrypt.hash(password, 12);
},
verify: async ({ hash, password }) => {
const bcrypt = await import("bcryptjs");
return bcrypt.compare(password, hash);
},
},
plugins: [
nextCookies(),
genericOAuth({
},
plugins: [
nextCookies(),
...(authentikEnabled
? [
genericOAuth({
config: [
{
providerId: "authentik",
clientId: process.env.AUTHENTIK_CLIENT_ID!,
clientSecret: process.env.AUTHENTIK_CLIENT_SECRET!,
discoveryUrl: `${process.env.AUTHENTIK_ISSUER}/.well-known/openid-configuration`,
// Explicit endpoints to ensure correct routing in production
authorizationUrl: "https://auth.soconnor.dev/application/o/authorize/",
tokenUrl: "https://auth.soconnor.dev/application/o/token/",
userInfoUrl: "https://auth.soconnor.dev/application/o/userinfo/",
scopes: ["openid", "email", "profile"],
pkce: true,
},
{
providerId: "authentik",
clientId: process.env.AUTHENTIK_CLIENT_ID!,
clientSecret: process.env.AUTHENTIK_CLIENT_SECRET!,
discoveryUrl: `${process.env.AUTHENTIK_ISSUER}/.well-known/openid-configuration`,
scopes: ["openid", "email", "profile"],
pkce: true,
},
],
}),
],
}),
]
: []),
],
});