@flink-app/oidc-plugin 0.14.3 → 2.0.0-alpha.100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +485 -0
- package/README.md +23 -2
- package/dist/OidcPlugin.d.ts +1 -1
- package/dist/OidcPlugin.d.ts.map +1 -1
- package/dist/OidcPlugin.js +32 -18
- package/dist/OidcPluginOptions.d.ts +75 -8
- package/dist/OidcPluginOptions.d.ts.map +1 -1
- package/dist/OidcProviderConfig.d.ts +21 -1
- package/dist/OidcProviderConfig.d.ts.map +1 -1
- package/dist/handlers/CallbackOidc.d.ts.map +1 -1
- package/dist/handlers/CallbackOidc.js +50 -5
- package/dist/handlers/InitiateOidc.d.ts.map +1 -1
- package/dist/handlers/InitiateOidc.js +14 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/log.d.ts +27 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +37 -0
- package/dist/providers/OidcProvider.d.ts +1 -1
- package/dist/providers/OidcProvider.d.ts.map +1 -1
- package/dist/providers/OidcProvider.js +46 -5
- package/dist/providers/ProviderRegistry.d.ts +2 -1
- package/dist/providers/ProviderRegistry.d.ts.map +1 -1
- package/dist/providers/ProviderRegistry.js +10 -2
- package/dist/schemas/CallbackRequest.d.ts +3 -6
- package/dist/schemas/CallbackRequest.d.ts.map +1 -1
- package/dist/schemas/InitiateRequest.d.ts +3 -6
- package/dist/schemas/InitiateRequest.d.ts.map +1 -1
- package/dist/schemas/OidcSession.d.ts +5 -0
- package/dist/schemas/OidcSession.d.ts.map +1 -1
- package/dist/utils/response-utils.d.ts +16 -5
- package/dist/utils/response-utils.d.ts.map +1 -1
- package/dist/utils/response-utils.js +31 -10
- package/examples/multi-provider.ts +1 -1
- package/package.json +8 -11
- package/spec/helpers/test-helpers.ts +14 -0
- package/spec/plugin/OidcPlugin.spec.ts +104 -3
- package/spec/providers/ProviderRegistry.spec.ts +8 -7
- package/spec/utils/response-utils.spec.ts +85 -0
- package/src/OidcPlugin.ts +54 -21
- package/src/OidcPluginOptions.ts +84 -9
- package/src/OidcProviderConfig.ts +23 -1
- package/src/handlers/CallbackOidc.ts +66 -5
- package/src/handlers/InitiateOidc.ts +19 -1
- package/src/index.ts +1 -1
- package/src/log.ts +33 -0
- package/src/providers/OidcProvider.ts +60 -7
- package/src/providers/ProviderRegistry.ts +22 -3
- package/src/schemas/CallbackRequest.ts +4 -6
- package/src/schemas/InitiateRequest.ts +3 -6
- package/src/schemas/OidcSession.ts +6 -0
- package/src/utils/response-utils.ts +53 -10
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import OidcProfile from "./schemas/OidcProfile";
|
|
2
2
|
import OidcTokenSet from "./schemas/OidcTokenSet";
|
|
3
3
|
import { OidcProviderConfig } from "./OidcProviderConfig";
|
|
4
|
+
import { TokenDeliveryMode } from "./utils/response-utils";
|
|
4
5
|
/**
|
|
5
6
|
* OIDC error information passed to onAuthError callback
|
|
6
7
|
*/
|
|
@@ -35,7 +36,9 @@ export interface AuthSuccessCallbackResponse {
|
|
|
35
36
|
token: string;
|
|
36
37
|
/**
|
|
37
38
|
* Optional redirect URL after authentication
|
|
38
|
-
*
|
|
39
|
+
*
|
|
40
|
+
* The plugin will attach the JWT token to this URL according to the
|
|
41
|
+
* top-level `tokenDelivery` option (fragment by default, or query).
|
|
39
42
|
*/
|
|
40
43
|
redirectUrl?: string;
|
|
41
44
|
}
|
|
@@ -56,7 +59,7 @@ export interface AuthErrorCallbackResponse {
|
|
|
56
59
|
* The onAuthSuccess callback receives the Flink context as a second parameter,
|
|
57
60
|
* allowing the application to generate JWT tokens using ctx.plugins.jwtAuth.createToken().
|
|
58
61
|
*/
|
|
59
|
-
export interface OidcPluginOptions {
|
|
62
|
+
export interface OidcPluginOptions<TCtx = any> {
|
|
60
63
|
/**
|
|
61
64
|
* OIDC provider configurations
|
|
62
65
|
* Key = provider name (used in URLs: /oidc/{provider}/initiate)
|
|
@@ -81,7 +84,7 @@ export interface OidcPluginOptions {
|
|
|
81
84
|
* }
|
|
82
85
|
* }
|
|
83
86
|
*/
|
|
84
|
-
providers
|
|
87
|
+
providers?: Record<string, OidcProviderConfig>;
|
|
85
88
|
/**
|
|
86
89
|
* Whether to store OIDC tokens for future API access
|
|
87
90
|
* If false, tokens are discarded after authentication (auth-only mode)
|
|
@@ -110,7 +113,7 @@ export interface OidcPluginOptions {
|
|
|
110
113
|
*
|
|
111
114
|
* Example:
|
|
112
115
|
* ```typescript
|
|
113
|
-
* onAuthSuccess: async ({ profile, claims, provider }, ctx) => {
|
|
116
|
+
* onAuthSuccess: async ({ profile, claims, provider, metadata }, ctx) => {
|
|
114
117
|
* // Find user by OIDC subject + issuer
|
|
115
118
|
* let user = await ctx.repos.userRepo.getOne({
|
|
116
119
|
* 'oidcConnections.subject': claims.sub,
|
|
@@ -158,12 +161,32 @@ export interface OidcPluginOptions {
|
|
|
158
161
|
* Provider name (e.g., "acme", "contoso")
|
|
159
162
|
*/
|
|
160
163
|
provider: string;
|
|
164
|
+
/**
|
|
165
|
+
* The redirectUri passed on the initiate request (stored in session)
|
|
166
|
+
* Use this to redirect back to the originating client application.
|
|
167
|
+
*
|
|
168
|
+
* Example:
|
|
169
|
+
* ```typescript
|
|
170
|
+
* return { user, token, redirectUrl: redirectUri || DEFAULT_REDIRECT_URL };
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
redirectUri: string;
|
|
174
|
+
/**
|
|
175
|
+
* Arbitrary metadata collected from meta.* query parameters on the initiate request.
|
|
176
|
+
* Opaque to the plugin — it only transports these values.
|
|
177
|
+
*
|
|
178
|
+
* Example: GET /oidc/acme/initiate?meta.intent=admin&meta.source=mobile
|
|
179
|
+
* Produces: { intent: "admin", source: "mobile" }
|
|
180
|
+
*
|
|
181
|
+
* Empty object ({}) if no meta.* params were provided.
|
|
182
|
+
*/
|
|
183
|
+
metadata: Record<string, string>;
|
|
161
184
|
/**
|
|
162
185
|
* OIDC tokens (only if storeTokens: true)
|
|
163
186
|
* Includes accessToken, idToken, refreshToken
|
|
164
187
|
*/
|
|
165
188
|
tokens?: OidcTokenSet;
|
|
166
|
-
}, ctx:
|
|
189
|
+
}, ctx: TCtx) => Promise<AuthSuccessCallbackResponse>;
|
|
167
190
|
/**
|
|
168
191
|
* Callback invoked on OIDC authentication errors
|
|
169
192
|
*
|
|
@@ -194,6 +217,17 @@ export interface OidcPluginOptions {
|
|
|
194
217
|
onAuthError?: (params: {
|
|
195
218
|
error: OidcError;
|
|
196
219
|
provider: string;
|
|
220
|
+
/**
|
|
221
|
+
* The redirectUri from the initiate request (if available)
|
|
222
|
+
* May be undefined for errors that occur before session lookup
|
|
223
|
+
* (e.g., IdP returns an error before we can retrieve the session)
|
|
224
|
+
*/
|
|
225
|
+
redirectUri?: string;
|
|
226
|
+
/**
|
|
227
|
+
* Metadata from the initiate request (meta.* query params, prefix stripped).
|
|
228
|
+
* Empty object ({}) if no meta.* params were provided or session was not found.
|
|
229
|
+
*/
|
|
230
|
+
metadata: Record<string, string>;
|
|
197
231
|
}) => Promise<AuthErrorCallbackResponse>;
|
|
198
232
|
/**
|
|
199
233
|
* Dynamic provider loader callback
|
|
@@ -204,11 +238,12 @@ export interface OidcPluginOptions {
|
|
|
204
238
|
* Use this for multi-tenant scenarios where each organization has different IdPs.
|
|
205
239
|
*
|
|
206
240
|
* @param providerName - Name of the provider to load
|
|
241
|
+
* @param ctx - Flink context with access to repos and plugins
|
|
207
242
|
* @returns Provider configuration or null if not found
|
|
208
243
|
*
|
|
209
244
|
* Example:
|
|
210
245
|
* ```typescript
|
|
211
|
-
* providerLoader: async (providerName) => {
|
|
246
|
+
* providerLoader: async (providerName, ctx) => {
|
|
212
247
|
* const config = await ctx.repos.oidcProviderRepo.getByName(providerName);
|
|
213
248
|
* if (!config || !config.enabled) {
|
|
214
249
|
* return null;
|
|
@@ -224,7 +259,7 @@ export interface OidcPluginOptions {
|
|
|
224
259
|
* }
|
|
225
260
|
* ```
|
|
226
261
|
*/
|
|
227
|
-
providerLoader?: (providerName: string) => Promise<OidcProviderConfig | null>;
|
|
262
|
+
providerLoader?: (providerName: string, ctx: TCtx) => Promise<OidcProviderConfig | null>;
|
|
228
263
|
/**
|
|
229
264
|
* Custom collection name for OIDC sessions
|
|
230
265
|
* Default: 'oidc_sessions'
|
|
@@ -246,7 +281,9 @@ export interface OidcPluginOptions {
|
|
|
246
281
|
sessionTTL?: number;
|
|
247
282
|
/**
|
|
248
283
|
* Encryption key for encrypting stored OIDC tokens
|
|
249
|
-
* If not provided, will be derived from first configured provider's client secret
|
|
284
|
+
* If not provided, will be derived from the first configured provider's client secret
|
|
285
|
+
*
|
|
286
|
+
* Required when using storeTokens with public clients (no clientSecret).
|
|
250
287
|
*
|
|
251
288
|
* Recommended: Use a dedicated encryption key from environment variables
|
|
252
289
|
* Must be at least 32 characters
|
|
@@ -254,6 +291,36 @@ export interface OidcPluginOptions {
|
|
|
254
291
|
* Example: process.env.OIDC_ENCRYPTION_KEY
|
|
255
292
|
*/
|
|
256
293
|
encryptionKey?: string;
|
|
294
|
+
/**
|
|
295
|
+
* Controls how the JWT token is delivered back to the client on the
|
|
296
|
+
* post-callback redirect (ignored when the caller uses `?response_type=json`).
|
|
297
|
+
*
|
|
298
|
+
* - `"fragment"` (default): appends `#token=...` to the redirectUrl. Best
|
|
299
|
+
* for web browsers — URL fragments are not sent to the server in HTTP
|
|
300
|
+
* requests, which preserves a small but real security property.
|
|
301
|
+
* - `"query"`: appends `?token=...` (or `&token=...`). Required for native
|
|
302
|
+
* mobile flows where the callback comes back via a custom URL scheme,
|
|
303
|
+
* because iOS `ASWebAuthenticationSession` strips URL fragments before
|
|
304
|
+
* delivering the URL to the app.
|
|
305
|
+
* - function: called once per callback to decide the delivery mode. Use
|
|
306
|
+
* this when one app serves both web and native clients. The function
|
|
307
|
+
* receives the resolved redirectUrl and the metadata bag from the
|
|
308
|
+
* initiate request, so the host can route by URL scheme, by
|
|
309
|
+
* `meta.intent`, or any other signal — the plugin makes no assumptions.
|
|
310
|
+
*
|
|
311
|
+
* Default: `"fragment"` (unchanged from prior versions).
|
|
312
|
+
*
|
|
313
|
+
* Example — route native (custom-scheme) clients to query, browsers to fragment:
|
|
314
|
+
* ```typescript
|
|
315
|
+
* tokenDelivery: ({ redirectUrl }) =>
|
|
316
|
+
* /^https?:/i.test(redirectUrl) ? "fragment" : "query",
|
|
317
|
+
* ```
|
|
318
|
+
*/
|
|
319
|
+
tokenDelivery?: TokenDeliveryMode | ((params: {
|
|
320
|
+
redirectUrl: string;
|
|
321
|
+
provider: string;
|
|
322
|
+
metadata: Record<string, string>;
|
|
323
|
+
}) => TokenDeliveryMode);
|
|
257
324
|
/**
|
|
258
325
|
* Whether to register OIDC routes automatically
|
|
259
326
|
* If false, you must manually handle OIDC flow
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OidcPluginOptions.d.ts","sourceRoot":"","sources":["../src/OidcPluginOptions.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,uBAAuB,CAAC;AAChD,OAAO,YAAY,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"OidcPluginOptions.d.ts","sourceRoot":"","sources":["../src/OidcPluginOptions.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,8 +18,19 @@ export interface OidcProviderConfig {
|
|
|
18
18
|
/**
|
|
19
19
|
* OAuth 2.0 client secret
|
|
20
20
|
* Provided by the IdP - keep this secure!
|
|
21
|
+
*
|
|
22
|
+
* Optional for public clients using PKCE-only authentication.
|
|
23
|
+
* When omitted, token_endpoint_auth_method defaults to "none".
|
|
21
24
|
*/
|
|
22
|
-
clientSecret
|
|
25
|
+
clientSecret?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Token endpoint authentication method
|
|
28
|
+
*
|
|
29
|
+
* - "client_secret_basic": HTTP Basic auth with client_id and client_secret (default when clientSecret is provided)
|
|
30
|
+
* - "client_secret_post": client_id and client_secret in POST body
|
|
31
|
+
* - "none": No client authentication (default when clientSecret is omitted, for public/PKCE-only clients)
|
|
32
|
+
*/
|
|
33
|
+
tokenEndpointAuthMethod?: "client_secret_basic" | "client_secret_post" | "none";
|
|
23
34
|
/**
|
|
24
35
|
* Callback URL for OAuth redirect
|
|
25
36
|
* Must match the redirect URI registered with the IdP
|
|
@@ -73,5 +84,14 @@ export interface OidcProviderConfig {
|
|
|
73
84
|
* e.g., { "department": "custom:department", "role": "custom:role" }
|
|
74
85
|
*/
|
|
75
86
|
claimMapping?: Record<string, string>;
|
|
87
|
+
/**
|
|
88
|
+
* Whether to fetch additional claims from the UserInfo endpoint.
|
|
89
|
+
* Default: true
|
|
90
|
+
*
|
|
91
|
+
* Set to `false` for IdPs whose UserInfo endpoint is unreliable or
|
|
92
|
+
* returns no additional data beyond what's already in the ID token.
|
|
93
|
+
* When disabled, profiles are built from ID token claims only.
|
|
94
|
+
*/
|
|
95
|
+
useUserInfoEndpoint?: boolean;
|
|
76
96
|
}
|
|
77
97
|
//# sourceMappingURL=OidcProviderConfig.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OidcProviderConfig.d.ts","sourceRoot":"","sources":["../src/OidcProviderConfig.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IAC/B;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB
|
|
1
|
+
{"version":3,"file":"OidcProviderConfig.d.ts","sourceRoot":"","sources":["../src/OidcProviderConfig.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IAC/B;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;;;OAMG;IACH,uBAAuB,CAAC,EAAE,qBAAqB,GAAG,oBAAoB,GAAG,MAAM,CAAC;IAEhF;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAEjB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IAEH;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEtC;;;;;;;OAOG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;CACjC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CallbackOidc.d.ts","sourceRoot":"","sources":["../../src/handlers/CallbackOidc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,UAAU,EAAc,UAAU,EAAwC,MAAM,kBAAkB,CAAC;AAC5G,OAAO,eAAe,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"CallbackOidc.d.ts","sourceRoot":"","sources":["../../src/handlers/CallbackOidc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,UAAU,EAAc,UAAU,EAAwC,MAAM,kBAAkB,CAAC;AAC5G,OAAO,eAAe,MAAM,4BAA4B,CAAC;AAOzD;;GAEG;AACH,UAAU,UAAU;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,eAAO,MAAM,KAAK,EAAE,UAGnB,CAAC;AAEF;;;;;;GAMG;AACH,QAAA,MAAM,YAAY,EAAE,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,eAAe,CA4QnE,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -20,6 +20,7 @@ const state_utils_1 = require("../utils/state-utils");
|
|
|
20
20
|
const response_utils_1 = require("../utils/response-utils");
|
|
21
21
|
const encryption_utils_1 = require("../utils/encryption-utils");
|
|
22
22
|
const error_utils_1 = require("../utils/error-utils");
|
|
23
|
+
const log_1 = require("../log");
|
|
23
24
|
/**
|
|
24
25
|
* Route configuration
|
|
25
26
|
* This handler is registered programmatically by the plugin
|
|
@@ -38,19 +39,35 @@ exports.Route = {
|
|
|
38
39
|
const CallbackOidc = async ({ ctx, req }) => {
|
|
39
40
|
const { provider } = req.params;
|
|
40
41
|
const { code, state, error: oidcError, error_description, response_type } = req.query;
|
|
42
|
+
// Track session outside try/catch so redirectUri and metadata are available in error handling
|
|
43
|
+
let sessionRedirectUri;
|
|
44
|
+
let sessionMetadata = {};
|
|
41
45
|
try {
|
|
42
46
|
// Validate provider and response_type
|
|
43
47
|
(0, error_utils_1.validateProvider)(provider);
|
|
44
48
|
(0, error_utils_1.validateResponseType)(response_type);
|
|
49
|
+
log_1.oidcLog.debug(`Callback: provider="${provider}" hasCode=${!!code} hasState=${!!state} responseType="${response_type || "redirect"}"`);
|
|
45
50
|
// Check for OIDC provider errors (e.g., user denied access)
|
|
46
51
|
if (oidcError) {
|
|
52
|
+
log_1.oidcLog.debug(`Callback: IdP returned error="${oidcError}" description="${error_description || ""}"`);
|
|
47
53
|
const error = (0, error_utils_1.handleProviderError)({ error: oidcError, error_description });
|
|
54
|
+
// Try to retrieve session redirectUri (state may be available even on IdP errors)
|
|
55
|
+
if (state) {
|
|
56
|
+
const errorSession = await ctx.repos.oidcSessionRepo.getByState(state);
|
|
57
|
+
sessionRedirectUri = errorSession?.redirectUri;
|
|
58
|
+
sessionMetadata = errorSession?.metadata ?? {};
|
|
59
|
+
if (errorSession) {
|
|
60
|
+
await ctx.repos.oidcSessionRepo.deleteBySessionId(errorSession.sessionId);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
48
63
|
// Call onAuthError callback if provided
|
|
49
64
|
const { options } = ctx.plugins.oidc;
|
|
50
65
|
if (options.onAuthError) {
|
|
51
66
|
const errorResult = await options.onAuthError({
|
|
52
67
|
error,
|
|
53
68
|
provider,
|
|
69
|
+
redirectUri: sessionRedirectUri,
|
|
70
|
+
metadata: sessionMetadata,
|
|
54
71
|
});
|
|
55
72
|
if (errorResult.redirectUrl) {
|
|
56
73
|
return {
|
|
@@ -72,16 +89,22 @@ const CallbackOidc = async ({ ctx, req }) => {
|
|
|
72
89
|
// Find OIDC session by state
|
|
73
90
|
const session = await ctx.repos.oidcSessionRepo.getByState(state);
|
|
74
91
|
if (!session) {
|
|
92
|
+
log_1.oidcLog.debug(`Callback: no session found for state (may be expired)`);
|
|
75
93
|
throw (0, error_utils_1.createOidcError)(error_utils_1.OidcErrorCodes.SESSION_EXPIRED, "OIDC session not found or expired. Please try logging in again.", { state });
|
|
76
94
|
}
|
|
95
|
+
log_1.oidcLog.debug(`Callback: session found sessionId=${session.sessionId} provider="${session.provider}" redirectUri="${session.redirectUri}"`);
|
|
77
96
|
// Validate state parameter (CSRF protection)
|
|
78
97
|
if (!(0, state_utils_1.validateState)(state, session.state)) {
|
|
79
98
|
throw (0, error_utils_1.createOidcError)(error_utils_1.OidcErrorCodes.INVALID_STATE, "Invalid state parameter. Possible CSRF attack detected.", {
|
|
80
99
|
providedState: state.substring(0, 10) + "...",
|
|
81
100
|
});
|
|
82
101
|
}
|
|
102
|
+
// Track redirectUri and metadata for error handling
|
|
103
|
+
sessionRedirectUri = session.redirectUri;
|
|
104
|
+
sessionMetadata = session.metadata ?? {};
|
|
83
105
|
// Delete session immediately after validation (one-time use)
|
|
84
106
|
await ctx.repos.oidcSessionRepo.deleteBySessionId(session.sessionId);
|
|
107
|
+
log_1.oidcLog.debug(`Callback: state validated, session deleted (one-time use)`);
|
|
85
108
|
// Get plugin options
|
|
86
109
|
const { options } = ctx.plugins.oidc;
|
|
87
110
|
// Get provider instance
|
|
@@ -97,13 +120,17 @@ const CallbackOidc = async ({ ctx, req }) => {
|
|
|
97
120
|
state: session.state,
|
|
98
121
|
nonce: session.nonce,
|
|
99
122
|
});
|
|
100
|
-
|
|
101
|
-
|
|
123
|
+
log_1.oidcLog.debug(`Callback: token exchange successful`, `sub="${tokenSet.claims.sub}"`, `iss="${tokenSet.claims.iss}"`, `email="${tokenSet.claims.email || "(none)"}"`, `hasRefreshToken=${!!tokenSet.refreshToken}`, `expiresIn=${tokenSet.expiresIn ?? "(none)"}s`);
|
|
124
|
+
// Build user profile from ID token and (optionally) UserInfo
|
|
125
|
+
const profile = await oidcProvider.buildProfile(tokenSet, oidcProvider.config.useUserInfoEndpoint ?? true);
|
|
126
|
+
log_1.oidcLog.debug(`Callback: profile built id="${profile.id}" email="${profile.email || "(none)"}" name="${profile.name || "(none)"}"`);
|
|
102
127
|
// Call onAuthSuccess callback to create/link user and generate JWT token
|
|
103
128
|
const authSuccessParams = {
|
|
104
129
|
profile,
|
|
105
130
|
claims: tokenSet.claims,
|
|
106
131
|
provider,
|
|
132
|
+
redirectUri: session.redirectUri,
|
|
133
|
+
metadata: sessionMetadata,
|
|
107
134
|
...(options.storeTokens ? { tokens: tokenSet } : {}),
|
|
108
135
|
};
|
|
109
136
|
let authResult;
|
|
@@ -121,6 +148,8 @@ const CallbackOidc = async ({ ctx, req }) => {
|
|
|
121
148
|
const errorResult = await options.onAuthError({
|
|
122
149
|
error: oidcError,
|
|
123
150
|
provider,
|
|
151
|
+
redirectUri: session.redirectUri,
|
|
152
|
+
metadata: sessionMetadata,
|
|
124
153
|
});
|
|
125
154
|
if (errorResult.redirectUrl) {
|
|
126
155
|
return {
|
|
@@ -140,7 +169,7 @@ const CallbackOidc = async ({ ctx, req }) => {
|
|
|
140
169
|
// Store OIDC connection if token storage is enabled
|
|
141
170
|
if (options.storeTokens && user && user._id) {
|
|
142
171
|
// Get encryption secret (use provider client secret or global encryption key)
|
|
143
|
-
const staticProviderConfig = options.providers[provider];
|
|
172
|
+
const staticProviderConfig = options.providers?.[provider];
|
|
144
173
|
const encryptionSecret = options.encryptionKey || staticProviderConfig?.clientSecret;
|
|
145
174
|
if (!encryptionSecret) {
|
|
146
175
|
flink_1.log.warn("No encryption secret available, tokens will not be stored");
|
|
@@ -155,7 +184,8 @@ const CallbackOidc = async ({ ctx, req }) => {
|
|
|
155
184
|
// Create or update OIDC connection
|
|
156
185
|
const existingConnection = await ctx.repos.oidcConnectionRepo.findByUserAndProvider(user._id, provider);
|
|
157
186
|
if (existingConnection) {
|
|
158
|
-
|
|
187
|
+
log_1.oidcLog.debug(`Callback: updating existing connection for userId=${user._id} provider="${provider}"`);
|
|
188
|
+
await ctx.repos.oidcConnectionRepo.updateById(existingConnection._id, {
|
|
159
189
|
accessToken: encryptedAccessToken,
|
|
160
190
|
idToken: encryptedIdToken,
|
|
161
191
|
refreshToken: encryptedRefreshToken,
|
|
@@ -165,6 +195,7 @@ const CallbackOidc = async ({ ctx, req }) => {
|
|
|
165
195
|
});
|
|
166
196
|
}
|
|
167
197
|
else {
|
|
198
|
+
log_1.oidcLog.debug(`Callback: creating new connection for userId=${user._id} provider="${provider}" subject="${tokenSet.claims.sub}"`);
|
|
168
199
|
await ctx.repos.oidcConnectionRepo.create({
|
|
169
200
|
userId: user._id,
|
|
170
201
|
provider,
|
|
@@ -182,8 +213,20 @@ const CallbackOidc = async ({ ctx, req }) => {
|
|
|
182
213
|
}
|
|
183
214
|
}
|
|
184
215
|
}
|
|
216
|
+
const finalRedirectUrl = redirectUrl || session.redirectUri;
|
|
217
|
+
log_1.oidcLog.debug(`Callback: auth complete, responding via ${response_type === "json" ? "JSON" : `redirect to "${finalRedirectUrl}"`}`);
|
|
218
|
+
// Resolve token delivery mode: literal, function, or default "fragment".
|
|
219
|
+
// The plugin stays a dumb transport — the host app makes the policy decision.
|
|
220
|
+
const tokenDeliverySetting = options.tokenDelivery ?? "fragment";
|
|
221
|
+
const resolvedTokenDelivery = typeof tokenDeliverySetting === "function"
|
|
222
|
+
? tokenDeliverySetting({
|
|
223
|
+
redirectUrl: finalRedirectUrl,
|
|
224
|
+
provider,
|
|
225
|
+
metadata: sessionMetadata,
|
|
226
|
+
})
|
|
227
|
+
: tokenDeliverySetting;
|
|
185
228
|
// Return JWT token in requested format
|
|
186
|
-
return (0, response_utils_1.formatTokenResponse)(token, user,
|
|
229
|
+
return (0, response_utils_1.formatTokenResponse)(token, user, finalRedirectUrl, response_type, resolvedTokenDelivery);
|
|
187
230
|
}
|
|
188
231
|
catch (error) {
|
|
189
232
|
flink_1.log.error("OIDC callback error:", error);
|
|
@@ -196,6 +239,8 @@ const CallbackOidc = async ({ ctx, req }) => {
|
|
|
196
239
|
const errorResult = await options.onAuthError({
|
|
197
240
|
error,
|
|
198
241
|
provider,
|
|
242
|
+
redirectUri: sessionRedirectUri,
|
|
243
|
+
metadata: sessionMetadata,
|
|
199
244
|
});
|
|
200
245
|
if (errorResult.redirectUrl) {
|
|
201
246
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InitiateOidc.d.ts","sourceRoot":"","sources":["../../src/handlers/InitiateOidc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,UAAU,EAAc,UAAU,EAAmC,MAAM,kBAAkB,CAAC;AACvG,OAAO,eAAe,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"InitiateOidc.d.ts","sourceRoot":"","sources":["../../src/handlers/InitiateOidc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,UAAU,EAAc,UAAU,EAAmC,MAAM,kBAAkB,CAAC;AACvG,OAAO,eAAe,MAAM,4BAA4B,CAAC;AAMzD;;GAEG;AACH,UAAU,UAAU;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,eAAO,MAAM,KAAK,EAAE,UAGnB,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,YAAY,EAAE,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,eAAe,CAkFnE,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -17,6 +17,7 @@ const flink_1 = require("@flink-app/flink");
|
|
|
17
17
|
const state_utils_1 = require("../utils/state-utils");
|
|
18
18
|
const error_utils_1 = require("../utils/error-utils");
|
|
19
19
|
const openid_client_1 = require("openid-client");
|
|
20
|
+
const log_1 = require("../log");
|
|
20
21
|
/**
|
|
21
22
|
* Route configuration
|
|
22
23
|
* This handler is registered programmatically by the plugin
|
|
@@ -37,6 +38,7 @@ const InitiateOidc = async ({ ctx, req }) => {
|
|
|
37
38
|
try {
|
|
38
39
|
// Validate provider name format
|
|
39
40
|
(0, error_utils_1.validateProvider)(provider);
|
|
41
|
+
log_1.oidcLog.debug(`Initiate: provider="${provider}" redirectUri="${redirectUri || "(not set)"}"`);
|
|
40
42
|
// Get provider registry from context
|
|
41
43
|
const providerRegistry = ctx.oidcProviderRegistry;
|
|
42
44
|
if (!providerRegistry) {
|
|
@@ -47,8 +49,16 @@ const InitiateOidc = async ({ ctx, req }) => {
|
|
|
47
49
|
// Get plugin options
|
|
48
50
|
const { options } = ctx.plugins.oidc;
|
|
49
51
|
// Determine redirect URI (use provided or default to callback URL)
|
|
50
|
-
const staticProviderConfig = options.providers[provider];
|
|
52
|
+
const staticProviderConfig = options.providers?.[provider];
|
|
51
53
|
const finalRedirectUri = redirectUri || staticProviderConfig?.callbackUrl || `${req.protocol}://${req.get("host")}/oidc/${provider}/callback`;
|
|
54
|
+
// Collect meta.* query params as opaque metadata (prefix stripped)
|
|
55
|
+
const metadata = {};
|
|
56
|
+
for (const [key, value] of Object.entries(req.query)) {
|
|
57
|
+
if (key.startsWith("meta.") && typeof value === "string") {
|
|
58
|
+
metadata[key.slice(5)] = value;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
log_1.oidcLog.debug(`Initiate: resolved redirectUri="${finalRedirectUri}" (source: ${redirectUri ? "query param" : staticProviderConfig?.callbackUrl ? "provider config" : "auto-detected"})`);
|
|
52
62
|
// Generate cryptographically secure parameters
|
|
53
63
|
const state = (0, state_utils_1.generateState)();
|
|
54
64
|
const sessionId = (0, state_utils_1.generateSessionId)();
|
|
@@ -62,14 +72,17 @@ const InitiateOidc = async ({ ctx, req }) => {
|
|
|
62
72
|
nonce,
|
|
63
73
|
provider,
|
|
64
74
|
redirectUri: finalRedirectUri,
|
|
75
|
+
metadata,
|
|
65
76
|
createdAt: new Date(),
|
|
66
77
|
});
|
|
78
|
+
log_1.oidcLog.debug(`Initiate: session created sessionId=${sessionId}`);
|
|
67
79
|
// Build authorization URL with PKCE and nonce
|
|
68
80
|
const authorizationUrl = await oidcProvider.getAuthorizationUrl({
|
|
69
81
|
state,
|
|
70
82
|
codeVerifier,
|
|
71
83
|
nonce,
|
|
72
84
|
});
|
|
85
|
+
log_1.oidcLog.debug(`Initiate: redirecting to IdP authorization URL: ${authorizationUrl}`);
|
|
73
86
|
// Redirect user to provider's authorization page
|
|
74
87
|
return {
|
|
75
88
|
status: 302,
|
package/dist/index.d.ts
CHANGED
|
@@ -22,6 +22,6 @@ export { ProviderRegistry } from "./providers/ProviderRegistry";
|
|
|
22
22
|
export { generateState, generateSessionId, generateNonce, validateState } from "./utils/state-utils";
|
|
23
23
|
export { encryptToken, decryptToken, validateEncryptionSecret } from "./utils/encryption-utils";
|
|
24
24
|
export { mapClaimsToProfile, extractCustomClaims } from "./utils/claims-mapper";
|
|
25
|
-
export { formatTokenResponse } from "./utils/response-utils";
|
|
25
|
+
export { formatTokenResponse, TokenDeliveryMode } from "./utils/response-utils";
|
|
26
26
|
export { createOidcError, validateProvider, handleProviderError, OidcErrorCodes } from "./utils/error-utils";
|
|
27
27
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,2BAA2B,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAC3H,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAGvE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAGhE,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACrG,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAChG,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,2BAA2B,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAC3H,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAGvE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAGhE,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACrG,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAChG,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAChF,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/log.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Named logger for the OIDC plugin.
|
|
3
|
+
*
|
|
4
|
+
* Enables independent log level control via flink.config.js:
|
|
5
|
+
* ```js
|
|
6
|
+
* module.exports = {
|
|
7
|
+
* logging: {
|
|
8
|
+
* components: {
|
|
9
|
+
* "flink.oidc": "debug"
|
|
10
|
+
* }
|
|
11
|
+
* }
|
|
12
|
+
* };
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* Or at runtime:
|
|
16
|
+
* ```ts
|
|
17
|
+
* FlinkLogFactory.setComponentLevel("flink.oidc", "debug");
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare const oidcLog: import("@flink-app/flink").ComponentLogger;
|
|
21
|
+
/**
|
|
22
|
+
* Mask a secret value for safe logging.
|
|
23
|
+
* Shows the first 4 characters followed by **** to help identify which secret
|
|
24
|
+
* is in use without exposing the full value.
|
|
25
|
+
*/
|
|
26
|
+
export declare function maskSecret(value: string | undefined): string;
|
|
27
|
+
//# sourceMappingURL=log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,OAAO,4CAA6C,CAAC;AAElE;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAI5D"}
|
package/dist/log.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.oidcLog = void 0;
|
|
4
|
+
exports.maskSecret = maskSecret;
|
|
5
|
+
const flink_1 = require("@flink-app/flink");
|
|
6
|
+
/**
|
|
7
|
+
* Named logger for the OIDC plugin.
|
|
8
|
+
*
|
|
9
|
+
* Enables independent log level control via flink.config.js:
|
|
10
|
+
* ```js
|
|
11
|
+
* module.exports = {
|
|
12
|
+
* logging: {
|
|
13
|
+
* components: {
|
|
14
|
+
* "flink.oidc": "debug"
|
|
15
|
+
* }
|
|
16
|
+
* }
|
|
17
|
+
* };
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* Or at runtime:
|
|
21
|
+
* ```ts
|
|
22
|
+
* FlinkLogFactory.setComponentLevel("flink.oidc", "debug");
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
exports.oidcLog = flink_1.FlinkLogFactory.createLogger("flink.oidc");
|
|
26
|
+
/**
|
|
27
|
+
* Mask a secret value for safe logging.
|
|
28
|
+
* Shows the first 4 characters followed by **** to help identify which secret
|
|
29
|
+
* is in use without exposing the full value.
|
|
30
|
+
*/
|
|
31
|
+
function maskSecret(value) {
|
|
32
|
+
if (!value)
|
|
33
|
+
return "(not set)";
|
|
34
|
+
if (value.length <= 4)
|
|
35
|
+
return "****";
|
|
36
|
+
return `${value.slice(0, 4)}****`;
|
|
37
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OidcProvider.d.ts","sourceRoot":"","sources":["../../src/providers/OidcProvider.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"OidcProvider.d.ts","sourceRoot":"","sources":["../../src/providers/OidcProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwD,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACvG,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,WAAW,MAAM,wBAAwB,CAAC;AACjD,OAAO,YAAY,MAAM,yBAAyB,CAAC;AAKnD;;;;;;;;;;GAUG;AACH,qBAAa,YAAY;IACrB,SAAgB,MAAM,EAAE,kBAAkB,CAAC;IAC3C,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,WAAW,CAAkB;gBAEzB,MAAM,EAAE,kBAAkB;IAItC;;;;;;;OAOG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAsEjC;;;;;OAKG;IACG,mBAAmB,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAiB1G;;;;;;;OAOG;IACG,oBAAoB,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,YAAY,CAAC;IAoD/H;;;;;;;;OAQG;IACG,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAsBjE;;;;;;;;;OASG;IACG,YAAY,CAAC,QAAQ,EAAE,YAAY,EAAE,eAAe,GAAE,OAAc,GAAG,OAAO,CAAC,WAAW,CAAC;IAgCjG;;;;OAIG;YACW,iBAAiB;IAU/B;;;;OAIG;IACH,iBAAiB,IAAI,GAAG;CAM3B"}
|