@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.
- package/LICENSE +201 -0
- package/dist/ThunderIDExpressClient.d.ts +29 -0
- package/dist/ThunderIDExpressClient.d.ts.map +1 -0
- package/dist/__legacy__/client.d.ts +46 -0
- package/dist/__legacy__/client.d.ts.map +1 -0
- package/dist/__legacy__/constants/default-options.d.ts +26 -0
- package/dist/__legacy__/constants/default-options.d.ts.map +1 -0
- package/dist/__legacy__/constants/index.d.ts +20 -0
- package/dist/__legacy__/constants/index.d.ts.map +1 -0
- package/dist/__legacy__/constants/logger-config.d.ts +28 -0
- package/dist/__legacy__/constants/logger-config.d.ts.map +1 -0
- package/dist/__legacy__/middleware/authentication.d.ts +23 -0
- package/dist/__legacy__/middleware/authentication.d.ts.map +1 -0
- package/dist/__legacy__/middleware/index.d.ts +20 -0
- package/dist/__legacy__/middleware/index.d.ts.map +1 -0
- package/dist/__legacy__/middleware/protect-route.d.ts +22 -0
- package/dist/__legacy__/middleware/protect-route.d.ts.map +1 -0
- package/dist/__legacy__/models/client-config.d.ts +33 -0
- package/dist/__legacy__/models/client-config.d.ts.map +1 -0
- package/dist/__legacy__/models/data.d.ts +21 -0
- package/dist/__legacy__/models/data.d.ts.map +1 -0
- package/dist/__legacy__/models/index.d.ts +21 -0
- package/dist/__legacy__/models/index.d.ts.map +1 -0
- package/dist/__legacy__/models/protect-route.d.ts +20 -0
- package/dist/__legacy__/models/protect-route.d.ts.map +1 -0
- package/dist/__legacy__/utils/express-utils.d.ts +22 -0
- package/dist/__legacy__/utils/express-utils.d.ts.map +1 -0
- package/dist/cjs/index.cjs +257 -0
- package/dist/edge/index.js +227 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +227 -0
- package/dist/models/config.d.ts +30 -0
- package/dist/models/config.d.ts.map +1 -0
- 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
|
+
}
|