providers.ts230 lines · main
1/**
2 * briven-engine social provider catalog (Phase 3).
3 *
4 * Built-in third-party ids the product supports. Customer secrets are stored
5 * per project (later UI); empty providers list at boot until configured.
6 *
7 * Product brand: briven-engine only.
8 */
9
10export type BrivenSocialProviderId =
11 | 'konnos'
12 | 'google'
13 | 'github'
14 | 'apple'
15 | 'discord'
16 | 'microsoft'
17 | 'facebook'
18 | 'twitter'
19 | 'linkedin'
20 | 'gitlab'
21 | 'bitbucket'
22 | 'spotify';
23
24export type BrivenSocialProviderMeta = {
25 thirdPartyId: BrivenSocialProviderId;
26 name: string;
27 engine: 'briven-engine';
28 help: string;
29 builtIn: true;
30 /** Shown under OAuth setup (callback / webhook URL pattern). */
31 callbackHint?: string;
32};
33
34export const BRIVEN_ENGINE_SOCIAL_CATALOG: readonly BrivenSocialProviderMeta[] = [
35 {
36 thirdPartyId: 'konnos',
37 name: 'Konnos',
38 engine: 'briven-engine',
39 help: 'code.konnos.org → Settings → Applications (OAuth2)',
40 builtIn: true,
41 callbackHint:
42 'Redirect URI: {apiOrigin}/v1/auth-core/oauth/konnos/callback?projectId={projectId}',
43 },
44 {
45 thirdPartyId: 'google',
46 name: 'Google',
47 engine: 'briven-engine',
48 help: 'Google Cloud Console → APIs & Services → Credentials',
49 builtIn: true,
50 callbackHint:
51 'Authorized redirect: {apiOrigin}/v1/auth-core/oauth/google/callback',
52 },
53 {
54 thirdPartyId: 'github',
55 name: 'GitHub',
56 engine: 'briven-engine',
57 help: 'GitHub → Settings → Developer settings → OAuth Apps',
58 builtIn: true,
59 callbackHint:
60 'Authorization callback URL: {apiOrigin}/v1/auth-core/oauth/github/callback',
61 },
62 {
63 thirdPartyId: 'apple',
64 name: 'Apple',
65 engine: 'briven-engine',
66 help: 'Apple Developer → Certificates, Identifiers & Profiles (paste client secret JWT)',
67 builtIn: true,
68 callbackHint:
69 'Return URL: {apiOrigin}/v1/auth-core/oauth/apple/callback',
70 },
71 {
72 thirdPartyId: 'discord',
73 name: 'Discord',
74 engine: 'briven-engine',
75 help: 'Discord Developer Portal → Applications → OAuth2',
76 builtIn: true,
77 callbackHint:
78 'Redirects: {apiOrigin}/v1/auth-core/oauth/discord/callback',
79 },
80 {
81 thirdPartyId: 'microsoft',
82 name: 'Microsoft',
83 engine: 'briven-engine',
84 help: 'Azure Portal → Entra ID → App registrations',
85 builtIn: true,
86 callbackHint:
87 'Redirect URI: {apiOrigin}/v1/auth-core/oauth/microsoft/callback',
88 },
89 {
90 thirdPartyId: 'facebook',
91 name: 'Facebook',
92 engine: 'briven-engine',
93 help: 'Meta for Developers → My Apps → Facebook Login',
94 builtIn: true,
95 callbackHint:
96 'Valid OAuth Redirect URIs: {apiOrigin}/v1/auth-core/oauth/facebook/callback',
97 },
98 {
99 thirdPartyId: 'twitter',
100 name: 'X (Twitter)',
101 engine: 'briven-engine',
102 help: 'X Developer Portal → Projects & Apps → OAuth 2.0',
103 builtIn: true,
104 callbackHint:
105 'Callback URI: {apiOrigin}/v1/auth-core/oauth/twitter/callback',
106 },
107 {
108 thirdPartyId: 'linkedin',
109 name: 'LinkedIn',
110 engine: 'briven-engine',
111 help: 'LinkedIn Developers → My Apps → Auth',
112 builtIn: true,
113 callbackHint:
114 'Redirect URL: {apiOrigin}/v1/auth-core/oauth/linkedin/callback',
115 },
116 {
117 thirdPartyId: 'gitlab',
118 name: 'GitLab',
119 engine: 'briven-engine',
120 help: 'GitLab → Preferences → Applications',
121 builtIn: true,
122 callbackHint:
123 'Redirect URI: {apiOrigin}/v1/auth-core/oauth/gitlab/callback',
124 },
125 {
126 thirdPartyId: 'bitbucket',
127 name: 'Bitbucket',
128 engine: 'briven-engine',
129 help: 'Bitbucket → Workspace settings → OAuth consumers',
130 builtIn: true,
131 callbackHint:
132 'Callback URL: {apiOrigin}/v1/auth-core/oauth/bitbucket/callback',
133 },
134 {
135 thirdPartyId: 'spotify',
136 name: 'Spotify',
137 engine: 'briven-engine',
138 help: 'Spotify Developer Dashboard → Redirect URIs',
139 builtIn: true,
140 callbackHint:
141 'Redirect URIs: {apiOrigin}/v1/auth-core/oauth/spotify/callback',
142 },
143] as const;
144
145export type ProjectProviderSecrets = {
146 thirdPartyId: BrivenSocialProviderId;
147 clientId: string;
148 clientSecret: string;
149 additionalConfig?: Record<string, string>;
150};
151
152/**
153 * Map stored secrets → ThirdParty.init providers array entries.
154 * Returns empty when no secrets configured (sign-in methods still work via email/password/SMS/passkey).
155 */
156export function buildThirdPartyProvidersFromSecrets(
157 secrets: ProjectProviderSecrets[],
158 // eslint-disable-next-line @typescript-eslint/no-explicit-any
159 ThirdPartyProviders: any,
160 // eslint-disable-next-line @typescript-eslint/no-explicit-any
161): any[] {
162 const out: unknown[] = [];
163 for (const s of secrets) {
164 if (!s.clientId || !s.clientSecret) continue;
165 const clients = [{ clientId: s.clientId, clientSecret: s.clientSecret }];
166 switch (s.thirdPartyId) {
167 case 'google':
168 out.push(ThirdPartyProviders.Google({ clients }));
169 break;
170 case 'github':
171 out.push(ThirdPartyProviders.Github({ clients }));
172 break;
173 case 'apple':
174 out.push(
175 ThirdPartyProviders.Apple({
176 clients: [
177 {
178 clientId: s.clientId,
179 clientSecret: {
180 keyId: s.additionalConfig?.keyId ?? '',
181 privateKey: s.clientSecret,
182 teamId: s.additionalConfig?.teamId ?? '',
183 },
184 additionalConfig: s.additionalConfig,
185 },
186 ],
187 }),
188 );
189 break;
190 case 'discord':
191 out.push(ThirdPartyProviders.Discord({ clients }));
192 break;
193 case 'microsoft':
194 out.push(
195 ThirdPartyProviders.Microsoft({
196 clients,
197 // directoryId optional
198 }),
199 );
200 break;
201 case 'facebook':
202 out.push(ThirdPartyProviders.Facebook({ clients }));
203 break;
204 case 'linkedin':
205 out.push(ThirdPartyProviders.LinkedIn({ clients }));
206 break;
207 case 'gitlab':
208 out.push(ThirdPartyProviders.Gitlab({ clients }));
209 break;
210 case 'bitbucket':
211 out.push(ThirdPartyProviders.Bitbucket({ clients }));
212 break;
213 case 'spotify':
214 out.push(ThirdPartyProviders.Spotify({ clients }));
215 break;
216 case 'twitter':
217 // X/Twitter provider name varies by SDK version
218 if (typeof ThirdPartyProviders.Twitter === 'function') {
219 out.push(ThirdPartyProviders.Twitter({ clients }));
220 }
221 break;
222 case 'konnos':
223 // Custom OIDC / generic — wired in FDI via project secrets + issuer
224 break;
225 default:
226 break;
227 }
228 }
229 return out;
230}