@privateaim/server-http-kit 0.8.21 → 0.8.23
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 +38 -0
- package/dist/index.mjs +548 -0
- package/dist/index.mjs.map +1 -0
- package/dist/middlewares/error.d.ts.map +1 -1
- package/dist/services/authup/middleware.d.ts.map +1 -1
- package/dist/services/authup/permission-provider.d.ts +2 -2
- package/dist/services/authup/permission-provider.d.ts.map +1 -1
- package/dist/swagger/module.d.ts +1 -1
- package/dist/swagger/module.d.ts.map +1 -1
- package/package.json +36 -26
- package/rollup.config.mjs +18 -0
- package/src/middlewares/error.ts +6 -1
- package/src/services/authup/middleware.ts +15 -9
- package/src/services/authup/permission-provider.ts +2 -2
- package/src/services/authup/utils.ts +2 -2
- package/dist/constants.js +0 -15
- package/dist/constants.js.map +0 -1
- package/dist/index.js +0 -28
- package/dist/index.js.map +0 -1
- package/dist/middlewares/basic.js +0 -14
- package/dist/middlewares/basic.js.map +0 -1
- package/dist/middlewares/cors.js +0 -23
- package/dist/middlewares/cors.js.map +0 -1
- package/dist/middlewares/decorators.js +0 -39
- package/dist/middlewares/decorators.js.map +0 -1
- package/dist/middlewares/error.js +0 -91
- package/dist/middlewares/error.js.map +0 -1
- package/dist/middlewares/force-logged-in.js +0 -18
- package/dist/middlewares/force-logged-in.js.map +0 -1
- package/dist/middlewares/index.js +0 -33
- package/dist/middlewares/index.js.map +0 -1
- package/dist/middlewares/module.js +0 -41
- package/dist/middlewares/module.js.map +0 -1
- package/dist/middlewares/prometheus.js +0 -14
- package/dist/middlewares/prometheus.js.map +0 -1
- package/dist/middlewares/rate-limit.js +0 -36
- package/dist/middlewares/rate-limit.js.map +0 -1
- package/dist/middlewares/swagger.js +0 -29
- package/dist/middlewares/swagger.js.map +0 -1
- package/dist/middlewares/types.js +0 -9
- package/dist/middlewares/types.js.map +0 -1
- package/dist/request/env.js +0 -21
- package/dist/request/env.js.map +0 -1
- package/dist/request/identity-realm.js +0 -21
- package/dist/request/identity-realm.js.map +0 -1
- package/dist/request/identity.js +0 -32
- package/dist/request/identity.js.map +0 -1
- package/dist/request/index.js +0 -28
- package/dist/request/index.js.map +0 -1
- package/dist/request/permission/helper.js +0 -23
- package/dist/request/permission/helper.js.map +0 -1
- package/dist/request/permission/index.js +0 -25
- package/dist/request/permission/index.js.map +0 -1
- package/dist/request/permission/module.js +0 -47
- package/dist/request/permission/module.js.map +0 -1
- package/dist/request/types.js +0 -9
- package/dist/request/types.js.map +0 -1
- package/dist/services/authup/index.js +0 -25
- package/dist/services/authup/index.js.map +0 -1
- package/dist/services/authup/middleware.js +0 -86
- package/dist/services/authup/middleware.js.map +0 -1
- package/dist/services/authup/permission-provider.js +0 -20
- package/dist/services/authup/permission-provider.js.map +0 -1
- package/dist/services/authup/types.js +0 -9
- package/dist/services/authup/types.js.map +0 -1
- package/dist/services/authup/utils.js +0 -51
- package/dist/services/authup/utils.js.map +0 -1
- package/dist/services/index.js +0 -24
- package/dist/services/index.js.map +0 -1
- package/dist/swagger/index.js +0 -24
- package/dist/swagger/index.js.map +0 -1
- package/dist/swagger/module.js +0 -66
- package/dist/swagger/module.js.map +0 -1
- package/dist/swagger/types.js +0 -9
- package/dist/swagger/types.js.map +0 -1
- package/dist/utils/boolable-to-object.js +0 -16
- package/dist/utils/boolable-to-object.js.map +0 -1
- package/dist/utils/index.js +0 -24
- package/dist/utils/index.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.8.23](https://github.com/PrivateAIM/hub/compare/v0.8.22...v0.8.23) (2026-02-02)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **deps:** bump the minorandpatch group across 1 directory with 19 updates ([#1392](https://github.com/PrivateAIM/hub/issues/1392)) ([23060bf](https://github.com/PrivateAIM/hub/commit/23060bfce24100d17d4d83c7ee45ed6d85073c6b))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Dependencies
|
|
12
|
+
|
|
13
|
+
* The following workspace dependencies were updated
|
|
14
|
+
* dependencies
|
|
15
|
+
* @privateaim/kit bumped from ^0.8.22 to ^0.8.23
|
|
16
|
+
* @privateaim/server-kit bumped from ^0.8.22 to ^0.8.23
|
|
17
|
+
* @privateaim/telemetry-kit bumped from ^0.8.22 to ^0.8.23
|
|
18
|
+
|
|
19
|
+
## [0.8.22](https://github.com/PrivateAIM/hub/compare/v0.8.21...v0.8.22) (2026-01-27)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Features
|
|
23
|
+
|
|
24
|
+
* check handlers for analysis building and distribution ([#1318](https://github.com/PrivateAIM/hub/issues/1318)) ([a43ba20](https://github.com/PrivateAIM/hub/commit/a43ba203223ee5ffc00e63c3ff1d8829970590b2))
|
|
25
|
+
* migrate to esm & replace jest with vitest ([#1368](https://github.com/PrivateAIM/hub/issues/1368)) ([5a4d9d1](https://github.com/PrivateAIM/hub/commit/5a4d9d1ce118f65740aa49caf948208eac299032))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Bug Fixes
|
|
29
|
+
|
|
30
|
+
* **deps:** bump the minorandpatch group across 1 directory with 16 updates ([#1329](https://github.com/PrivateAIM/hub/issues/1329)) ([7b394da](https://github.com/PrivateAIM/hub/commit/7b394da159d8e52cc37fe489832307a234f3ddb0))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
### Dependencies
|
|
34
|
+
|
|
35
|
+
* The following workspace dependencies were updated
|
|
36
|
+
* dependencies
|
|
37
|
+
* @privateaim/kit bumped from ^0.8.21 to ^0.8.22
|
|
38
|
+
* @privateaim/server-kit bumped from ^0.8.21 to ^0.8.22
|
|
39
|
+
* @privateaim/telemetry-kit bumped from ^0.8.21 to ^0.8.22
|
|
40
|
+
|
|
3
41
|
## [0.8.21](https://github.com/PrivateAIM/hub/compare/v0.8.20...v0.8.21) (2025-11-04)
|
|
4
42
|
|
|
5
43
|
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,548 @@
|
|
|
1
|
+
import { basic } from '@routup/basic';
|
|
2
|
+
import cors from 'cors';
|
|
3
|
+
import { coreHandler, errorHandler, setRequestEnv as setRequestEnv$1, useRequestEnv as useRequestEnv$1, getRequestHeader } from 'routup';
|
|
4
|
+
import 'body-parser';
|
|
5
|
+
import 'qs';
|
|
6
|
+
import { decorators } from '@routup/decorators';
|
|
7
|
+
import { PermissionError, BuiltInPolicyType, PermissionMemoryProvider, PermissionChecker } from '@authup/access';
|
|
8
|
+
import { isObject, HubError } from '@privateaim/kit';
|
|
9
|
+
import { LogChannel, LogFlag } from '@privateaim/telemetry-kit';
|
|
10
|
+
import { useLogger } from '@privateaim/server-kit';
|
|
11
|
+
import { EntityRelationLookupError } from 'typeorm-extension';
|
|
12
|
+
import { ValidupNestedError, ValidupValidatorError } from 'validup';
|
|
13
|
+
import { BadRequestError, UnauthorizedError } from '@ebec/http';
|
|
14
|
+
import { REALM_MASTER_NAME, ScopeName } from '@authup/core-kit';
|
|
15
|
+
import { RedisTokenVerifierCache, MemoryTokenVerifierCache, TokenVerifier } from '@authup/server-adapter-kit';
|
|
16
|
+
import { createMiddleware } from '@authup/server-adapter-http';
|
|
17
|
+
import { parseAuthorizationHeader } from 'hapic';
|
|
18
|
+
import { unwrapOAuth2Scope } from '@authup/specs';
|
|
19
|
+
import { prometheus } from '@routup/prometheus';
|
|
20
|
+
import { rateLimit } from '@routup/rate-limit';
|
|
21
|
+
import path from 'node:path';
|
|
22
|
+
import { swaggerUI, generate, Version } from '@routup/swagger';
|
|
23
|
+
import { loadSync, load } from 'locter';
|
|
24
|
+
import process from 'node:process';
|
|
25
|
+
|
|
26
|
+
/*
|
|
27
|
+
* Copyright (c) 2024.
|
|
28
|
+
* Author Peter Placzek (tada5hi)
|
|
29
|
+
* For the full copyright and license information,
|
|
30
|
+
* view the LICENSE file that was distributed with this source code.
|
|
31
|
+
*/ var HTTPHandlerOperation = /*#__PURE__*/ function(HTTPHandlerOperation) {
|
|
32
|
+
HTTPHandlerOperation["CREATE"] = "create";
|
|
33
|
+
HTTPHandlerOperation["UPDATE"] = "update";
|
|
34
|
+
return HTTPHandlerOperation;
|
|
35
|
+
}({});
|
|
36
|
+
|
|
37
|
+
function mountBasicMiddleware(router) {
|
|
38
|
+
router.use(basic());
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function mountCorsMiddleware(router) {
|
|
42
|
+
router.use(coreHandler((req, res, next)=>cors({
|
|
43
|
+
origin (origin, callback) {
|
|
44
|
+
callback(null, true);
|
|
45
|
+
},
|
|
46
|
+
credentials: true
|
|
47
|
+
})(req, res, next)));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const BodySymbol = Symbol.for('ReqBody');
|
|
51
|
+
function useRequestBody(req, key) {
|
|
52
|
+
let body;
|
|
53
|
+
/* istanbul ignore next */ if ('body' in req) {
|
|
54
|
+
body = req.body;
|
|
55
|
+
}
|
|
56
|
+
if (BodySymbol in req) {
|
|
57
|
+
if (body) {
|
|
58
|
+
body = {
|
|
59
|
+
...req[BodySymbol],
|
|
60
|
+
...body
|
|
61
|
+
};
|
|
62
|
+
} else {
|
|
63
|
+
body = req[BodySymbol];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (body) {
|
|
67
|
+
if (typeof key === 'string') {
|
|
68
|
+
return body[key];
|
|
69
|
+
}
|
|
70
|
+
return body;
|
|
71
|
+
}
|
|
72
|
+
return typeof key === 'string' ? undefined : {};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const CookieSymbol = Symbol.for('ReqCookie');
|
|
76
|
+
function useRequestCookies(req) {
|
|
77
|
+
if (CookieSymbol in req) {
|
|
78
|
+
return req[CookieSymbol];
|
|
79
|
+
}
|
|
80
|
+
return {};
|
|
81
|
+
}
|
|
82
|
+
function useRequestCookie(req, name) {
|
|
83
|
+
return useRequestCookies(req)[name];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const QuerySymbol = Symbol.for('ReqQuery');
|
|
87
|
+
function useRequestQuery(req, key) {
|
|
88
|
+
/* istanbul ignore if */ if ('query' in req) {
|
|
89
|
+
if (typeof key === 'string') {
|
|
90
|
+
return req.query[key];
|
|
91
|
+
}
|
|
92
|
+
return req.query;
|
|
93
|
+
}
|
|
94
|
+
if (QuerySymbol in req) {
|
|
95
|
+
if (typeof key === 'string') {
|
|
96
|
+
return req[QuerySymbol][key];
|
|
97
|
+
}
|
|
98
|
+
return req[QuerySymbol];
|
|
99
|
+
}
|
|
100
|
+
return typeof key === 'string' ? undefined : {};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function mountDecoratorsMiddleware(router, options) {
|
|
104
|
+
router.use(decorators({
|
|
105
|
+
controllers: options.controllers,
|
|
106
|
+
parameter: {
|
|
107
|
+
body: (context, name)=>{
|
|
108
|
+
if (name) {
|
|
109
|
+
return useRequestBody(context.request, name);
|
|
110
|
+
}
|
|
111
|
+
return useRequestBody(context.request);
|
|
112
|
+
},
|
|
113
|
+
cookie: (context, name)=>{
|
|
114
|
+
if (name) {
|
|
115
|
+
return useRequestCookie(context.request, name);
|
|
116
|
+
}
|
|
117
|
+
return useRequestCookies(context.request);
|
|
118
|
+
},
|
|
119
|
+
query: (context, name)=>{
|
|
120
|
+
if (name) {
|
|
121
|
+
return useRequestQuery(context.request, name);
|
|
122
|
+
}
|
|
123
|
+
return useRequestQuery(context.request);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function mountErrorMiddleware(router) {
|
|
130
|
+
router.use(errorHandler((error, req, res)=>{
|
|
131
|
+
const isServerError = error.statusCode >= 500 && error.statusCode < 600;
|
|
132
|
+
if (isServerError || error.logMessage) {
|
|
133
|
+
if (error.cause && isObject(error.cause)) {
|
|
134
|
+
useLogger().error({
|
|
135
|
+
message: error.cause,
|
|
136
|
+
[LogFlag.CHANNEL]: LogChannel.HTTP
|
|
137
|
+
});
|
|
138
|
+
} else {
|
|
139
|
+
useLogger().error({
|
|
140
|
+
message: error,
|
|
141
|
+
[LogFlag.CHANNEL]: LogChannel.HTTP
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (error.cause instanceof HubError) {
|
|
146
|
+
error.expose = true;
|
|
147
|
+
error.statusCode = 400;
|
|
148
|
+
}
|
|
149
|
+
if (error.cause instanceof PermissionError) {
|
|
150
|
+
error.expose = true;
|
|
151
|
+
if (error.cause.policy && error.cause.policy.type === BuiltInPolicyType.IDENTITY) {
|
|
152
|
+
error.statusCode = 401;
|
|
153
|
+
} else {
|
|
154
|
+
error.statusCode = 403;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (error.cause instanceof EntityRelationLookupError) {
|
|
158
|
+
error.expose = true;
|
|
159
|
+
error.statusCode = 400;
|
|
160
|
+
}
|
|
161
|
+
if (error.cause instanceof ValidupNestedError) {
|
|
162
|
+
error.expose = true;
|
|
163
|
+
error.statusCode = 400;
|
|
164
|
+
error.data = {
|
|
165
|
+
children: error.cause.children,
|
|
166
|
+
attributes: error.cause.children.map((child)=>child.pathAbsolute)
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
if (error.cause instanceof ValidupValidatorError) {
|
|
170
|
+
error.expose = true;
|
|
171
|
+
error.statusCode = 400;
|
|
172
|
+
}
|
|
173
|
+
// catch and decorate some db errors :)
|
|
174
|
+
switch(error.code){
|
|
175
|
+
case 'ER_DUP_ENTRY':
|
|
176
|
+
case 'SQLITE_CONSTRAINT_UNIQUE':
|
|
177
|
+
{
|
|
178
|
+
error.statusCode = 409;
|
|
179
|
+
error.message = 'An entry with some unique attributes already exist.';
|
|
180
|
+
error.expose = true;
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
case 'ER_DISK_FULL':
|
|
184
|
+
error.statusCode = 507;
|
|
185
|
+
error.message = 'No database operation possible, due the leak of free disk space.';
|
|
186
|
+
error.expose = true;
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
const exposeError = typeof error.expose === 'boolean' ? error.expose : !isServerError;
|
|
190
|
+
if (!exposeError) {
|
|
191
|
+
error.message = 'An internal server error occurred.';
|
|
192
|
+
}
|
|
193
|
+
res.statusCode = error.statusCode;
|
|
194
|
+
return {
|
|
195
|
+
statusCode: error.statusCode,
|
|
196
|
+
code: `${error.code}`,
|
|
197
|
+
message: error.message,
|
|
198
|
+
...exposeError && isObject(error.data) ? error.data : {}
|
|
199
|
+
};
|
|
200
|
+
}));
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function useRequestEnv(req, key) {
|
|
204
|
+
if (typeof key === 'string') {
|
|
205
|
+
return useRequestEnv$1(req, key);
|
|
206
|
+
}
|
|
207
|
+
return useRequestEnv$1(req);
|
|
208
|
+
}
|
|
209
|
+
function setRequestEnv(req, key, value) {
|
|
210
|
+
return setRequestEnv$1(req, key, value);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function setRequestPermissionChecker(req, checker) {
|
|
214
|
+
setRequestEnv(req, 'permissionChecker', checker);
|
|
215
|
+
}
|
|
216
|
+
function useRequestPermissionChecker(req) {
|
|
217
|
+
const checker = useRequestEnv(req, 'permissionChecker');
|
|
218
|
+
if (!checker) {
|
|
219
|
+
throw new BadRequestError('The request permission checker is not initialized.');
|
|
220
|
+
}
|
|
221
|
+
return checker;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function useRequestIdentity(req) {
|
|
225
|
+
return useRequestEnv(req, 'identity');
|
|
226
|
+
}
|
|
227
|
+
function setRequestIdentity(req, identity) {
|
|
228
|
+
setRequestEnv(req, 'identity', identity);
|
|
229
|
+
}
|
|
230
|
+
function useRequestIdentityOrFail(req) {
|
|
231
|
+
const identity = useRequestIdentity(req);
|
|
232
|
+
if (!identity) {
|
|
233
|
+
throw new UnauthorizedError();
|
|
234
|
+
}
|
|
235
|
+
return identity;
|
|
236
|
+
}
|
|
237
|
+
function isRequestIdentityMasterRealmMember(input) {
|
|
238
|
+
return input.realmName === REALM_MASTER_NAME;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
class RequestPermissionChecker {
|
|
242
|
+
req;
|
|
243
|
+
checker;
|
|
244
|
+
constructor(req, checker){
|
|
245
|
+
this.req = req;
|
|
246
|
+
this.checker = checker;
|
|
247
|
+
}
|
|
248
|
+
// --------------------------------------------------------------
|
|
249
|
+
async check(ctx) {
|
|
250
|
+
return this.checker.check(this.extendCheckContext(ctx));
|
|
251
|
+
}
|
|
252
|
+
async preCheck(ctx) {
|
|
253
|
+
return this.checker.preCheck(this.extendCheckContext(ctx));
|
|
254
|
+
}
|
|
255
|
+
// --------------------------------------------------------------
|
|
256
|
+
async preCheckOneOf(ctx) {
|
|
257
|
+
return this.checker.preCheckOneOf(this.extendCheckContext(ctx));
|
|
258
|
+
}
|
|
259
|
+
async checkOneOf(ctx) {
|
|
260
|
+
return this.checker.checkOneOf(this.extendCheckContext(ctx));
|
|
261
|
+
}
|
|
262
|
+
// --------------------------------------------------------------
|
|
263
|
+
extendCheckContext(ctx) {
|
|
264
|
+
const scopes = useRequestEnv(this.req, 'scopes') || [];
|
|
265
|
+
if (scopes.indexOf(ScopeName.GLOBAL) !== -1) {
|
|
266
|
+
ctx.input = {
|
|
267
|
+
...ctx.input || {},
|
|
268
|
+
identity: useRequestIdentity(this.req)
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
return ctx;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function useRequestIdentityRealm(req) {
|
|
276
|
+
const identity = useRequestIdentity(req);
|
|
277
|
+
if (!identity) {
|
|
278
|
+
return undefined;
|
|
279
|
+
}
|
|
280
|
+
return {
|
|
281
|
+
id: identity.realmId,
|
|
282
|
+
name: identity.realmName
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
class ForceLoggedInMiddleware {
|
|
287
|
+
run(request, response, next) {
|
|
288
|
+
useRequestIdentityOrFail(request);
|
|
289
|
+
next();
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/*
|
|
294
|
+
* Copyright (c) 2025.
|
|
295
|
+
* Author Peter Placzek (tada5hi)
|
|
296
|
+
* For the full copyright and license information,
|
|
297
|
+
* view the LICENSE file that was distributed with this source code.
|
|
298
|
+
*/ class FakePermissionProvider {
|
|
299
|
+
async get(criteria) {
|
|
300
|
+
return {
|
|
301
|
+
name: criteria.name,
|
|
302
|
+
realmId: criteria.realmId,
|
|
303
|
+
policy: null
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function createFakeTokenVerificationData() {
|
|
309
|
+
return {
|
|
310
|
+
realm_id: 'd94b2f28-29e3-4ced-b8f1-6923a01dc1ee',
|
|
311
|
+
realm_name: REALM_MASTER_NAME,
|
|
312
|
+
sub_kind: 'user',
|
|
313
|
+
sub: 'd94b2f28-29e3-4ced-b8f1-6923a01dc1ee',
|
|
314
|
+
sub_name: 'admin',
|
|
315
|
+
permissions: []
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
function applyTokenVerificationData(req, data, fakeAbilities) {
|
|
319
|
+
let provider;
|
|
320
|
+
if (fakeAbilities) {
|
|
321
|
+
provider = new FakePermissionProvider();
|
|
322
|
+
} else {
|
|
323
|
+
provider = new PermissionMemoryProvider(data.permissions);
|
|
324
|
+
}
|
|
325
|
+
const permissionChecker = new PermissionChecker({
|
|
326
|
+
provider
|
|
327
|
+
});
|
|
328
|
+
const requestPermissionChecker = new RequestPermissionChecker(req, permissionChecker);
|
|
329
|
+
setRequestEnv(req, 'permissionChecker', requestPermissionChecker);
|
|
330
|
+
setRequestEnv(req, 'identity', {
|
|
331
|
+
id: data.sub,
|
|
332
|
+
type: data.sub_kind,
|
|
333
|
+
realmId: data.realm_id,
|
|
334
|
+
realmName: data.realm_name,
|
|
335
|
+
attributes: {
|
|
336
|
+
id: data.sub,
|
|
337
|
+
name: data.sub_name
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
setRequestEnv(req, 'scopes', unwrapOAuth2Scope(data.scope || []));
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
function mountAuthupMiddleware(router, options) {
|
|
344
|
+
if (!options.client) {
|
|
345
|
+
const data = createFakeTokenVerificationData();
|
|
346
|
+
router.use(coreHandler((req, res, next)=>{
|
|
347
|
+
applyTokenVerificationData(req, data, options.fakeAbilities);
|
|
348
|
+
next();
|
|
349
|
+
}));
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
router.use(coreHandler(async (req, res, next)=>{
|
|
353
|
+
const headerRaw = getRequestHeader(req, 'authorization');
|
|
354
|
+
if (typeof headerRaw !== 'string') {
|
|
355
|
+
next();
|
|
356
|
+
}
|
|
357
|
+
const cacheKey = `authorization-header:${headerRaw}`;
|
|
358
|
+
if (options.redisClient) {
|
|
359
|
+
const data = await options.redisClient.get(cacheKey);
|
|
360
|
+
if (data) {
|
|
361
|
+
req.headers.authorization = `Bearer ${data}`;
|
|
362
|
+
next();
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
const header = parseAuthorizationHeader(headerRaw);
|
|
367
|
+
if (header.type === 'Basic') {
|
|
368
|
+
const token = await options.client.token.createWithPassword({
|
|
369
|
+
username: header.username,
|
|
370
|
+
password: header.password
|
|
371
|
+
});
|
|
372
|
+
req.headers.authorization = `Bearer ${token.access_token}`;
|
|
373
|
+
if (options.redisClient) {
|
|
374
|
+
await options.redisClient.setex(cacheKey, token.expires_in, token.access_token);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
next();
|
|
378
|
+
}));
|
|
379
|
+
let tokenCreator;
|
|
380
|
+
if (options.vaultClient) {
|
|
381
|
+
tokenCreator = {
|
|
382
|
+
type: 'robotInVault',
|
|
383
|
+
name: 'system',
|
|
384
|
+
vault: options.vaultClient,
|
|
385
|
+
baseURL: options.client.getBaseURL()
|
|
386
|
+
};
|
|
387
|
+
} else {
|
|
388
|
+
tokenCreator = {
|
|
389
|
+
type: 'user',
|
|
390
|
+
name: 'admin',
|
|
391
|
+
password: 'start123',
|
|
392
|
+
baseURL: options.client.getBaseURL()
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
let cache;
|
|
396
|
+
if (options.redisClient) {
|
|
397
|
+
cache = new RedisTokenVerifierCache(options.redisClient);
|
|
398
|
+
} else {
|
|
399
|
+
cache = new MemoryTokenVerifierCache();
|
|
400
|
+
}
|
|
401
|
+
const middleware = createMiddleware({
|
|
402
|
+
tokenByCookie: (req, cookieName)=>useRequestCookie(req, cookieName),
|
|
403
|
+
tokenVerifier: new TokenVerifier({
|
|
404
|
+
baseURL: options.client.getBaseURL(),
|
|
405
|
+
creator: tokenCreator,
|
|
406
|
+
cache
|
|
407
|
+
}),
|
|
408
|
+
tokenVerifierHandler: (req, data)=>applyTokenVerificationData(req, data, options.fakeAbilities)
|
|
409
|
+
});
|
|
410
|
+
router.use(coreHandler((req, res, next)=>middleware(req, res, next)));
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/*
|
|
414
|
+
* Copyright (c) 2024.
|
|
415
|
+
* Author Peter Placzek (tada5hi)
|
|
416
|
+
* For the full copyright and license information,
|
|
417
|
+
* view the LICENSE file that was distributed with this source code.
|
|
418
|
+
*/ function boolableToObject(input) {
|
|
419
|
+
if (typeof input === 'boolean') {
|
|
420
|
+
return {};
|
|
421
|
+
}
|
|
422
|
+
return input;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function mountPrometheusMiddleware(router) {
|
|
426
|
+
router.use(prometheus());
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
function mountRateLimiterMiddleware(router) {
|
|
430
|
+
const options = {
|
|
431
|
+
skip (req) {
|
|
432
|
+
const identity = useRequestIdentity(req);
|
|
433
|
+
return identity && identity.type === 'robot' && identity.realmName === REALM_MASTER_NAME;
|
|
434
|
+
},
|
|
435
|
+
max (req) {
|
|
436
|
+
const identity = useRequestIdentity(req);
|
|
437
|
+
if (identity && identity.type === 'user') {
|
|
438
|
+
return 60 * 100; // 100 req p. sec
|
|
439
|
+
}
|
|
440
|
+
if (identity && (identity.type === 'robot' || identity.type === 'client')) {
|
|
441
|
+
return 60 * 1000; // 1000 req p. sec
|
|
442
|
+
}
|
|
443
|
+
return 60 * 20; // 20 req p. sec
|
|
444
|
+
},
|
|
445
|
+
windowMs: 60 * 1000
|
|
446
|
+
};
|
|
447
|
+
router.use(rateLimit(options));
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
function mountSwaggerMiddleware(router, options = {}) {
|
|
451
|
+
let document;
|
|
452
|
+
if (options.cwd) {
|
|
453
|
+
document = loadSync(path.join(options.cwd, 'swagger.json'));
|
|
454
|
+
} else {
|
|
455
|
+
document = loadSync(path.join(process.cwd(), 'writable', 'swagger.json'));
|
|
456
|
+
}
|
|
457
|
+
router.use('/docs', swaggerUI(document, {
|
|
458
|
+
baseURL: options.baseURL
|
|
459
|
+
}));
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
function mountMiddlewares(router, options = {}) {
|
|
463
|
+
if (options.cors) {
|
|
464
|
+
mountCorsMiddleware(router);
|
|
465
|
+
}
|
|
466
|
+
if (options.basic) {
|
|
467
|
+
mountBasicMiddleware(router);
|
|
468
|
+
}
|
|
469
|
+
if (options.authup) {
|
|
470
|
+
mountAuthupMiddleware(router, options.authup);
|
|
471
|
+
}
|
|
472
|
+
if (options.prometheus) {
|
|
473
|
+
mountPrometheusMiddleware(router);
|
|
474
|
+
}
|
|
475
|
+
if (options.rateLimit) {
|
|
476
|
+
mountRateLimiterMiddleware(router);
|
|
477
|
+
}
|
|
478
|
+
if (options.swagger) {
|
|
479
|
+
mountSwaggerMiddleware(router, boolableToObject(options.swagger));
|
|
480
|
+
}
|
|
481
|
+
if (options.decorators) {
|
|
482
|
+
mountDecoratorsMiddleware(router, options.decorators);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
async function generateSwagger(options) {
|
|
487
|
+
const cwd = options.cwd || process.cwd();
|
|
488
|
+
const packageJson = await load(path.join(cwd, 'package.json'));
|
|
489
|
+
const securityDefinitions = {
|
|
490
|
+
bearer: {
|
|
491
|
+
name: 'Bearer',
|
|
492
|
+
type: 'apiKey',
|
|
493
|
+
in: 'header'
|
|
494
|
+
},
|
|
495
|
+
basicAuth: {
|
|
496
|
+
type: 'http',
|
|
497
|
+
schema: 'basic'
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
if (options.authupURL) {
|
|
501
|
+
securityDefinitions.oauth2 = {
|
|
502
|
+
type: 'oauth2',
|
|
503
|
+
flows: {
|
|
504
|
+
password: {
|
|
505
|
+
tokenUrl: new URL('token', options.authupURL).href
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
return generate({
|
|
511
|
+
version: Version.V2,
|
|
512
|
+
options: {
|
|
513
|
+
metadata: {
|
|
514
|
+
cache: false,
|
|
515
|
+
entryPoint: [
|
|
516
|
+
{
|
|
517
|
+
pattern: '**/*.ts',
|
|
518
|
+
cwd: options.controllerBasePath
|
|
519
|
+
}
|
|
520
|
+
],
|
|
521
|
+
ignore: [
|
|
522
|
+
'**/node_modules/**'
|
|
523
|
+
],
|
|
524
|
+
allow: [
|
|
525
|
+
'**/@authup/**'
|
|
526
|
+
]
|
|
527
|
+
},
|
|
528
|
+
yaml: false,
|
|
529
|
+
servers: [
|
|
530
|
+
options.baseURL
|
|
531
|
+
],
|
|
532
|
+
name: 'API Documentation',
|
|
533
|
+
description: 'Explore the REST Endpoints.',
|
|
534
|
+
version: packageJson.version,
|
|
535
|
+
outputDirectory: path.join(cwd, 'writable'),
|
|
536
|
+
securityDefinitions,
|
|
537
|
+
consumes: [
|
|
538
|
+
'application/json'
|
|
539
|
+
],
|
|
540
|
+
produces: [
|
|
541
|
+
'application/json'
|
|
542
|
+
]
|
|
543
|
+
}
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
export { ForceLoggedInMiddleware, HTTPHandlerOperation, RequestPermissionChecker, generateSwagger, isRequestIdentityMasterRealmMember, mountAuthupMiddleware, mountBasicMiddleware, mountCorsMiddleware, mountDecoratorsMiddleware, mountErrorMiddleware, mountMiddlewares, mountPrometheusMiddleware, mountRateLimiterMiddleware, mountSwaggerMiddleware, setRequestEnv, setRequestIdentity, setRequestPermissionChecker, useRequestEnv, useRequestIdentity, useRequestIdentityOrFail, useRequestIdentityRealm, useRequestPermissionChecker };
|
|
548
|
+
//# sourceMappingURL=index.mjs.map
|