@thunderid/express 0.0.1

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 (35) hide show
  1. package/LICENSE +201 -0
  2. package/dist/ThunderIDExpressClient.d.ts +29 -0
  3. package/dist/ThunderIDExpressClient.d.ts.map +1 -0
  4. package/dist/__legacy__/client.d.ts +46 -0
  5. package/dist/__legacy__/client.d.ts.map +1 -0
  6. package/dist/__legacy__/constants/default-options.d.ts +26 -0
  7. package/dist/__legacy__/constants/default-options.d.ts.map +1 -0
  8. package/dist/__legacy__/constants/index.d.ts +20 -0
  9. package/dist/__legacy__/constants/index.d.ts.map +1 -0
  10. package/dist/__legacy__/constants/logger-config.d.ts +28 -0
  11. package/dist/__legacy__/constants/logger-config.d.ts.map +1 -0
  12. package/dist/__legacy__/middleware/authentication.d.ts +23 -0
  13. package/dist/__legacy__/middleware/authentication.d.ts.map +1 -0
  14. package/dist/__legacy__/middleware/index.d.ts +20 -0
  15. package/dist/__legacy__/middleware/index.d.ts.map +1 -0
  16. package/dist/__legacy__/middleware/protect-route.d.ts +22 -0
  17. package/dist/__legacy__/middleware/protect-route.d.ts.map +1 -0
  18. package/dist/__legacy__/models/client-config.d.ts +33 -0
  19. package/dist/__legacy__/models/client-config.d.ts.map +1 -0
  20. package/dist/__legacy__/models/data.d.ts +21 -0
  21. package/dist/__legacy__/models/data.d.ts.map +1 -0
  22. package/dist/__legacy__/models/index.d.ts +21 -0
  23. package/dist/__legacy__/models/index.d.ts.map +1 -0
  24. package/dist/__legacy__/models/protect-route.d.ts +20 -0
  25. package/dist/__legacy__/models/protect-route.d.ts.map +1 -0
  26. package/dist/__legacy__/utils/express-utils.d.ts +22 -0
  27. package/dist/__legacy__/utils/express-utils.d.ts.map +1 -0
  28. package/dist/cjs/index.cjs +257 -0
  29. package/dist/edge/index.js +227 -0
  30. package/dist/index.d.ts +21 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +227 -0
  33. package/dist/models/config.d.ts +30 -0
  34. package/dist/models/config.d.ts.map +1 -0
  35. package/package.json +67 -0
package/dist/index.js ADDED
@@ -0,0 +1,227 @@
1
+ import { LegacyThunderIDNodeClient, Logger, ThunderIDAuthException } from "@thunderid/node";
2
+ import { v4 } from "uuid";
3
+ import express from "express";
4
+
5
+ export * from "@thunderid/node"
6
+
7
+ //#region src/__legacy__/constants/default-options.ts
8
+ /**
9
+ * Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).
10
+ *
11
+ * WSO2 LLC. licenses this file to you under the Apache License,
12
+ * Version 2.0 (the "License"); you may not use this file except
13
+ * in compliance with the License.
14
+ * You may obtain a copy of the License at
15
+ *
16
+ * http://www.apache.org/licenses/LICENSE-2.0
17
+ *
18
+ * Unless required by applicable law or agreed to in writing,
19
+ * software distributed under the License is distributed on an
20
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21
+ * KIND, either express or implied. See the License for the
22
+ * specific language governing permissions and limitations
23
+ * under the License.
24
+ */
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";
34
+
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
+ };
50
+ };
51
+
52
+ //#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;
59
+ next();
60
+ });
61
+ router.get(config.loginPath || DEFAULT_LOGIN_PATH, async (req, res, next) => {
62
+ try {
63
+ const response = await thunderIDExpressClient.signIn(req, res, next, config.signInConfig);
64
+ if (response.accessToken || response.idToken) onSignIn(res, response);
65
+ } catch (e) {
66
+ Logger.error(e.message);
67
+ onError(res, e);
68
+ }
69
+ });
70
+ router.get(config.logoutPath || DEFAULT_LOGOUT_PATH, async (req, res, next) => {
71
+ if (req.query.state === "sign_out_success") {
72
+ onSignOut(res);
73
+ return;
74
+ }
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."));
77
+ return;
78
+ } else try {
79
+ const signOutURL = await req.thunderIDAuth.signOut(req.cookies.THUNDERID_SESSION_ID);
80
+ if (signOutURL) {
81
+ res.cookie("THUNDERID_SESSION_ID", null, { maxAge: 0 });
82
+ res.redirect(signOutURL);
83
+ return;
84
+ }
85
+ } catch (e) {
86
+ onError(res, e);
87
+ return;
88
+ }
89
+ });
90
+ return router;
91
+ };
92
+
93
+ //#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
+ }
117
+ };
118
+
119
+ //#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;
136
+ }
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");
144
+ }
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
160
+ });
161
+ res.redirect(url);
162
+ next && typeof next === "function" && next();
163
+ }
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
+ }
224
+ };
225
+
226
+ //#endregion
227
+ export { ThunderIDExpressClient };
@@ -0,0 +1,30 @@
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 { ThunderIDNodeConfig } from '@thunderid/node';
19
+ /**
20
+ * Configuration type for the ThunderID Express.js SDK.
21
+ * Extends the base Config type from @thunderid/node with Express.js specific settings.
22
+ *
23
+ * @remarks
24
+ * This type is used to configure the Express.js SDK with settings like:
25
+ * - Server endpoints
26
+ * - Authentication parameters
27
+ * - Session management options
28
+ */
29
+ export type ThunderIDExpressConfig = ThunderIDNodeConfig;
30
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/models/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAC,mBAAmB,EAAC,MAAM,iBAAiB,CAAC;AAEpD;;;;;;;;;GASG;AACH,MAAM,MAAM,sBAAsB,GAAG,mBAAmB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@thunderid/express",
3
+ "version": "0.0.1",
4
+ "description": "Express.js SDK for ThunderID",
5
+ "keywords": [
6
+ "thunderid",
7
+ "express.js",
8
+ "server"
9
+ ],
10
+ "homepage": "https://github.com/thunder-id/thunderid/tree/main/sdks/express#readme",
11
+ "bugs": {
12
+ "url": "https://github.com/thunder-id/thunderid/issues"
13
+ },
14
+ "author": "WSO2",
15
+ "license": "Apache-2.0",
16
+ "type": "module",
17
+ "main": "dist/index.js",
18
+ "module": "dist/index.js",
19
+ "commonjs": "dist/cjs/index.js",
20
+ "exports": {
21
+ "import": "./dist/index.js",
22
+ "require": "./dist/cjs/index.js"
23
+ },
24
+ "files": [
25
+ "dist",
26
+ "README.md",
27
+ "LICENSE"
28
+ ],
29
+ "types": "dist/index.d.ts",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/thunder-id/thunderid",
33
+ "directory": "sdks/express"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "22.15.3",
37
+ "eslint": "9.39.4",
38
+ "express": "5.2.1",
39
+ "prettier": "3.6.2",
40
+ "rimraf": "6.1.3",
41
+ "rolldown": "1.0.0-beta.45",
42
+ "typescript": "5.9.3",
43
+ "vitest": "4.1.3",
44
+ "@thunderid/eslint-plugin": "^0.0.0",
45
+ "@thunderid/prettier-config": "^0.0.0"
46
+ },
47
+ "dependencies": {
48
+ "uuid": "11.1.0",
49
+ "@thunderid/node": "^0.0.0"
50
+ },
51
+ "peerDependencies": {
52
+ "express": ">=4.21.2"
53
+ },
54
+ "publishConfig": {
55
+ "access": "public"
56
+ },
57
+ "scripts": {
58
+ "build": "pnpm clean && rolldown -c rolldown.config.js && tsc -p tsconfig.lib.json --emitDeclarationOnly --outDir dist",
59
+ "clean": "rimraf dist",
60
+ "format:check": "prettier --check --cache .",
61
+ "format:fix": "prettier --write --cache .",
62
+ "lint": "eslint . --ext .js,.jsx,.ts,.tsx,.cjs,.mjs",
63
+ "lint:fix": "eslint . --fix --ext .js,.jsx,.ts,.tsx,.cjs,.mjs",
64
+ "test": "vitest --passWithNoTests",
65
+ "typecheck": "tsc -p tsconfig.lib.json"
66
+ }
67
+ }