@@ -30,6 +30,7 @@ import { AnalyticsServicePlugin } from '@objectstack/service-analytics';
3030import CrmApp from '../../examples/app-crm/objectstack.config' ;
3131import TodoApp from '../../examples/app-todo/objectstack.config' ;
3232import BiPluginManifest from '../../examples/plugin-bi/objectstack.config' ;
33+ import type { SocialProviderConfig , OidcProvidersConfig } from '@objectstack/spec/system' ;
3334import { fileURLToPath } from 'node:url' ;
3435import { dirname , resolve } from 'node:path' ;
3536
@@ -41,6 +42,64 @@ const baseUrl = process.env.NEXT_PUBLIC_BASE_URL
4142 ? `https://${ process . env . VERCEL_URL } ` : undefined )
4243 ?? 'http://localhost:3000' ;
4344
45+ function buildSocialProviders ( ) : SocialProviderConfig | undefined {
46+ const providers : SocialProviderConfig = { } ;
47+ if ( process . env . GOOGLE_CLIENT_ID && process . env . GOOGLE_CLIENT_SECRET ) {
48+ providers . google = {
49+ clientId : process . env . GOOGLE_CLIENT_ID ,
50+ clientSecret : process . env . GOOGLE_CLIENT_SECRET ,
51+ ...( process . env . GOOGLE_OAUTH_SCOPES
52+ ? { scope : process . env . GOOGLE_OAUTH_SCOPES . split ( ',' ) . map ( ( s ) => s . trim ( ) ) }
53+ : { } ) ,
54+ } ;
55+ }
56+ if ( process . env . GITHUB_CLIENT_ID && process . env . GITHUB_CLIENT_SECRET ) {
57+ providers . github = {
58+ clientId : process . env . GITHUB_CLIENT_ID ,
59+ clientSecret : process . env . GITHUB_CLIENT_SECRET ,
60+ } ;
61+ }
62+ if ( process . env . MICROSOFT_CLIENT_ID && process . env . MICROSOFT_CLIENT_SECRET ) {
63+ providers . microsoft = {
64+ clientId : process . env . MICROSOFT_CLIENT_ID ,
65+ clientSecret : process . env . MICROSOFT_CLIENT_SECRET ,
66+ ...( process . env . MICROSOFT_TENANT_ID
67+ ? { tenantId : process . env . MICROSOFT_TENANT_ID }
68+ : { } ) ,
69+ } ;
70+ }
71+ if ( process . env . APPLE_CLIENT_ID && process . env . APPLE_CLIENT_SECRET ) {
72+ providers . apple = {
73+ clientId : process . env . APPLE_CLIENT_ID ,
74+ clientSecret : process . env . APPLE_CLIENT_SECRET ,
75+ } ;
76+ }
77+ const keys = Object . keys ( providers ) ;
78+ if ( keys . length > 0 ) {
79+ console . info ( `[auth] enabled social providers: ${ keys . join ( ', ' ) } ` ) ;
80+ return providers ;
81+ }
82+ return undefined ;
83+ }
84+
85+ function buildOidcProviders ( ) : OidcProvidersConfig | undefined {
86+ const raw = process . env . OIDC_PROVIDERS ;
87+ if ( ! raw ) return undefined ;
88+ try {
89+ const parsed = JSON . parse ( raw ) as OidcProvidersConfig ;
90+ if ( Array . isArray ( parsed ) && parsed . length > 0 ) {
91+ console . info ( `[auth] enabled OIDC providers: ${ parsed . map ( p => p . providerId ) . join ( ', ' ) } ` ) ;
92+ return parsed ;
93+ }
94+ } catch {
95+ console . warn ( '[auth] Failed to parse OIDC_PROVIDERS env var — expected a JSON array' ) ;
96+ }
97+ return undefined ;
98+ }
99+
100+ const socialProviders = buildSocialProviders ( ) ;
101+ const oidcProviders = buildOidcProviders ( ) ;
102+
44103// Turso driver for sys namespace — remote when env vars are configured, local SQLite otherwise
45104const __dirname = dirname ( fileURLToPath ( import . meta. url ) ) ;
46105const tursoDriver = new TursoDriver (
@@ -99,6 +158,8 @@ export default defineStack({
99158 secret : process . env . AUTH_SECRET ?? 'dev-secret-please-change-in-production-min-32-chars' ,
100159 baseUrl,
101160 plugins : { organization : true } ,
161+ ...( socialProviders ? { socialProviders } : { } ) ,
162+ ...( oidcProviders ? { oidcProviders } : { } ) ,
102163 } ) ,
103164 new SecurityPlugin ( ) ,
104165 new AuditPlugin ( ) ,
0 commit comments