@thunderid/express 0.0.4 → 0.0.5

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.
Files changed (42) hide show
  1. package/dist/ThunderIDExpressClient.d.ts +11 -9
  2. package/dist/ThunderIDExpressClient.d.ts.map +1 -1
  3. package/dist/cjs/index.cjs +306 -172
  4. package/dist/{__legacy__/constants/logger-config.d.ts → constants/CookieConfig.d.ts} +11 -11
  5. package/dist/constants/CookieConfig.d.ts.map +1 -0
  6. package/dist/edge/index.js +300 -172
  7. package/dist/index.d.ts +6 -2
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +300 -172
  10. package/dist/middleware/authentication.d.ts +66 -0
  11. package/dist/middleware/authentication.d.ts.map +1 -0
  12. package/dist/middleware/flow.d.ts +50 -0
  13. package/dist/middleware/flow.d.ts.map +1 -0
  14. package/dist/{__legacy__/middleware/protect-route.d.ts → middleware/protect.d.ts} +12 -5
  15. package/dist/middleware/protect.d.ts.map +1 -0
  16. package/dist/models/config.d.ts +28 -9
  17. package/dist/models/config.d.ts.map +1 -1
  18. package/dist/{__legacy__/models/protect-route.d.ts → models/protectRoute.d.ts} +6 -3
  19. package/dist/models/protectRoute.d.ts.map +1 -0
  20. package/dist/{__legacy__/constants/index.d.ts → utils/expressUtils.d.ts} +9 -4
  21. package/dist/utils/expressUtils.d.ts.map +1 -0
  22. package/package.json +2 -2
  23. package/dist/__legacy__/client.d.ts +0 -46
  24. package/dist/__legacy__/client.d.ts.map +0 -1
  25. package/dist/__legacy__/constants/default-options.d.ts +0 -26
  26. package/dist/__legacy__/constants/default-options.d.ts.map +0 -1
  27. package/dist/__legacy__/constants/index.d.ts.map +0 -1
  28. package/dist/__legacy__/constants/logger-config.d.ts.map +0 -1
  29. package/dist/__legacy__/middleware/authentication.d.ts +0 -23
  30. package/dist/__legacy__/middleware/authentication.d.ts.map +0 -1
  31. package/dist/__legacy__/middleware/index.d.ts +0 -20
  32. package/dist/__legacy__/middleware/index.d.ts.map +0 -1
  33. package/dist/__legacy__/middleware/protect-route.d.ts.map +0 -1
  34. package/dist/__legacy__/models/client-config.d.ts +0 -33
  35. package/dist/__legacy__/models/client-config.d.ts.map +0 -1
  36. package/dist/__legacy__/models/data.d.ts +0 -21
  37. package/dist/__legacy__/models/data.d.ts.map +0 -1
  38. package/dist/__legacy__/models/index.d.ts +0 -21
  39. package/dist/__legacy__/models/index.d.ts.map +0 -1
  40. package/dist/__legacy__/models/protect-route.d.ts.map +0 -1
  41. package/dist/__legacy__/utils/express-utils.d.ts +0 -22
  42. package/dist/__legacy__/utils/express-utils.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -1,12 +1,11 @@
1
- import { LegacyThunderIDNodeClient, Logger, ThunderIDAuthException } from "@thunderid/node";
1
+ import { ThunderIDAuthException, ThunderIDNodeClient, ThunderIDRuntimeError, executeEmbeddedSignInFlowV2, logger } from "@thunderid/node";
2
2
  import { v4 } from "uuid";
3
- import express from "express";
4
3
 
5
4
  export * from "@thunderid/node"
6
5
 
7
- //#region src/__legacy__/constants/default-options.ts
6
+ //#region src/constants/CookieConfig.ts
8
7
  /**
9
- * Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).
8
+ * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
10
9
  *
11
10
  * WSO2 LLC. licenses this file to you under the Apache License,
12
11
  * Version 2.0 (the "License"); you may not use this file except
@@ -22,206 +21,335 @@ export * from "@thunderid/node"
22
21
  * specific language governing permissions and limitations
23
22
  * under the License.
24
23
  */
25
- let CookieConfig = /* @__PURE__ */ function(CookieConfig$1) {
26
- CookieConfig$1[CookieConfig$1["defaultMaxAge"] = 9e4] = "defaultMaxAge";
27
- CookieConfig$1["defaultHttpOnly"] = "true";
28
- CookieConfig$1["defaultSameSite"] = "lax";
29
- CookieConfig$1["defaultSecure"] = "false";
30
- return CookieConfig$1;
31
- }({});
32
- const DEFAULT_LOGIN_PATH = "/login";
33
- const DEFAULT_LOGOUT_PATH = "/logout";
24
+ /** Session cookie name used across the Express SDK. */
25
+ const SESSION_COOKIE_NAME = "THUNDERID_SESSION_ID";
26
+ /** Default cookie configuration values. */
27
+ const CookieConfig = {
28
+ defaultExpirySeconds: 86400,
29
+ defaultHttpOnly: true,
30
+ defaultSameSite: "lax",
31
+ defaultSecure: false
32
+ };
33
+ var CookieConfig_default = CookieConfig;
34
34
 
35
35
  //#endregion
36
- //#region src/__legacy__/middleware/protect-route.ts
37
- const protectRoute = (thunderIDExpressClient, callback) => {
38
- return async (req, res, next) => {
39
- if (req.cookies.THUNDERID_SESSION_ID === void 0) {
40
- Logger.error("No session ID found in the request cookies");
41
- if (callback(res, "Unauthenticated")) return;
42
- return next();
43
- } else if (await thunderIDExpressClient.isSignedIn(req.cookies.THUNDERID_SESSION_ID)) return next();
44
- else {
45
- Logger.error("Invalid session ID found in the request cookies");
46
- if (callback(res, "Invalid session cookie")) return;
47
- return next();
48
- }
49
- };
36
+ //#region src/utils/expressUtils.ts
37
+ /**
38
+ * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
39
+ *
40
+ * WSO2 LLC. licenses this file to you under the Apache License,
41
+ * Version 2.0 (the "License"); you may not use this file except
42
+ * in compliance with the License.
43
+ * You may obtain a copy of the License at
44
+ *
45
+ * http://www.apache.org/licenses/LICENSE-2.0
46
+ *
47
+ * Unless required by applicable law or agreed to in writing,
48
+ * software distributed under the License is distributed on an
49
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
50
+ * KIND, either express or implied. See the License for the
51
+ * specific language governing permissions and limitations
52
+ * under the License.
53
+ */
54
+ const AUTH_ERROR_REGEXP = /[?&]error=[^&]+/;
55
+ /**
56
+ * Returns `true` if the given URL contains an OAuth error query parameter.
57
+ *
58
+ * @param url - The URL to inspect.
59
+ */
60
+ const hasErrorInURL = (url) => AUTH_ERROR_REGEXP.test(url);
61
+ var expressUtils_default = hasErrorInURL;
62
+
63
+ //#endregion
64
+ //#region src/ThunderIDExpressClient.ts
65
+ var ThunderIDExpressClient = class extends ThunderIDNodeClient {
66
+ _expressConfig;
67
+ constructor() {
68
+ super();
69
+ }
70
+ async initialize(config, storage) {
71
+ this._expressConfig = config;
72
+ return super.initialize(config, storage);
73
+ }
74
+ get expressConfig() {
75
+ return this._expressConfig;
76
+ }
77
+ async getUserFromRequest(req) {
78
+ const sessionId = req.cookies?.[SESSION_COOKIE_NAME];
79
+ return this.getUser(sessionId);
80
+ }
81
+ async signIn(req, res, next, signInConfig) {
82
+ if (expressUtils_default(req.originalUrl)) return Promise.reject(new ThunderIDAuthException("EXPRESS-CLIENT-SI-IV01", "Invalid login request URL", "Login request contains an error query parameter in the URL"));
83
+ let userId = req.cookies?.[SESSION_COOKIE_NAME];
84
+ if (!userId) userId = v4();
85
+ const sc = this._expressConfig?.sessionCookie;
86
+ const authRedirectCallback = (url) => {
87
+ if (!url) return;
88
+ res.cookie(SESSION_COOKIE_NAME, userId, {
89
+ httpOnly: sc?.httpOnly ?? CookieConfig_default.defaultHttpOnly,
90
+ maxAge: (sc?.expiryTime ?? CookieConfig_default.defaultExpirySeconds) * 1e3,
91
+ sameSite: sc?.sameSite ?? CookieConfig_default.defaultSameSite,
92
+ secure: sc?.secure ?? CookieConfig_default.defaultSecure
93
+ });
94
+ res.redirect(url);
95
+ if (typeof next === "function") next();
96
+ };
97
+ const authResponse = await super.signIn(authRedirectCallback, userId, req.query.code, req.query.session_state, req.query.state, signInConfig);
98
+ if (authResponse.accessToken || authResponse.idToken) return authResponse;
99
+ return {
100
+ accessToken: "",
101
+ createdAt: 0,
102
+ expiresIn: "",
103
+ idToken: "",
104
+ refreshToken: "",
105
+ scope: "",
106
+ tokenType: ""
107
+ };
108
+ }
109
+ async signOut(userId) {
110
+ return super.signOut(userId);
111
+ }
50
112
  };
113
+ var ThunderIDExpressClient_default = ThunderIDExpressClient;
51
114
 
52
115
  //#endregion
53
- //#region src/__legacy__/middleware/authentication.ts
54
- const thunderIDExpressAuth = (thunderIDExpressClient, config, onSignIn, onSignOut, onError) => {
55
- const router = new express.Router();
56
- router.use(async (req, res, next) => {
57
- req.thunderIDAuth = thunderIDExpressClient;
58
- res.thunderIDAuth = thunderIDExpressClient;
116
+ //#region src/middleware/authentication.ts
117
+ /**
118
+ * Returns Express middleware that initialises the ThunderID client and attaches
119
+ * it to `req.thunderIDAuth` for use in route handlers and `protect()`.
120
+ *
121
+ * Unlike the old `thunderID()` router, this function does **not** mount any
122
+ * routes automatically. Register sign-in and sign-out handlers explicitly:
123
+ *
124
+ * ```ts
125
+ * app.use(thunderID(config));
126
+ * app.get('/login', handleSignIn());
127
+ * app.get('/logout', handleSignOut());
128
+ * ```
129
+ *
130
+ * @param config - ThunderID Express configuration.
131
+ */
132
+ const thunderID = (config) => {
133
+ const client = new ThunderIDExpressClient_default();
134
+ let initPromise;
135
+ const getInitPromise = (req) => {
136
+ if (initPromise === void 0) {
137
+ const origin = `${req.protocol}://${req.get("host")}`;
138
+ initPromise = client.initialize({
139
+ ...config,
140
+ afterSignInUrl: config.afterSignInUrl ?? `${origin}/login`,
141
+ afterSignOutUrl: config.afterSignOutUrl ?? `${origin}/logout`
142
+ });
143
+ }
144
+ return initPromise;
145
+ };
146
+ return async (req, res, next) => {
147
+ await getInitPromise(req);
148
+ req.thunderIDAuth = client;
149
+ res.thunderIDAuth = client;
59
150
  next();
60
- });
61
- router.get(config.loginPath || DEFAULT_LOGIN_PATH, async (req, res, next) => {
151
+ };
152
+ };
153
+ /**
154
+ * Returns an Express route handler for the sign-in path.
155
+ *
156
+ * - If the request has no `?code` query param, initiates the OAuth 2.0 redirect.
157
+ * - If the request has `?code`, exchanges the authorization code for tokens,
158
+ * sets the session cookie, and calls `onSignIn`.
159
+ *
160
+ * Must be used after `thunderID()` middleware so that `req.thunderIDAuth` is set.
161
+ *
162
+ * ```ts
163
+ * app.get('/login', handleSignIn());
164
+ * ```
165
+ */
166
+ const handleSignIn = () => {
167
+ return async (req, res, next) => {
168
+ const client = req.thunderIDAuth;
169
+ if (!client) {
170
+ logger.error("thunderID() middleware must be mounted before handleSignIn()");
171
+ res.status(500).end();
172
+ return;
173
+ }
174
+ const config = client.expressConfig;
175
+ const onSignIn = config?.onSignIn ?? ((r) => r.end());
176
+ const onError = config?.onError ?? ((r, e) => {
177
+ logger.error(e.message);
178
+ r.status(500).end();
179
+ });
62
180
  try {
63
- const response = await thunderIDExpressClient.signIn(req, res, next, config.signInConfig);
181
+ const response = await client.signIn(req, res, next, config?.signInOptions);
64
182
  if (response.accessToken || response.idToken) onSignIn(res, response);
65
183
  } catch (e) {
66
- Logger.error(e.message);
184
+ logger.error(e.message);
67
185
  onError(res, e);
68
186
  }
69
- });
70
- router.get(config.logoutPath || DEFAULT_LOGOUT_PATH, async (req, res, next) => {
187
+ };
188
+ };
189
+ /**
190
+ * Returns an Express route handler for the sign-out path.
191
+ *
192
+ * - Clears the session cookie and redirects to the identity provider's
193
+ * end-session endpoint.
194
+ * - When the identity provider redirects back with `?state=sign_out_success`,
195
+ * calls `onSignOut`.
196
+ *
197
+ * Must be used after `thunderID()` middleware so that `req.thunderIDAuth` is set.
198
+ *
199
+ * ```ts
200
+ * app.get('/logout', handleSignOut());
201
+ * ```
202
+ */
203
+ const handleSignOut = () => {
204
+ return async (req, res) => {
205
+ const client = req.thunderIDAuth;
206
+ if (!client) {
207
+ logger.error("thunderID() middleware must be mounted before handleSignOut()");
208
+ res.status(500).end();
209
+ return;
210
+ }
211
+ const config = client.expressConfig;
212
+ const onSignOut = config?.onSignOut ?? ((r) => r.end());
213
+ const onError = config?.onError ?? ((r, e) => {
214
+ logger.error(e.message);
215
+ r.status(500).end();
216
+ });
71
217
  if (req.query.state === "sign_out_success") {
72
218
  onSignOut(res);
73
219
  return;
74
220
  }
75
- if (req.cookies.THUNDERID_SESSION_ID === void 0) {
76
- onError(res, new ThunderIDAuthException("EXPRESS-AUTH_MW-LOGOUT-NF01", "No cookie found in the request", "No cookie was sent with the request. The user may not have signed in yet."));
221
+ const sessionId = req.cookies?.[SESSION_COOKIE_NAME];
222
+ if (!sessionId) {
223
+ onError(res, new ThunderIDRuntimeError("No cookie found in the request", "EXPRESS-AUTH_MW-LOGOUT-NF01", "express"));
77
224
  return;
78
- } else try {
79
- const signOutURL = await req.thunderIDAuth.signOut(req.cookies.THUNDERID_SESSION_ID);
225
+ }
226
+ try {
227
+ const signOutURL = await client.signOut(sessionId);
80
228
  if (signOutURL) {
81
- res.cookie("THUNDERID_SESSION_ID", null, { maxAge: 0 });
229
+ res.cookie(SESSION_COOKIE_NAME, null, { maxAge: 0 });
82
230
  res.redirect(signOutURL);
83
- return;
84
231
  }
85
232
  } catch (e) {
86
233
  onError(res, e);
87
- return;
88
234
  }
89
- });
90
- return router;
235
+ };
91
236
  };
92
237
 
93
238
  //#endregion
94
- //#region src/__legacy__/utils/express-utils.ts
95
- var ExpressUtils = class {
96
- static AUTH_CODE_REGEXP = /[?&]error=[^&]+/;
97
- /**
98
- * Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).
99
- *
100
- * WSO2 LLC. licenses this file to you under the Apache License,
101
- * Version 2.0 (the "License"); you may not use this file except
102
- * in compliance with the License.
103
- * You may obtain a copy of the License at
104
- *
105
- * http://www.apache.org/licenses/LICENSE-2.0
106
- *
107
- * Unless required by applicable law or agreed to in writing,
108
- * software distributed under the License is distributed on an
109
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
110
- * KIND, either express or implied. See the License for the
111
- * specific language governing permissions and limitations
112
- * under the License.
113
- */
114
- static hasErrorInURL(url) {
115
- return this.AUTH_CODE_REGEXP.test(url);
116
- }
239
+ //#region src/middleware/protect.ts
240
+ /**
241
+ * Returns Express middleware that blocks unauthenticated requests.
242
+ * Requires `thunderID()` to be mounted before this middleware so that
243
+ * `req.thunderIDAuth` is populated.
244
+ *
245
+ * @param onUnauthenticated - Called when the session is missing or invalid.
246
+ * Defaults to sending a 401 response.
247
+ */
248
+ const protect = (onUnauthenticated) => {
249
+ return async (req, res, next) => {
250
+ const client = req.thunderIDAuth;
251
+ const sessionId = req.cookies?.[SESSION_COOKIE_NAME];
252
+ const reject = () => {
253
+ if (onUnauthenticated) onUnauthenticated(res);
254
+ else res.status(401).end();
255
+ };
256
+ if (!client || !sessionId) {
257
+ logger.error("No session ID found in the request cookies");
258
+ reject();
259
+ return;
260
+ }
261
+ if (await client.isSignedIn(sessionId)) return next();
262
+ logger.error("Invalid session ID found in the request cookies");
263
+ reject();
264
+ };
117
265
  };
266
+ var protect_default = protect;
118
267
 
119
268
  //#endregion
120
- //#region src/__legacy__/client.ts
121
- var ThunderIDExpressClient = class ThunderIDExpressClient {
122
- _authClient;
123
- _storage;
124
- static _clientConfig;
125
- static _instance;
126
- constructor(config, storage) {
127
- ThunderIDExpressClient._clientConfig = { ...config };
128
- const nodeClientConfig = {
129
- ...config,
130
- afterSignInUrl: config.appURL + (config.loginPath || DEFAULT_LOGIN_PATH),
131
- afterSignOutUrl: config.appURL + (config.logoutPath || DEFAULT_LOGOUT_PATH)
132
- };
133
- if (storage) {
134
- Logger.debug("Initializing user provided storage");
135
- this._storage = storage;
269
+ //#region src/middleware/flow.ts
270
+ /**
271
+ * Returns an Express route handler that drives the embedded sign-in flow loop.
272
+ *
273
+ * Requires `thunderID()` middleware with `mode: 'embedded'` to be mounted first.
274
+ * On each POST, the handler advances the flow one step and returns JSON.
275
+ *
276
+ * **First call** — no `executionId`:
277
+ * ```json
278
+ * { "applicationId": "app-id", "flowType": "SIGN_IN" }
279
+ * ```
280
+ * Response includes `executionId`, `challengeToken`, `authId`, and `components`
281
+ * (the UI elements to render).
282
+ *
283
+ * **Subsequent calls** — continue the flow:
284
+ * ```json
285
+ * { "executionId": "...", "challengeToken": "...", "authId": "...", "inputs": { ... } }
286
+ * ```
287
+ *
288
+ * **On completion** — flow returns `{ "done": true, "redirectUrl": "/login?code=..." }`.
289
+ * The client navigates to `redirectUrl`, which is handled by `handleSignIn()` to
290
+ * exchange the code and set the session cookie.
291
+ *
292
+ * ```ts
293
+ * app.use(thunderID({ ..., mode: 'embedded' }));
294
+ * app.get('/login', handleSignIn());
295
+ * app.post('/flow/sign-in', handleFlow());
296
+ * app.get('/logout', handleSignOut());
297
+ * ```
298
+ */
299
+ const handleFlow = () => {
300
+ return async (req, res) => {
301
+ const client = req.thunderIDAuth;
302
+ if (!client) {
303
+ logger.error("thunderID() middleware must be mounted before handleFlow()");
304
+ res.status(500).json({ error: "SDK not initialised" });
305
+ return;
136
306
  }
137
- this._authClient = new LegacyThunderIDNodeClient();
138
- this._authClient.initialize(nodeClientConfig, this._storage);
139
- }
140
- static getInstance(config, storage) {
141
- if (!ThunderIDExpressClient._instance && config) {
142
- ThunderIDExpressClient._instance = new ThunderIDExpressClient(config, storage);
143
- Logger.debug("Initialized ThunderIDExpressClient successfully");
307
+ const baseUrl = client.expressConfig?.baseUrl;
308
+ if (!baseUrl) {
309
+ res.status(500).json({ error: "baseUrl is not configured" });
310
+ return;
144
311
  }
145
- if (!ThunderIDExpressClient._instance && !config) throw Error(new ThunderIDAuthException("EXPRESS-CLIENT-GI1-NF01", "User configuration is not found", "User config has not been passed to initialize ThunderIDExpressClient").toString());
146
- return ThunderIDExpressClient._instance;
147
- }
148
- async signIn(req, res, next, signInConfig) {
149
- if (ExpressUtils.hasErrorInURL(req.originalUrl)) return Promise.reject(new ThunderIDAuthException("EXPRESS-CLIENT-SI-IV01", "Invalid login request URL", "Login request contains an error query parameter in the URL"));
150
- let userId = req.cookies.THUNDERID_SESSION_ID;
151
- if (!userId) userId = v4();
152
- const authRedirectCallback = (url) => {
153
- if (url) {
154
- Logger.debug("Redirecting to: " + url);
155
- res.cookie("THUNDERID_SESSION_ID", userId, {
156
- maxAge: ThunderIDExpressClient._clientConfig.cookieConfig?.maxAge ? ThunderIDExpressClient._clientConfig.cookieConfig.maxAge : CookieConfig.defaultMaxAge,
157
- httpOnly: ThunderIDExpressClient._clientConfig.cookieConfig?.httpOnly ?? CookieConfig.defaultHttpOnly,
158
- sameSite: ThunderIDExpressClient._clientConfig.cookieConfig?.sameSite ?? CookieConfig.defaultSameSite,
159
- secure: ThunderIDExpressClient._clientConfig.cookieConfig?.secure ?? CookieConfig.defaultSecure
312
+ const { applicationId, flowType, executionId, challengeToken, authId, inputs } = req.body ?? {};
313
+ try {
314
+ let resolvedAuthId = authId;
315
+ if (!executionId && !resolvedAuthId) {
316
+ const authUrl = await client.getSignInUrl();
317
+ resolvedAuthId = new URL(authUrl).searchParams.get("authId") ?? void 0;
318
+ }
319
+ const flowResponse = await executeEmbeddedSignInFlowV2({
320
+ authId: resolvedAuthId,
321
+ baseUrl,
322
+ payload: executionId ? {
323
+ action: "submit",
324
+ challengeToken,
325
+ executionId,
326
+ inputs
327
+ } : {
328
+ applicationId,
329
+ flowType: flowType ?? "SIGN_IN"
330
+ }
331
+ });
332
+ if (flowResponse.redirectUrl) {
333
+ res.json({
334
+ done: true,
335
+ redirectUrl: flowResponse.redirectUrl
160
336
  });
161
- res.redirect(url);
162
- next && typeof next === "function" && next();
337
+ return;
163
338
  }
164
- };
165
- const authResponse = await this._authClient.signIn(authRedirectCallback, userId, req.query.code, req.query.session_state, req.query.state, signInConfig);
166
- if (authResponse.accessToken || authResponse.idToken) return authResponse;
167
- else return {
168
- accessToken: "",
169
- createdAt: 0,
170
- expiresIn: "",
171
- idToken: "",
172
- refreshToken: "",
173
- scope: "",
174
- tokenType: ""
175
- };
176
- }
177
- async signOut(userId) {
178
- return this._authClient.signOut(userId);
179
- }
180
- async isSignedIn(userId) {
181
- return this._authClient.isSignedIn(userId);
182
- }
183
- async getIdToken(userId) {
184
- return this._authClient.getIdToken(userId);
185
- }
186
- async getUser(userId) {
187
- return this._authClient.getUser(userId);
188
- }
189
- async getOpenIDProviderEndpoints() {
190
- return this._authClient.getOpenIDProviderEndpoints();
191
- }
192
- async getDecodedIdToken(userId) {
193
- return this._authClient.getDecodedIdToken(userId);
194
- }
195
- async getAccessToken(userId) {
196
- return this._authClient.getAccessToken(userId);
197
- }
198
- async exchangeToken(config, userId) {
199
- return this._authClient.exchangeToken(config, userId);
200
- }
201
- async reInitialize(config) {
202
- return this._authClient.reInitialize(config);
203
- }
204
- async revokeAccessToken(userId) {
205
- return this._authClient.revokeAccessToken(userId);
206
- }
207
- static didSignOutFail(afterSignOutUrl) {
208
- return LegacyThunderIDNodeClient.didSignOutFail(afterSignOutUrl);
209
- }
210
- static isSignOutSuccessful(afterSignOutUrl) {
211
- return LegacyThunderIDNodeClient.isSignOutSuccessful(afterSignOutUrl);
212
- }
213
- static protectRoute(callback) {
214
- if (!this._instance) throw new ThunderIDAuthException("EXPRESS-CLIENT-PR-NF01", "ThunderIDExpressClient is not instantiated", "Create an instance of ThunderIDExpressClient before using calling this method.");
215
- return protectRoute(this._instance, callback);
216
- }
217
- static thunderIDExpressAuth(onSignIn, onSignOut, onError) {
218
- if (!this._instance) throw new ThunderIDAuthException("EXPRESS-CLIENT-AEA-NF01", "ThunderIDExpressClient is not instantiated", "Create an instance of ThunderIDExpressClient before using calling this method.");
219
- return thunderIDExpressAuth(this._instance, ThunderIDExpressClient._clientConfig, onSignIn, onSignOut, onError);
220
- }
221
- async getStorageManager() {
222
- return this._authClient.getStorageManager();
223
- }
339
+ res.json({
340
+ authId: resolvedAuthId,
341
+ challengeToken: flowResponse.challengeToken,
342
+ components: flowResponse.data?.meta?.components ?? [],
343
+ executionId: flowResponse.executionId,
344
+ flowStatus: flowResponse.flowStatus
345
+ });
346
+ } catch (e) {
347
+ logger.error(e.message);
348
+ res.status(500).json({ error: e.message ?? "Flow execution failed" });
349
+ }
350
+ };
224
351
  };
352
+ var flow_default = handleFlow;
225
353
 
226
354
  //#endregion
227
- export { ThunderIDExpressClient };
355
+ export { CookieConfig_default as CookieConfig, SESSION_COOKIE_NAME, ThunderIDExpressClient_default as ThunderIDExpressClient, flow_default as handleFlow, handleSignIn, handleSignOut, protect_default as protect, thunderID };
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
3
+ *
4
+ * WSO2 LLC. licenses this file to you under the Apache License,
5
+ * Version 2.0 (the "License"); you may not use this file except
6
+ * in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing,
12
+ * software distributed under the License is distributed on an
13
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ * KIND, either express or implied. See the License for the
15
+ * specific language governing permissions and limitations
16
+ * under the License.
17
+ */
18
+ import express from 'express';
19
+ import { ThunderIDExpressConfig } from '../models/config';
20
+ /**
21
+ * Returns Express middleware that initialises the ThunderID client and attaches
22
+ * it to `req.thunderIDAuth` for use in route handlers and `protect()`.
23
+ *
24
+ * Unlike the old `thunderID()` router, this function does **not** mount any
25
+ * routes automatically. Register sign-in and sign-out handlers explicitly:
26
+ *
27
+ * ```ts
28
+ * app.use(thunderID(config));
29
+ * app.get('/login', handleSignIn());
30
+ * app.get('/logout', handleSignOut());
31
+ * ```
32
+ *
33
+ * @param config - ThunderID Express configuration.
34
+ */
35
+ declare const thunderID: (config: ThunderIDExpressConfig) => express.RequestHandler;
36
+ /**
37
+ * Returns an Express route handler for the sign-in path.
38
+ *
39
+ * - If the request has no `?code` query param, initiates the OAuth 2.0 redirect.
40
+ * - If the request has `?code`, exchanges the authorization code for tokens,
41
+ * sets the session cookie, and calls `onSignIn`.
42
+ *
43
+ * Must be used after `thunderID()` middleware so that `req.thunderIDAuth` is set.
44
+ *
45
+ * ```ts
46
+ * app.get('/login', handleSignIn());
47
+ * ```
48
+ */
49
+ declare const handleSignIn: () => express.RequestHandler;
50
+ /**
51
+ * Returns an Express route handler for the sign-out path.
52
+ *
53
+ * - Clears the session cookie and redirects to the identity provider's
54
+ * end-session endpoint.
55
+ * - When the identity provider redirects back with `?state=sign_out_success`,
56
+ * calls `onSignOut`.
57
+ *
58
+ * Must be used after `thunderID()` middleware so that `req.thunderIDAuth` is set.
59
+ *
60
+ * ```ts
61
+ * app.get('/logout', handleSignOut());
62
+ * ```
63
+ */
64
+ declare const handleSignOut: () => express.RequestHandler;
65
+ export { thunderID, handleSignIn, handleSignOut };
66
+ //# sourceMappingURL=authentication.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authentication.d.ts","sourceRoot":"","sources":["../../src/middleware/authentication.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,OAAO,MAAM,SAAS,CAAC;AAG9B,OAAO,EAAC,sBAAsB,EAAC,MAAM,kBAAkB,CAAC;AAExD;;;;;;;;;;;;;;GAcG;AACH,QAAA,MAAM,SAAS,GAAI,QAAQ,sBAAsB,KAAG,OAAO,CAAC,cAsB3D,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,QAAA,MAAM,YAAY,QAAO,OAAO,CAAC,cA6BhC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,QAAA,MAAM,aAAa,QAAO,OAAO,CAAC,cAgDjC,CAAC;AAEF,OAAO,EAAC,SAAS,EAAE,YAAY,EAAE,aAAa,EAAC,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
3
+ *
4
+ * WSO2 LLC. licenses this file to you under the Apache License,
5
+ * Version 2.0 (the "License"); you may not use this file except
6
+ * in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing,
12
+ * software distributed under the License is distributed on an
13
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ * KIND, either express or implied. See the License for the
15
+ * specific language governing permissions and limitations
16
+ * under the License.
17
+ */
18
+ import express from 'express';
19
+ /**
20
+ * Returns an Express route handler that drives the embedded sign-in flow loop.
21
+ *
22
+ * Requires `thunderID()` middleware with `mode: 'embedded'` to be mounted first.
23
+ * On each POST, the handler advances the flow one step and returns JSON.
24
+ *
25
+ * **First call** — no `executionId`:
26
+ * ```json
27
+ * { "applicationId": "app-id", "flowType": "SIGN_IN" }
28
+ * ```
29
+ * Response includes `executionId`, `challengeToken`, `authId`, and `components`
30
+ * (the UI elements to render).
31
+ *
32
+ * **Subsequent calls** — continue the flow:
33
+ * ```json
34
+ * { "executionId": "...", "challengeToken": "...", "authId": "...", "inputs": { ... } }
35
+ * ```
36
+ *
37
+ * **On completion** — flow returns `{ "done": true, "redirectUrl": "/login?code=..." }`.
38
+ * The client navigates to `redirectUrl`, which is handled by `handleSignIn()` to
39
+ * exchange the code and set the session cookie.
40
+ *
41
+ * ```ts
42
+ * app.use(thunderID({ ..., mode: 'embedded' }));
43
+ * app.get('/login', handleSignIn());
44
+ * app.post('/flow/sign-in', handleFlow());
45
+ * app.get('/logout', handleSignOut());
46
+ * ```
47
+ */
48
+ declare const handleFlow: () => express.RequestHandler;
49
+ export default handleFlow;
50
+ //# sourceMappingURL=flow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow.d.ts","sourceRoot":"","sources":["../../src/middleware/flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,OAAO,MAAM,SAAS,CAAC;AAG9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,QAAA,MAAM,UAAU,QAAO,OAAO,CAAC,cAwD9B,CAAC;AAEF,eAAe,UAAU,CAAC"}