@samanbayaka/core-gtwy 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/CHANGELOG.md +58 -0
- package/index.mjs +207 -0
- package/package.json +32 -0
- package/src/access-token-validator.mjs +249 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# demo
|
|
2
|
+
|
|
3
|
+
## 0.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- chore: pkg sanitize
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @samanbayaka/core@0.0.11
|
|
10
|
+
|
|
11
|
+
## 0.0.2
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- chore: update workspace lockfile
|
|
16
|
+
- Updated dependencies
|
|
17
|
+
- @samanbayaka/core@0.0.11
|
|
18
|
+
|
|
19
|
+
## 0.0.3
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- chore: update workspac
|
|
24
|
+
- Updated dependencies
|
|
25
|
+
- @samanbayaka/core@0.0.11
|
|
26
|
+
|
|
27
|
+
## 0.0.2
|
|
28
|
+
|
|
29
|
+
### Patch Changes
|
|
30
|
+
|
|
31
|
+
- 314257a: new
|
|
32
|
+
- Updated dependencies [314257a]
|
|
33
|
+
- @samanbayaka/core@0.0.11
|
|
34
|
+
|
|
35
|
+
## 0.0.2
|
|
36
|
+
|
|
37
|
+
### Patch Changes
|
|
38
|
+
|
|
39
|
+
- fixed
|
|
40
|
+
- Updated dependencies
|
|
41
|
+
- @samanbayaka/core@0.0.11
|
|
42
|
+
|
|
43
|
+
## 0.1.0
|
|
44
|
+
|
|
45
|
+
### Minor Changes
|
|
46
|
+
|
|
47
|
+
- dfc8940: fixed
|
|
48
|
+
|
|
49
|
+
### Patch Changes
|
|
50
|
+
|
|
51
|
+
- fixed
|
|
52
|
+
- 65fb2ca: fixed
|
|
53
|
+
- b845d66: fixed
|
|
54
|
+
- Updated dependencies
|
|
55
|
+
- Updated dependencies [65fb2ca]
|
|
56
|
+
- Updated dependencies [b845d66]
|
|
57
|
+
- Updated dependencies [dfc8940]
|
|
58
|
+
- @samanbayaka/core@0.1.0
|
package/index.mjs
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import ApiGateway from "moleculer-web"
|
|
2
|
+
import cookieParser from "cookie-parser"
|
|
3
|
+
import bodyParser from "body-parser"
|
|
4
|
+
import helmet from "helmet"
|
|
5
|
+
import compression from "compression"
|
|
6
|
+
|
|
7
|
+
import core from "@samanbayaka/core"
|
|
8
|
+
import * as tokenValidator from './src/access-token-validator.mjs'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Regx pattern to allow cors sutes and cors origins
|
|
12
|
+
* @type {String}
|
|
13
|
+
*/
|
|
14
|
+
const patternTxt = (await core.getConfigs(`/config/sbk/edge/CORS`)) || undefined
|
|
15
|
+
const reqOriginRegex = patternTxt ? new RegExp(patternTxt, "i") : undefined
|
|
16
|
+
|
|
17
|
+
const gtwySchema = {
|
|
18
|
+
name: "gtwy",
|
|
19
|
+
mixins: [
|
|
20
|
+
ApiGateway,
|
|
21
|
+
],
|
|
22
|
+
|
|
23
|
+
settings: {
|
|
24
|
+
port: 3000,
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Middleware mode (for ExpressJS)
|
|
28
|
+
*/
|
|
29
|
+
middleware: false,
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Exposed global path prefix
|
|
33
|
+
*/
|
|
34
|
+
// path: "/sbk",
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Global middlewares. Applied to all routes.
|
|
38
|
+
*/
|
|
39
|
+
use: [
|
|
40
|
+
compression(),
|
|
41
|
+
cookieParser(),
|
|
42
|
+
bodyParser.raw({
|
|
43
|
+
type: [
|
|
44
|
+
"application/octet-stream",
|
|
45
|
+
"multipart/form-data",
|
|
46
|
+
],
|
|
47
|
+
limit: "50mb"
|
|
48
|
+
}),
|
|
49
|
+
helmet(),
|
|
50
|
+
],
|
|
51
|
+
|
|
52
|
+
cors: reqOriginRegex ? {
|
|
53
|
+
origin: (reqOrigin) => {
|
|
54
|
+
if (!reqOrigin) return true
|
|
55
|
+
const { hostname } = new URL(reqOrigin)
|
|
56
|
+
return reqOriginRegex.test(hostname)
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
credentials: true
|
|
60
|
+
} : undefined,
|
|
61
|
+
|
|
62
|
+
routes: [
|
|
63
|
+
// // Public routes
|
|
64
|
+
// {
|
|
65
|
+
// path: "",
|
|
66
|
+
// authorization: false,
|
|
67
|
+
|
|
68
|
+
// onBeforeCall(ctx, route, req, res) {
|
|
69
|
+
// ctx.meta.method = req?.method
|
|
70
|
+
// ctx.meta.headers = req?.headers
|
|
71
|
+
// ctx.meta.cookies = req?.cookies
|
|
72
|
+
// },
|
|
73
|
+
|
|
74
|
+
// whitelist: [
|
|
75
|
+
// "gateway.apiDesc",
|
|
76
|
+
// "gateway.apiVer",
|
|
77
|
+
// /**
|
|
78
|
+
// * Access any actions in 'system' service
|
|
79
|
+
// */
|
|
80
|
+
// /^auth\.(?!listAliases$)\w+(?:\.\w+)*$/
|
|
81
|
+
// ],
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
// aliases: {
|
|
85
|
+
// "GET /sbk/version": "gateway.apiVer",
|
|
86
|
+
// "GET /sbk/description": "gateway.apiDesc",
|
|
87
|
+
// },
|
|
88
|
+
|
|
89
|
+
// autoAliases: true,
|
|
90
|
+
// mergeParams: false,
|
|
91
|
+
// logging: false,
|
|
92
|
+
|
|
93
|
+
// },
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Protected API routes
|
|
97
|
+
*/
|
|
98
|
+
{
|
|
99
|
+
path: "/sbk/api",
|
|
100
|
+
authentication: true,
|
|
101
|
+
authorization: true,
|
|
102
|
+
onBeforeCall(ctx, route, req, res) {
|
|
103
|
+
ctx.meta.method = req?.method
|
|
104
|
+
ctx.meta.headers = req?.headers
|
|
105
|
+
ctx.meta.cookies = req?.cookies
|
|
106
|
+
},
|
|
107
|
+
whitelist: [
|
|
108
|
+
/**
|
|
109
|
+
* Access any actions except 'gateway', 'system', 'oidc', and 'auth' service
|
|
110
|
+
*/
|
|
111
|
+
/^(?!(gateway|system|core.auth|auth|oidc|asset|dbs.pg)\.)\w+(?:\.\w+)*$/
|
|
112
|
+
],
|
|
113
|
+
|
|
114
|
+
autoAliases: true,
|
|
115
|
+
mergeParams: false,
|
|
116
|
+
mappingPolicy: "restrict",
|
|
117
|
+
logging: true,
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Use bodyparser module
|
|
121
|
+
*/
|
|
122
|
+
bodyParsers: {
|
|
123
|
+
json: true,
|
|
124
|
+
urlencoded: { extended: true },
|
|
125
|
+
text: {
|
|
126
|
+
type: [
|
|
127
|
+
"text/plain",
|
|
128
|
+
"application/xml",
|
|
129
|
+
"application/yaml",
|
|
130
|
+
"text/xml",
|
|
131
|
+
]
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
],
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
// /**
|
|
139
|
+
// * Logging request parameters with 'info' level
|
|
140
|
+
// */
|
|
141
|
+
logRequestParams: null,
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
// /**
|
|
145
|
+
// * Logging response data with 'debug' level
|
|
146
|
+
// */
|
|
147
|
+
logResponseData: false,
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Global error handler
|
|
152
|
+
*/
|
|
153
|
+
onError(req, res, err) {
|
|
154
|
+
|
|
155
|
+
core.httpErrorFormatter(req, res, err)
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Custom logging
|
|
159
|
+
*/
|
|
160
|
+
this.logResponse(req, res)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
},
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
// actions: {
|
|
167
|
+
// apiDesc:{
|
|
168
|
+
// openapi: {
|
|
169
|
+
// summary: "API Description",
|
|
170
|
+
// description: "Returns a textual description of the API."
|
|
171
|
+
// },
|
|
172
|
+
// handler: (ctx) => {
|
|
173
|
+
// return ctx.call("system.info.apiDesc")
|
|
174
|
+
// }
|
|
175
|
+
// },
|
|
176
|
+
|
|
177
|
+
// apiVer: {
|
|
178
|
+
// openapi: {
|
|
179
|
+
// summary: "API Version",
|
|
180
|
+
// description: "Returns the current version of the API."
|
|
181
|
+
// },
|
|
182
|
+
// handler: (ctx) => {
|
|
183
|
+
// return ctx.call("system.info.apiVer")
|
|
184
|
+
// },
|
|
185
|
+
// },
|
|
186
|
+
// },
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
methods: {
|
|
190
|
+
/**
|
|
191
|
+
* This overrides the errorHandler method found in the official file
|
|
192
|
+
*/
|
|
193
|
+
errorHandler(req, res, err) {
|
|
194
|
+
// // don't log client side errors unless it's configured
|
|
195
|
+
// if (this.settings.log4XXResponses || (err && !_.inRange(err.code, 400, 500))) {
|
|
196
|
+
// this.logger.error(" Request error!", err.name, ":", err.message, "\n", err.stack, "\nData:", err.data);
|
|
197
|
+
// }
|
|
198
|
+
this.sendError(req, res, err)
|
|
199
|
+
},
|
|
200
|
+
authenticate: tokenValidator.authenticate,
|
|
201
|
+
authorize: tokenValidator.authorize,
|
|
202
|
+
},
|
|
203
|
+
}
|
|
204
|
+
export default {
|
|
205
|
+
...core,
|
|
206
|
+
schema: gtwySchema,
|
|
207
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@samanbayaka/core-gtwy",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "index.mjs",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./index.mjs"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"index.mjs",
|
|
12
|
+
"src/",
|
|
13
|
+
"README.md",
|
|
14
|
+
"CHANGELOG.md"
|
|
15
|
+
],
|
|
16
|
+
"keywords": [],
|
|
17
|
+
"author": "",
|
|
18
|
+
"license": "ISC",
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"body-parser": "^2.3.0",
|
|
21
|
+
"compression": "^1.8.1",
|
|
22
|
+
"cookie-parser": "^1.4.7",
|
|
23
|
+
"helmet": "^8.2.0",
|
|
24
|
+
"jsonwebtoken": "^9.0.3",
|
|
25
|
+
"jwks-rsa": "^4.0.1",
|
|
26
|
+
"moleculer-web": "^0.11.0",
|
|
27
|
+
"@samanbayaka/core": "0.0.10"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { Errors } from "moleculer"
|
|
2
|
+
import ApiGateway from "moleculer-web"
|
|
3
|
+
import jwt from "jsonwebtoken"
|
|
4
|
+
import jwksClient from "jwks-rsa"
|
|
5
|
+
|
|
6
|
+
import core from "@samanbayaka/core"
|
|
7
|
+
|
|
8
|
+
const ACCESS_ROLES = await core.getConfigs('/config/sbk/edge/yaml/roles')
|
|
9
|
+
const OPENID_CONFIG = await core.getConfigs('/config/sbk/edge/yaml/auth')
|
|
10
|
+
export const {clientId} = OPENID_CONFIG
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Initializes OpenID Connect configuration and JWKS client.
|
|
14
|
+
*
|
|
15
|
+
* Fetches the OpenID configuration document from the configured
|
|
16
|
+
* issuer endpoint and creates a cached JWKS client for JWT
|
|
17
|
+
* signature verification.
|
|
18
|
+
*
|
|
19
|
+
* The JWKS client supports:
|
|
20
|
+
* - Automatic key retrieval
|
|
21
|
+
* - In-memory caching
|
|
22
|
+
* - Request rate limiting
|
|
23
|
+
*
|
|
24
|
+
* @async
|
|
25
|
+
* @function getOpenidConfigs
|
|
26
|
+
*
|
|
27
|
+
* @throws {Error} Throws if the OpenID configuration request fails
|
|
28
|
+
* or the response cannot be parsed.
|
|
29
|
+
*
|
|
30
|
+
* @returns {Promise<void>}
|
|
31
|
+
*/
|
|
32
|
+
const getOpenidConfigs = async () => {
|
|
33
|
+
|
|
34
|
+
const response = await fetch(OPENID_CONFIG.url)
|
|
35
|
+
|
|
36
|
+
if ( !response.ok ) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
`OpenID configuration endpoint failed with status "${response.status}"`
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return await response.json()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export const {
|
|
46
|
+
issuer,
|
|
47
|
+
jwks_uri: jwksUri,
|
|
48
|
+
authorization_endpoint: authorizationEndpoint,
|
|
49
|
+
token_endpoint: tokenEndpoint,
|
|
50
|
+
end_session_endpoint: endSessionEndpoint,
|
|
51
|
+
} = await getOpenidConfigs()
|
|
52
|
+
|
|
53
|
+
const client = jwksClient({
|
|
54
|
+
...OPENID_CONFIG.jwksClient,
|
|
55
|
+
jwksUri: jwksUri,
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
const issuers = ((iss) => {
|
|
59
|
+
const httpUrl = new URL(iss)
|
|
60
|
+
httpUrl.protocol = "http:"
|
|
61
|
+
httpUrl.port = String(OPENID_CONFIG.kcPort)
|
|
62
|
+
return [
|
|
63
|
+
iss,
|
|
64
|
+
httpUrl.toString(),
|
|
65
|
+
]
|
|
66
|
+
})(issuer)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Retrieves the public signing key corresponding to a JWT `kid`.
|
|
71
|
+
*
|
|
72
|
+
* Used by JWT verification libraries (such as `jsonwebtoken`)
|
|
73
|
+
* to dynamically resolve signing keys from a JWKS endpoint.
|
|
74
|
+
*
|
|
75
|
+
* @param {Object} header - Decoded JWT header.
|
|
76
|
+
* @param {string} header.kid - Key ID used to identify the signing key.
|
|
77
|
+
* @param {Function} callback - Callback function invoked after key retrieval.
|
|
78
|
+
* @param {Error|null} callback.err - Error object if key retrieval fails.
|
|
79
|
+
* @param {string|null} callback.key - PEM formatted public key.
|
|
80
|
+
*
|
|
81
|
+
* @returns {void}
|
|
82
|
+
*/
|
|
83
|
+
const getKey = (header, callback) => {
|
|
84
|
+
|
|
85
|
+
client.getSigningKey(
|
|
86
|
+
header.kid,
|
|
87
|
+
(err, key) => {
|
|
88
|
+
|
|
89
|
+
if (err) {
|
|
90
|
+
callback(err)
|
|
91
|
+
return
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
callback(
|
|
95
|
+
null,
|
|
96
|
+
key.publicKey || key.rsaPublicKey
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Authenticates the requester by verifying the access token.
|
|
107
|
+
* The token can be provided either in the Bearer Authorization header
|
|
108
|
+
* or in cookies.
|
|
109
|
+
*
|
|
110
|
+
* @param {Context} ctx - Moleculer service context
|
|
111
|
+
* @param {Object} route - REST route configuration object
|
|
112
|
+
* @param {HTTP request<Object>} req - HTTP request object
|
|
113
|
+
* @returns {Promise<Object>} Authenticated user / authorization result
|
|
114
|
+
*/
|
|
115
|
+
export const authenticate = async (ctx, route, req, res) => {
|
|
116
|
+
|
|
117
|
+
let token = null
|
|
118
|
+
|
|
119
|
+
const auth =
|
|
120
|
+
req.headers.authorization
|
|
121
|
+
|
|
122
|
+
if (auth?.startsWith("Bearer ")) {
|
|
123
|
+
token = auth.replace(/^Bearer\s+/i, "")
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
if (
|
|
128
|
+
!token &&
|
|
129
|
+
req.cookies?.WbsedclAccessToken
|
|
130
|
+
) {
|
|
131
|
+
token = req.cookies?.WbsedclAccessToken
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
if (!token) {
|
|
136
|
+
throw new ApiGateway.Errors.UnAuthorizedError(
|
|
137
|
+
ApiGateway.Errors.ERR_NO_TOKEN
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
const decoded =
|
|
143
|
+
await new Promise((resolve, reject) => {
|
|
144
|
+
|
|
145
|
+
jwt.verify(
|
|
146
|
+
token,
|
|
147
|
+
getKey,
|
|
148
|
+
{
|
|
149
|
+
algorithms: OPENID_CONFIG.jwtVerifyAlgo,
|
|
150
|
+
issuers,
|
|
151
|
+
// audience: OPENID_CONFIG.audience,
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
(err, dec) => {
|
|
155
|
+
|
|
156
|
+
if (err) {
|
|
157
|
+
reject(err)
|
|
158
|
+
return
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
resolve(dec)
|
|
162
|
+
}
|
|
163
|
+
)
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
ctx.broker.logger.debug({tag: "SBK", message: "Decoded Token Object", token: decoded, OPENID_CONFIG, issuers})
|
|
167
|
+
// ctx.meta.user = {
|
|
168
|
+
// sessionId: decoded?.sid,
|
|
169
|
+
// id: decoded?.sub,
|
|
170
|
+
// userId: (decoded?.sub).split(":").at(-1),
|
|
171
|
+
// username: decoded?.preferred_username,
|
|
172
|
+
// firstName: decoded?.given_name,
|
|
173
|
+
// lastName: decoded?.family_name,
|
|
174
|
+
// fullName: [...new Set(decoded?.name.split(/\s+/))].join(" "),
|
|
175
|
+
// emailIds: decoded?.email,
|
|
176
|
+
// mobileNos: decoded?.mobile_no,
|
|
177
|
+
// userRoles: decoded?.user_role,
|
|
178
|
+
// }
|
|
179
|
+
return decoded
|
|
180
|
+
|
|
181
|
+
} catch (err) {
|
|
182
|
+
ctx.broker.logger.debug({tag: "SBK", OPENID_CONFIG})
|
|
183
|
+
throw new ApiGateway.Errors.UnAuthorizedError(
|
|
184
|
+
ApiGateway.Errors.ERR_INVALID_TOKEN
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Verifies the user's roles and access grants before authorizing
|
|
191
|
+
* access to the requested resource.
|
|
192
|
+
* @param {object} ctx [description]
|
|
193
|
+
* @param {object} route [description]
|
|
194
|
+
* @param {object} req [description]
|
|
195
|
+
* @param {object} res [description]
|
|
196
|
+
* @return {object} [description]
|
|
197
|
+
*/
|
|
198
|
+
export const authorize = async(ctx, route, req, res) => {
|
|
199
|
+
|
|
200
|
+
ctx.broker.logger.debug({tag: "SBK", message: "User Profile"}, ctx.meta.user, route?.path)
|
|
201
|
+
|
|
202
|
+
if( ctx.meta?.user?.preferred_username === undefined ){
|
|
203
|
+
throw new ApiGateway.Errors.UnAuthorizedError(
|
|
204
|
+
ApiGateway.Errors.ERR_INVALID_TOKEN
|
|
205
|
+
)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
ctx.broker.logger.debug({tag: "SBK", message: "ACCESS_ROLES", ACCESS_ROLES, resource_access: ctx.meta.user.resource_access})
|
|
209
|
+
|
|
210
|
+
// resource_access
|
|
211
|
+
|
|
212
|
+
// const aa = new RegExp("^/system/oidc(?:/.*)?$", "i")
|
|
213
|
+
// if()
|
|
214
|
+
|
|
215
|
+
// if( req.url.startsWith("/system" ){
|
|
216
|
+
|
|
217
|
+
// }
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
// /**
|
|
221
|
+
// * Resticed accessor can't access all resources
|
|
222
|
+
// */
|
|
223
|
+
// if( ctx.meta?.user?.preferred_username == OPENID_CONFIG.rAccessor ){
|
|
224
|
+
// throw new Errors.MoleculerError(
|
|
225
|
+
// "You are not authorized to access this resource",
|
|
226
|
+
// 403,
|
|
227
|
+
// "FORBIDDEN"
|
|
228
|
+
// )
|
|
229
|
+
// }
|
|
230
|
+
|
|
231
|
+
// if( ctx.meta.user?.azp == clientId && req.url.startsWith(OPENID_CONFIG.rRoute)) {
|
|
232
|
+
// throw new Errors.MoleculerError(
|
|
233
|
+
// "You are not authorized to access this resource",
|
|
234
|
+
// 403,
|
|
235
|
+
// "FORBIDDEN"
|
|
236
|
+
// )
|
|
237
|
+
// }
|
|
238
|
+
|
|
239
|
+
// if( ctx.meta.user?.azp == OPENID_CONFIG.rAccessor && !req.url.startsWith(OPENID_CONFIG.rRoute)) {
|
|
240
|
+
// throw new Errors.MoleculerError(
|
|
241
|
+
// "You are not authorized to access this resource",
|
|
242
|
+
// 403,
|
|
243
|
+
// "FORBIDDEN"
|
|
244
|
+
// )
|
|
245
|
+
// }
|
|
246
|
+
|
|
247
|
+
return Promise.resolve(ctx)
|
|
248
|
+
}
|
|
249
|
+
|