mirror of
https://github.com/saltbo/zpan.git
synced 2026-08-29 00:01:42 +08:00
4a5fbb7f4a
* feat(auth): add dynamic OAuth provider system Admin can configure OAuth/OIDC providers in the database via API. All 35 built-in better-auth providers are registered as async functions that read config from system_options at runtime. Custom OIDC providers use the genericOAuth plugin with configs loaded at auth init time. New endpoints: - GET /api/auth-providers (public, enabled only, no secrets) - GET /api/auth-providers/admin (admin, all configs, masked secrets) - PUT /api/auth-providers/admin/:providerId (admin, upsert) - DELETE /api/auth-providers/admin/:providerId (admin, remove) Agent-Profile: https://agent-kanban.dev/agents/a6bb038c4226a87f Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: async createTestApp compat in email and invite test files createAuth became async in the OAuth PR, which made createTestApp async. Email and invite code test files need await + Awaited<> type wrappers. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Bob <aibob@mails.agent-kanban.dev> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
80 lines
2.9 KiB
TypeScript
80 lines
2.9 KiB
TypeScript
/**
|
|
* Static display metadata for all built-in better-auth social providers.
|
|
* Used by the frontend to render login buttons with correct names and icons.
|
|
*/
|
|
export const OAuthProviderMeta: Record<string, { name: string; icon: string } | undefined> = {
|
|
apple: { name: 'Apple', icon: 'apple' },
|
|
atlassian: { name: 'Atlassian', icon: 'atlassian' },
|
|
cognito: { name: 'AWS Cognito', icon: 'cognito' },
|
|
discord: { name: 'Discord', icon: 'discord' },
|
|
dropbox: { name: 'Dropbox', icon: 'dropbox' },
|
|
facebook: { name: 'Facebook', icon: 'facebook' },
|
|
figma: { name: 'Figma', icon: 'figma' },
|
|
github: { name: 'GitHub', icon: 'github' },
|
|
gitlab: { name: 'GitLab', icon: 'gitlab' },
|
|
google: { name: 'Google', icon: 'google' },
|
|
huggingface: { name: 'Hugging Face', icon: 'huggingface' },
|
|
kakao: { name: 'Kakao', icon: 'kakao' },
|
|
kick: { name: 'Kick', icon: 'kick' },
|
|
line: { name: 'LINE', icon: 'line' },
|
|
linear: { name: 'Linear', icon: 'linear' },
|
|
linkedin: { name: 'LinkedIn', icon: 'linkedin' },
|
|
microsoft: { name: 'Microsoft', icon: 'microsoft' },
|
|
naver: { name: 'Naver', icon: 'naver' },
|
|
notion: { name: 'Notion', icon: 'notion' },
|
|
paybin: { name: 'Paybin', icon: 'paybin' },
|
|
paypal: { name: 'PayPal', icon: 'paypal' },
|
|
polar: { name: 'Polar', icon: 'polar' },
|
|
railway: { name: 'Railway', icon: 'railway' },
|
|
reddit: { name: 'Reddit', icon: 'reddit' },
|
|
roblox: { name: 'Roblox', icon: 'roblox' },
|
|
salesforce: { name: 'Salesforce', icon: 'salesforce' },
|
|
slack: { name: 'Slack', icon: 'slack' },
|
|
spotify: { name: 'Spotify', icon: 'spotify' },
|
|
tiktok: { name: 'TikTok', icon: 'tiktok' },
|
|
twitch: { name: 'Twitch', icon: 'twitch' },
|
|
twitter: { name: 'Twitter / X', icon: 'twitter' },
|
|
vercel: { name: 'Vercel', icon: 'vercel' },
|
|
vk: { name: 'VK', icon: 'vk' },
|
|
wechat: { name: 'WeChat', icon: 'wechat' },
|
|
zoom: { name: 'Zoom', icon: 'zoom' },
|
|
}
|
|
|
|
/** All built-in provider IDs supported by better-auth */
|
|
export const BUILTIN_PROVIDER_IDS = Object.keys(OAuthProviderMeta) as readonly string[]
|
|
|
|
/** Key prefix for OAuth provider configs stored in system_options */
|
|
export const OAUTH_PROVIDER_KEY_PREFIX = 'oauth_provider_'
|
|
|
|
/** LIKE pattern for querying all OAuth provider configs */
|
|
export const OAUTH_PROVIDER_KEY_PATTERN = `${OAUTH_PROVIDER_KEY_PREFIX}%`
|
|
|
|
/** Regex for valid custom OIDC provider IDs */
|
|
const PROVIDER_ID_RE = /^[a-z0-9-]+$/
|
|
|
|
export function isValidProviderId(id: string): boolean {
|
|
return PROVIDER_ID_RE.test(id)
|
|
}
|
|
|
|
export function parseProviderConfig(value: string): OAuthProviderConfig | null {
|
|
try {
|
|
return JSON.parse(value) as OAuthProviderConfig
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
export type OAuthProviderType = 'builtin' | 'oidc'
|
|
|
|
export interface OAuthProviderConfig {
|
|
providerId: string
|
|
type: OAuthProviderType
|
|
clientId: string
|
|
clientSecret: string
|
|
enabled: boolean
|
|
/** Only for type: 'oidc' */
|
|
discoveryUrl?: string
|
|
/** Only for type: 'oidc' */
|
|
scopes?: string[]
|
|
}
|