@blazedpath/commons 0.0.4

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 (224) hide show
  1. package/README.md +3 -0
  2. package/blz-base/health/index.js +215 -0
  3. package/blz-base/index.js +1466 -0
  4. package/blz-cache/LruCache.js +44 -0
  5. package/blz-cache/index.js +29 -0
  6. package/blz-config/index.js +434 -0
  7. package/blz-core/index.js +364 -0
  8. package/blz-cryptography/index.js +54 -0
  9. package/blz-datetimes/index.js +356 -0
  10. package/blz-file/example.dat +2545 -0
  11. package/blz-file/fileService.js +205 -0
  12. package/blz-file/index.js +94 -0
  13. package/blz-file/index.test.js +31 -0
  14. package/blz-file/lab.js +33 -0
  15. package/blz-hazelcast/index.js +189 -0
  16. package/blz-hazelcast/lib/credentials.js +25 -0
  17. package/blz-hazelcast/lib/credentialsFactory.js +12 -0
  18. package/blz-hazelcast/lib/hazelcastCache.js +234 -0
  19. package/blz-iterable/index.js +446 -0
  20. package/blz-json-schema/index.js +11 -0
  21. package/blz-jwt/index.js +121 -0
  22. package/blz-kafka/index.js +522 -0
  23. package/blz-math/index.js +131 -0
  24. package/blz-mongodb/index.js +326 -0
  25. package/blz-rds/__test__/scape.test.js +58 -0
  26. package/blz-rds/blz-rds-executor.js +578 -0
  27. package/blz-rds/blz-rds-helper.js +310 -0
  28. package/blz-rds/commands/core/add.js +13 -0
  29. package/blz-rds/commands/core/and.js +18 -0
  30. package/blz-rds/commands/core/asc.js +10 -0
  31. package/blz-rds/commands/core/avg.js +10 -0
  32. package/blz-rds/commands/core/column-ref.js +8 -0
  33. package/blz-rds/commands/core/count-distinct.js +10 -0
  34. package/blz-rds/commands/core/count.js +10 -0
  35. package/blz-rds/commands/core/decimal.js +8 -0
  36. package/blz-rds/commands/core/desc.js +10 -0
  37. package/blz-rds/commands/core/distinct.js +10 -0
  38. package/blz-rds/commands/core/divide.js +11 -0
  39. package/blz-rds/commands/core/embedded-exists.js +17 -0
  40. package/blz-rds/commands/core/embedded-select.js +17 -0
  41. package/blz-rds/commands/core/equals.js +9 -0
  42. package/blz-rds/commands/core/false.js +8 -0
  43. package/blz-rds/commands/core/greater-or-equal.js +9 -0
  44. package/blz-rds/commands/core/greater.js +9 -0
  45. package/blz-rds/commands/core/in.js +9 -0
  46. package/blz-rds/commands/core/integer.js +8 -0
  47. package/blz-rds/commands/core/is-not-null.js +11 -0
  48. package/blz-rds/commands/core/is-null-or-value.js +10 -0
  49. package/blz-rds/commands/core/is-null.js +11 -0
  50. package/blz-rds/commands/core/less-or-equal.js +9 -0
  51. package/blz-rds/commands/core/less-unary.js +12 -0
  52. package/blz-rds/commands/core/less.js +9 -0
  53. package/blz-rds/commands/core/like.js +12 -0
  54. package/blz-rds/commands/core/max.js +10 -0
  55. package/blz-rds/commands/core/min.js +10 -0
  56. package/blz-rds/commands/core/multiply.js +13 -0
  57. package/blz-rds/commands/core/not-equals.js +9 -0
  58. package/blz-rds/commands/core/not-in.js +9 -0
  59. package/blz-rds/commands/core/not.js +13 -0
  60. package/blz-rds/commands/core/null.js +8 -0
  61. package/blz-rds/commands/core/nvl.js +11 -0
  62. package/blz-rds/commands/core/or.js +13 -0
  63. package/blz-rds/commands/core/parameter.js +34 -0
  64. package/blz-rds/commands/core/remainder.js +16 -0
  65. package/blz-rds/commands/core/string.js +8 -0
  66. package/blz-rds/commands/core/subtract.js +13 -0
  67. package/blz-rds/commands/core/sum.js +10 -0
  68. package/blz-rds/commands/core/true.js +8 -0
  69. package/blz-rds/commands/core/tuple.js +13 -0
  70. package/blz-rds/commands/datetimes/add-days.js +11 -0
  71. package/blz-rds/commands/datetimes/add-hours.js +11 -0
  72. package/blz-rds/commands/datetimes/add-milliseconds.js +11 -0
  73. package/blz-rds/commands/datetimes/add-minutes.js +11 -0
  74. package/blz-rds/commands/datetimes/add-months.js +11 -0
  75. package/blz-rds/commands/datetimes/add-seconds.js +11 -0
  76. package/blz-rds/commands/datetimes/add-years.js +11 -0
  77. package/blz-rds/commands/datetimes/date-diff.js +11 -0
  78. package/blz-rds/commands/datetimes/date.js +12 -0
  79. package/blz-rds/commands/datetimes/datetime-diff.js +11 -0
  80. package/blz-rds/commands/datetimes/datetime.js +15 -0
  81. package/blz-rds/commands/datetimes/day.js +10 -0
  82. package/blz-rds/commands/datetimes/hour.js +10 -0
  83. package/blz-rds/commands/datetimes/millisecond.js +10 -0
  84. package/blz-rds/commands/datetimes/minute.js +10 -0
  85. package/blz-rds/commands/datetimes/month-text.js +10 -0
  86. package/blz-rds/commands/datetimes/month.js +10 -0
  87. package/blz-rds/commands/datetimes/now.js +9 -0
  88. package/blz-rds/commands/datetimes/second.js +10 -0
  89. package/blz-rds/commands/datetimes/subtract-days.js +11 -0
  90. package/blz-rds/commands/datetimes/subtract-hours.js +11 -0
  91. package/blz-rds/commands/datetimes/subtract-milliseconds.js +11 -0
  92. package/blz-rds/commands/datetimes/subtract-minutes.js +11 -0
  93. package/blz-rds/commands/datetimes/subtract-seconds.js +11 -0
  94. package/blz-rds/commands/datetimes/time-diff.js +11 -0
  95. package/blz-rds/commands/datetimes/time.js +13 -0
  96. package/blz-rds/commands/datetimes/today.js +9 -0
  97. package/blz-rds/commands/datetimes/week-day-text.js +10 -0
  98. package/blz-rds/commands/datetimes/week-day.js +10 -0
  99. package/blz-rds/commands/datetimes/week.js +10 -0
  100. package/blz-rds/commands/datetimes/year.js +10 -0
  101. package/blz-rds/commands/math/abs.js +10 -0
  102. package/blz-rds/commands/math/acos.js +10 -0
  103. package/blz-rds/commands/math/asin.js +10 -0
  104. package/blz-rds/commands/math/atan.js +10 -0
  105. package/blz-rds/commands/math/atan2.js +11 -0
  106. package/blz-rds/commands/math/ceil.js +10 -0
  107. package/blz-rds/commands/math/cos.js +10 -0
  108. package/blz-rds/commands/math/cosh.js +10 -0
  109. package/blz-rds/commands/math/exp.js +10 -0
  110. package/blz-rds/commands/math/floor.js +10 -0
  111. package/blz-rds/commands/math/log.js +18 -0
  112. package/blz-rds/commands/math/log10.js +10 -0
  113. package/blz-rds/commands/math/pow.js +11 -0
  114. package/blz-rds/commands/math/random.js +9 -0
  115. package/blz-rds/commands/math/round.js +18 -0
  116. package/blz-rds/commands/math/sign.js +10 -0
  117. package/blz-rds/commands/math/sin.js +10 -0
  118. package/blz-rds/commands/math/sinh.js +10 -0
  119. package/blz-rds/commands/math/sqrt.js +10 -0
  120. package/blz-rds/commands/math/tan.js +10 -0
  121. package/blz-rds/commands/math/tanh.js +10 -0
  122. package/blz-rds/commands/math/trunc.js +18 -0
  123. package/blz-rds/commands/strings/concat.js +20 -0
  124. package/blz-rds/commands/strings/contains.js +12 -0
  125. package/blz-rds/commands/strings/ends-with.js +12 -0
  126. package/blz-rds/commands/strings/index-of.js +11 -0
  127. package/blz-rds/commands/strings/is-null-or-empty.js +11 -0
  128. package/blz-rds/commands/strings/is-null-or-white-space.js +11 -0
  129. package/blz-rds/commands/strings/join.js +22 -0
  130. package/blz-rds/commands/strings/last-index-of.js +11 -0
  131. package/blz-rds/commands/strings/length.js +10 -0
  132. package/blz-rds/commands/strings/pad-left.js +20 -0
  133. package/blz-rds/commands/strings/pad-right.js +20 -0
  134. package/blz-rds/commands/strings/replace.js +12 -0
  135. package/blz-rds/commands/strings/starts-with.js +12 -0
  136. package/blz-rds/commands/strings/substring.js +12 -0
  137. package/blz-rds/commands/strings/to-lower.js +10 -0
  138. package/blz-rds/commands/strings/to-upper.js +10 -0
  139. package/blz-rds/commands/strings/trim-end.js +10 -0
  140. package/blz-rds/commands/strings/trim-start.js +10 -0
  141. package/blz-rds/commands/strings/trim.js +10 -0
  142. package/blz-rds/index.js +744 -0
  143. package/blz-rds-mysql/base.js +857 -0
  144. package/blz-rds-mysql/connection-manager.js +129 -0
  145. package/blz-rds-mysql/execute-bulk-insert.js +35 -0
  146. package/blz-rds-mysql/execute-bulk-merge.js +45 -0
  147. package/blz-rds-mysql/execute-non-query.js +34 -0
  148. package/blz-rds-mysql/execute-query.js +50 -0
  149. package/blz-rds-mysql/index.js +41 -0
  150. package/blz-rds-mysql/stored-procedure.js +207 -0
  151. package/blz-rds-mysql/syntaxis.json +114 -0
  152. package/blz-rds-mysqlx/base.js +846 -0
  153. package/blz-rds-mysqlx/connection-manager.js +141 -0
  154. package/blz-rds-mysqlx/execute-bulk-insert.js +35 -0
  155. package/blz-rds-mysqlx/execute-bulk-merge.js +45 -0
  156. package/blz-rds-mysqlx/execute-non-query.js +29 -0
  157. package/blz-rds-mysqlx/execute-query.js +39 -0
  158. package/blz-rds-mysqlx/index.js +41 -0
  159. package/blz-rds-mysqlx/stored-procedure.js +179 -0
  160. package/blz-rds-mysqlx/syntaxis.json +105 -0
  161. package/blz-rds-oracle/index.js +540 -0
  162. package/blz-rds-oracle/syntaxis.json +112 -0
  163. package/blz-rds-postgres/base.js +861 -0
  164. package/blz-rds-postgres/connection-manager.js +225 -0
  165. package/blz-rds-postgres/execute-bulk-insert.js +81 -0
  166. package/blz-rds-postgres/execute-bulk-merge.js +93 -0
  167. package/blz-rds-postgres/execute-non-query.js +23 -0
  168. package/blz-rds-postgres/execute-query.js +37 -0
  169. package/blz-rds-postgres/index.js +41 -0
  170. package/blz-rds-postgres/result-set.js +51 -0
  171. package/blz-rds-postgres/stored-procedure.js +116 -0
  172. package/blz-rds-postgres/syntaxis.json +114 -0
  173. package/blz-redis/index.js +217 -0
  174. package/blz-redis/lib/redisCache.js +265 -0
  175. package/blz-regex/index.js +25 -0
  176. package/blz-security/.eslintrc.js +15 -0
  177. package/blz-security/__test__/AuthorizationKpn.yaml +1043 -0
  178. package/blz-security/__test__/FinancingSetting.yaml +177 -0
  179. package/blz-security/__test__/KpnConfigPortal.yaml +330 -0
  180. package/blz-security/__test__/OrderManagement.yaml +5190 -0
  181. package/blz-security/__test__/Security.yaml +128 -0
  182. package/blz-security/__test__/autorization.test.js +105 -0
  183. package/blz-security/__test__/orderManagement.test.js +26 -0
  184. package/blz-security/__test__/secureUrl.test.js +79 -0
  185. package/blz-security/__test__/solveMergeRule.test.js +109 -0
  186. package/blz-security/__test__/sqlInjectionGuard.test.js +203 -0
  187. package/blz-security/__test__/xssGuard.test.js +204 -0
  188. package/blz-security/authorizationService.js +536 -0
  189. package/blz-security/config/global.js +8 -0
  190. package/blz-security/config/welcome +8 -0
  191. package/blz-security/doc/README.md +75 -0
  192. package/blz-security/filescanner/index.js +46 -0
  193. package/blz-security/helpers/consts.js +229 -0
  194. package/blz-security/helpers/utils.js +267 -0
  195. package/blz-security/implementations/cache.js +90 -0
  196. package/blz-security/implementations/oidc.js +404 -0
  197. package/blz-security/implementations/pkceCacheStore.js +23 -0
  198. package/blz-security/implementations/saml.js +10 -0
  199. package/blz-security/implementations/uma.js +63 -0
  200. package/blz-security/implementations/webAuthn.js +9 -0
  201. package/blz-security/implementations/wstg.js +72 -0
  202. package/blz-security/index.js +77 -0
  203. package/blz-security/lab/index.js +27 -0
  204. package/blz-security/middleware/HapiServerAzureAd.js +641 -0
  205. package/blz-security/middleware/HapiServerKeycloak.js +840 -0
  206. package/blz-security/middleware/HapiServerSimToken.js +247 -0
  207. package/blz-security/middleware/hapi.js +515 -0
  208. package/blz-security/middleware/hapiServer.js +974 -0
  209. package/blz-security/navigationMemoryRepository.js +15 -0
  210. package/blz-security/navigationMongoDbRepository.js +73 -0
  211. package/blz-security/secureUrlService.js +47 -0
  212. package/blz-security/securityService.js +409 -0
  213. package/blz-security/sqlInjectionGuard.js +162 -0
  214. package/blz-security/templates/forbidden.html +0 -0
  215. package/blz-security/templates/session-iframe-azure-ad.html +7 -0
  216. package/blz-security/templates/session-iframe.html +73 -0
  217. package/blz-security/templates/unauthorized.html +1 -0
  218. package/blz-security/xssGuard.js +87 -0
  219. package/blz-strings/index.js +167 -0
  220. package/blz-uuid/index.js +7 -0
  221. package/blz-yaml/index.js +19 -0
  222. package/index.js +84 -0
  223. package/package.json +97 -0
  224. package/process-managers/index.js +422 -0
@@ -0,0 +1,515 @@
1
+ /**
2
+ * @author Blazedpath Team
3
+ * @implements Protecting all resources through hapi middleware
4
+ * @description Hapi.js (derived from Http-API) is an open-source Node.js
5
+ * framework used to build powerful and scalable web applications.
6
+ * @see https://hapi.dev/api/
7
+ */
8
+
9
+ const Uma = require('../implementations/uma')
10
+ const Jsonwebtoken = require('jsonwebtoken') // Implementations of JSON Web Tokens.
11
+ const {
12
+ Exception,
13
+ getFullUrl,
14
+ getHost,
15
+ getPathname,
16
+ getTemplate,
17
+ getTokenTolerance,
18
+ trace,
19
+ errorResponse
20
+ } = require('../helpers/utils')
21
+
22
+ let contextConfig = {}
23
+ let securityService = null
24
+
25
+ class Hapi {
26
+ constructor (oidc, cookiesName) {
27
+ this.oidc = oidc
28
+ this.COOKIE_NAMES = cookiesName
29
+ this.activateTraceApiMethod = false
30
+ this.queryStringLimit = null;
31
+ this.securityLoginTokenExpToleranceSeconds = 3600 * 5; // Default 5 hours
32
+ }
33
+
34
+ async connect (_securityService, context, config) {
35
+ contextConfig = config
36
+ securityService = _securityService
37
+ const { authServer, accessTokenSimulation, activateTraceApiMethod } = config
38
+ if (activateTraceApiMethod) {
39
+ this.activateTraceApiMethod = activateTraceApiMethod
40
+ }
41
+ let oidcConfiguration = {}
42
+ const stateOption = {
43
+ clearInvalid: true,
44
+ encoding: 'base64',
45
+ isSecure: true,
46
+ isHttpOnly: true,
47
+ isSameSite: 'Lax',
48
+ path: '/',
49
+ strictHeader: true
50
+ }
51
+ if (accessTokenSimulation && !authServer) {
52
+ context.config = config
53
+ context.state(this.COOKIE_NAMES.ACCESS_TOKEN, stateOption)
54
+ this.authServerSimulation(context)
55
+ } else {
56
+ try {
57
+ if (authServer.sessionCookiesDomain) {
58
+ stateOption.domain = authServer.sessionCookiesDomain
59
+ }
60
+ const isHttpOnlyForSessionState = authServer.isHttpOnlyForSessionState !== undefined ? authServer.isHttpOnlyForSessionState : false
61
+ context.state(this.COOKIE_NAMES.SID, stateOption)
62
+ stateOption.encoding = 'none'
63
+ stateOption.strictHeader = false
64
+ stateOption.isHttpOnly = isHttpOnlyForSessionState
65
+ context.state(this.COOKIE_NAMES.SESSION_STATE, stateOption)
66
+ oidcConfiguration = await this.configuration(authServer)
67
+ if (!authServer.scope || !authServer.scope.split(' ').some((reg) => reg === 'openid')) {
68
+ authServer.scope = `openid ${authServer.scope || ''}`
69
+ }
70
+ if (authServer.tokenEndpoint && !authServer.tokenEndpoint.match(/https.*/)) {
71
+ context.states.cookies[this.COOKIE_NAMES.SID].isSecure = false
72
+ context.states.cookies[this.COOKIE_NAMES.SESSION_STATE].isSecure = false
73
+ }
74
+ trace('INFO', 'The following configuration was initialized')
75
+ const securityConfiguration = Object.fromEntries(Object.entries(authServer).filter((entry) => !['clientSecret', 'PrivateKey', 'PublicKey'].includes(entry[0])))
76
+ trace('INFO', oidcConfiguration.tokenEndpoint ? oidcConfiguration : securityConfiguration)
77
+ } catch (err) {
78
+ trace('ERROR', `Exception ${err.message}`)
79
+ trace('ERROR', err.stack)
80
+ }
81
+ context.ext('onPreHandler', async (request, h) => {
82
+ const unprotectedPaths = [/\/health/, /\/metrics/]
83
+ const unprotectedExtensions = ['.ico', '.jpg', '.jpeg', '.gif', '.png', '.pdf', '.svg', '.html', '.htm', '.css', '.js', '.js.map', '.json', '.woff', '.woff2']
84
+ const requestUrl = getFullUrl(request)
85
+ if(this.activateTraceApiMethod){
86
+ if(requestUrl.includes('\/api\/')){
87
+ console.log(requestUrl + ' - ' + request.method.toUpperCase());
88
+ }
89
+ }
90
+ try {
91
+ const { session_state: qrSessionState, code } = request.query
92
+ const ckSessionState = request.state[this.COOKIE_NAMES.SESSION_STATE]
93
+ const sid = request.state[this.COOKIE_NAMES.SID]
94
+ const tokenSet = await this.oidc.tokenSet()
95
+ const uma = await Uma.permission()
96
+ const href = h.request.url.href || requestUrl
97
+
98
+ // Check for malicios query string parameters
99
+ if (this.queryStringLimit) {
100
+ const { limit } = request.query; // Access the query parameter "limit"
101
+ // Check if the limit is greater than the configured
102
+ if (limit && parseInt(limit, 10) > this.queryStringLimit) {
103
+ const error = new Error('Bad Request.');
104
+ error.name = 'BadRequest';
105
+ error.code = 400;
106
+ throw error;
107
+ }
108
+ }
109
+ if (unprotectedPaths.some((reg) => reg.test(request.path)) || unprotectedExtensions.some((ext) => requestUrl.endsWith(ext))) {
110
+ return h.continue
111
+ }
112
+ if (getHost(request).includes('0.0.0.0') && context.states.cookies[this.COOKIE_NAMES.SID].isSecure) {
113
+ trace('WARN', `Accessing ${getHost(request)} doesn't ensure a secure context for writing cookies.`)
114
+ context.states.cookies[this.COOKIE_NAMES.SID].isSecure = false
115
+ context.states.cookies[this.COOKIE_NAMES.SESSION_STATE].isSecure = false
116
+ }
117
+ trace('INFO', `Navigating to ${requestUrl}`)
118
+ if (!request.state) {
119
+ throw new Exception('Error when getting cookies', 'CookiesError', 404)
120
+ } else if (code && ckSessionState && qrSessionState && qrSessionState !== ckSessionState) {
121
+ trace('ERROR', `The Session cookie ${ckSessionState} doesn't match with the query session ${qrSessionState}`)
122
+ return h
123
+ .response()
124
+ .unstate(this.COOKIE_NAMES.SID)
125
+ .unstate(this.COOKIE_NAMES.SESSION_STATE)
126
+ .redirect(requestUrl)
127
+ .takeover()
128
+ } else if (ckSessionState && sid) {
129
+ // pasa por aca si sid=falsy
130
+ const tokens = await tokenSet.tokens(ckSessionState)
131
+ if (authServer.umaUri) {
132
+ let badUmaUri = false
133
+ const hrefParts = href.split('/')
134
+ if (hrefParts.length > 0) {
135
+ const lastHrefPart = hrefParts[hrefParts.length - 1]
136
+ badUmaUri = lastHrefPart.indexOf('.') !== -1
137
+ }
138
+ if (!badUmaUri) {
139
+ tokens.access_token = await uma.ticket({ tokenUrl: authServer.tokenEndpoint, token: tokens.access_token, audience: authServer.clientId })
140
+ trace('INFO', 'Generating uma ticket:')
141
+ }
142
+ }
143
+ if (this.validSid(sid)) {
144
+ return h.continue
145
+ }
146
+ else {
147
+ // valid Sid checks for invalid, or expired values.
148
+ const error = new Error('Invalid sid.');
149
+ error.name = 'ExpiredSid';
150
+ error.code = 401;
151
+ throw error;
152
+ }
153
+ } else if (code && sid) {
154
+ trace('INFO', 'Generating token:')
155
+ const tokensSet = await tokenSet.generate({ code, scope: authServer.scope, redirectUri: this.getRedirectUri(request), sid })
156
+ if (!tokensSet) {
157
+ return await this.authenticate(h, authServer.scope)
158
+ }
159
+ trace('INFO', `Set token for session_state:${tokensSet.session_state}`)
160
+ // trace('INFO', tokensSet)
161
+ return h
162
+ .response()
163
+ .state(this.COOKIE_NAMES.SID, sid)
164
+ .state(this.COOKIE_NAMES.SESSION_STATE, tokensSet.session_state)
165
+ .redirect(requestUrl)
166
+ .takeover()
167
+ } else if ((!sid && ckSessionState) || (!ckSessionState && sid)) {
168
+ const error = new Error('Token is Invalid.');
169
+ error.name = 'TokenInvalid';
170
+ error.code = 401;
171
+ throw error;
172
+ } else {
173
+ return await this.authenticate(h, authServer.scope)
174
+ }
175
+ } catch (err) {
176
+ let { code, name, message } = err
177
+ trace('ERROR', `${name}:${message}`)
178
+ code = parseInt(code) || (err.response ? err.response.statusCode : 500)
179
+ const errorList = ['pkce', 'code', 'jwt']
180
+ if (errorList.some((error) => message.includes(error)) && code !== 403) {
181
+ trace('ERROR', `Forbidden ${message}`)
182
+ return h
183
+ .response()
184
+ .unstate(this.COOKIE_NAMES.SID)
185
+ .unstate(this.COOKIE_NAMES.SESSION_STATE)
186
+ .redirect(requestUrl)
187
+ .takeover()
188
+ }
189
+ if (code === 403 || code === 401) {
190
+ if (name === 'ExpirationError' || name === 'TokenInvalid' || (name === 'TokenError' && getPathname(request) === '/')) {
191
+ return h
192
+ .response()
193
+ .unstate(this.COOKIE_NAMES.SID)
194
+ .unstate(this.COOKIE_NAMES.SESSION_STATE)
195
+ .redirect('/logout')
196
+ .takeover()
197
+ } else if (name === 'ExpiredSid') {
198
+ return h
199
+ .response()
200
+ .unstate(this.COOKIE_NAMES.SID)
201
+ .unstate(this.COOKIE_NAMES.SESSION_STATE)
202
+ .code(401)
203
+ .redirect('/logout')
204
+ .takeover()
205
+ } else {
206
+ return h
207
+ .response()
208
+ .code(401)
209
+ .unstate(this.COOKIE_NAMES.SID)
210
+ .unstate(this.COOKIE_NAMES.SESSION_STATE)
211
+ .takeover()
212
+ }
213
+ }
214
+ return h
215
+ .response({ name, message })
216
+ .code(code || 500)
217
+ .unstate(this.COOKIE_NAMES.SID)
218
+ .unstate(this.COOKIE_NAMES.SESSION_STATE)
219
+ .takeover()
220
+ }
221
+ })
222
+ const me = this
223
+ context.route({
224
+ method: 'GET',
225
+ path: '/get-authorization',
226
+ handler: async (request, h) => {
227
+ try {
228
+ const { session_state: ckSessionState } = request.state
229
+ if (!ckSessionState) {
230
+ throw new Exception("old Hapi get-authorization: Session cookie doesn't exist.", 'CookiesError', 404)
231
+ }
232
+ const tokenSet = await me.oidc.tokenSet()
233
+ const tokens = await tokenSet.tokens(ckSessionState)
234
+ const uma = await Uma.permission()
235
+ const token = await uma.ticket({ tokenUrl: authServer.tokenEndpoint || authServer.tokenUrl, token: tokens.access_token, audience: authServer.clientId })
236
+ const sourceData = Jsonwebtoken.decode(token.access_token)
237
+ return h.response(JSON.stringify(sourceData.authorization)).takeover()
238
+ } catch (err) {
239
+ return errorResponse(h, err, 401)
240
+ }
241
+ }
242
+ })
243
+
244
+ context.route({
245
+ method: 'GET',
246
+ path: '/get-security-rules',
247
+ handler: async (request, h) => {
248
+ try {
249
+ const securityRules = await securityService.getFrontendSecurityRules(request)
250
+ return h.response(JSON.stringify(securityRules)).takeover()
251
+ } catch (err) {
252
+ return errorResponse(h, err, 401)
253
+ }
254
+ }
255
+ })
256
+
257
+ context.route({
258
+ method: 'GET',
259
+ path: '/get-permissions',
260
+ handler: async (request, h) => {
261
+ try {
262
+ const permissions = await securityService.getPermissions()
263
+ return h.response(JSON.stringify(permissions)).takeover()
264
+ } catch (err) {
265
+ return errorResponse(h, err, 401)
266
+ }
267
+ }
268
+ })
269
+
270
+ context.route({
271
+ method: 'GET',
272
+ path: '/get-user-info',
273
+ handler: async (request, h) => {
274
+ try {
275
+ const userInfo = await securityService.getUserInfo(request)
276
+ return h
277
+ .response(JSON.stringify(userInfo))
278
+ .takeover()
279
+ } catch (err) {
280
+ return errorResponse(h, err, 500)
281
+ }
282
+ }
283
+ })
284
+ context.route({
285
+ path: '/logout',
286
+ method: 'GET',
287
+ handler: async (request, h) => {
288
+ try {
289
+ const ckSessionState = request.state[this.COOKIE_NAMES.SESSION_STATE]
290
+ return h
291
+ .response()
292
+ .unstate(this.COOKIE_NAMES.SID)
293
+ .unstate(this.COOKIE_NAMES.SESSION_STATE)
294
+ .redirect(await me.oidc.endSessionUrl({
295
+ sessionState: ckSessionState,
296
+ redirectUri: this.getRedirectUri(request)
297
+ }))
298
+ .takeover()
299
+ } catch (err) {
300
+ return errorResponse(h, err, 500)
301
+ }
302
+ }
303
+ })
304
+ context.route({
305
+ path: '/invalid-session',
306
+ method: 'GET',
307
+ handler: async (request, h) => {
308
+ try {
309
+ const endSessionUrl = await me.oidc.endSessionUrl({
310
+ redirectUri: this.getRedirectUri(request),
311
+ sessionState: request.state[this.COOKIE_NAMES.SESSION_STATE]
312
+ })
313
+ return h
314
+ .response()
315
+ .unstate(this.COOKIE_NAMES.SID)
316
+ .unstate(this.COOKIE_NAMES.SESSION_STATE)
317
+ .redirect(endSessionUrl)
318
+ .takeover()
319
+ } catch (err) {
320
+ return errorResponse(h, err, 500)
321
+ }
322
+ }
323
+ })
324
+
325
+ context.route({
326
+ path: '/check-session-iframe.html',
327
+ method: 'GET',
328
+ handler: async (_request, h) => {
329
+ try {
330
+ let content = '<html/>'
331
+ if (authServer && authServer.checkSessionIframe) {
332
+ const { checkSessionIframe: sessionIframeUrl, clientId, sessionCookiesPrefix } = authServer
333
+ if (sessionIframeUrl && sessionIframeUrl.includes('https://')) {
334
+ trace('INFO', `Session management url: ${sessionIframeUrl}`)
335
+ content = getTemplate('session-iframe', {
336
+ sessionIframeUrl,
337
+ clientId,
338
+ sessionCookiesPrefix: sessionCookiesPrefix || ''
339
+ })
340
+ } else {
341
+ trace('WARN', 'For session management, it is necessary to get the value from a cookie called session_state, and as a good practice, it should have reached a secure context [TLS].')
342
+ }
343
+ }
344
+ return h
345
+ .response(content)
346
+ .header('Content-Type', 'text/html')
347
+ } catch (err) {
348
+ return errorResponse(h, err, 500)
349
+ }
350
+ }
351
+ })
352
+ }
353
+ }
354
+ validSid(sid){
355
+ let decodedSid = Jsonwebtoken.decode(sid);
356
+ if (!decodedSid) {
357
+ return false;
358
+ }
359
+ // checks for expiration against current time, with 5' tolerance
360
+ if (decodedSid.exp)
361
+ return (decodedSid.exp + this.securityLoginTokenExpToleranceSeconds > (Date.now() / 1000))
362
+ else
363
+ return false;
364
+ }
365
+
366
+ authServerSimulation (context) {
367
+ if (!context.config || !context.config.accessTokenSimulation) {
368
+ throw new Exception('Error parsing metadata for simulation', 'ConfigurationError', 404)
369
+ }
370
+ let { algorithm, payload, secret } = context.config.accessTokenSimulation
371
+ const me = this
372
+ context.ext('onPreAuth', async function (request, h) {
373
+ if (request.state && request.state[me.COOKIE_NAMES.ACCESS_TOKEN]) {
374
+ return h.continue
375
+ } else {
376
+ switch (algorithm) {
377
+ case 'HMAC-SHA384': {
378
+ algorithm = 'HS384'
379
+ break
380
+ }
381
+ case 'HMAC-SHA512': {
382
+ algorithm = 'HS512'
383
+ break
384
+ }
385
+ default: {
386
+ algorithm = 'HS256'
387
+ }
388
+ }
389
+ const jwt = me.oidc.jwt().sign({ payload, secret, algorithm })
390
+ return h
391
+ .response()
392
+ .state(me.COOKIE_NAMES.ACCESS_TOKEN, jwt)
393
+ .redirect(me.getRedirectUri(request))
394
+ .takeover()
395
+ }
396
+ })
397
+ context.route({
398
+ path: '/get-authorization',
399
+ method: 'GET',
400
+ handler: async function (_request, h) {
401
+ return h
402
+ .response('[]')
403
+ .code(200)
404
+ }
405
+ })
406
+ context.route({
407
+ path: '/get-security-rules',
408
+ method: 'GET',
409
+ handler: async function (_request, h) {
410
+ let securityRules = []
411
+ if (securityService && context.config.accessTokenSimulation.playload) {
412
+ const groups = securityService.getGroups(context.config.accessTokenSimulation.playload)
413
+ securityRules = securityService.getFrontendSecurityRules([groups])
414
+ }
415
+ return h
416
+ .response(JSON.stringify(securityRules))
417
+ .code(200)
418
+ }
419
+ })
420
+ context.route({
421
+ path: '/get-permissions',
422
+ method: 'GET',
423
+ handler: async function (_request, h) {
424
+ const permissions = (securityService) ? securityService.getPermissions() : []
425
+ return h
426
+ .response(JSON.stringify(permissions))
427
+ .code(200)
428
+ }
429
+ })
430
+ context.route({
431
+ path: '/get-user-info',
432
+ method: 'GET',
433
+ handler: async function (_request, h) {
434
+ return h
435
+ .response(JSON.stringify(payload))
436
+ .code(200)
437
+ }
438
+ })
439
+ context.route({
440
+ path: '/logout',
441
+ method: 'GET',
442
+ handler: async function (_request, h) {
443
+ return h
444
+ .response()
445
+ .unstate(this.COOKIE_NAMES.ACCESS_TOKEN)
446
+ .takeover()
447
+ }
448
+ })
449
+ }
450
+
451
+ getRedirectUri (request) {
452
+ return contextConfig.authServer.redirectUri || getFullUrl(request)
453
+ }
454
+
455
+ async authenticate (h, scope) {
456
+ const { request } = h
457
+ const pkceCode = await this.oidc.pkceCode()
458
+ const requestUrl = getFullUrl(request)
459
+ let oidcMetadata = await this.oidc.oidcMetadata()
460
+ if (!oidcMetadata || !oidcMetadata.openid_configuration) {
461
+ oidcMetadata = await this.configuration(contextConfig.authServer)
462
+ }
463
+ if (requestUrl.match(new RegExp(/^(https?:\/{2}.*):?(\d*)/.source + getHost(request) + /\/?$/.source))) {
464
+ const authorizationUrl = await this.oidc.authorizationUrl({ scope, redirectUri: this.getRedirectUri(request), pkceCode })
465
+ trace('INFO', `Authenticate redirecting to ${authorizationUrl}`)
466
+ return h
467
+ .response()
468
+ .state(this.COOKIE_NAMES.SID, pkceCode)
469
+ .redirect(authorizationUrl)
470
+ .takeover()
471
+ } else if (getPathname(request) === '/logout') {
472
+ return h.continue
473
+ } else {
474
+ const tokenSet = await this.oidc.tokenSet()
475
+ const { state } = request
476
+ if (tokenSet && state && state[this.COOKIE_NAMES.SESSION_STATE]) {
477
+ const tokens = await tokenSet.tokens(state[this.COOKIE_NAMES.SESSION_STATE])
478
+ if (!tokens || tokens.refresh_expires_in <= getTokenTolerance(0)) {
479
+ throw new Exception('Error when getting token', 'ExpirationError', 403)
480
+ }
481
+ return h.continue
482
+ } else {
483
+ return h
484
+ .response()
485
+ .code(401)
486
+ .takeover()
487
+ }
488
+ }
489
+ }
490
+
491
+ async configuration (authServer) {
492
+ if (!authServer) {
493
+ throw new Exception('Error when getting configuration attributes ')
494
+ }
495
+ const { clientId, clientSecret } = authServer
496
+ await this.oidc.client({ clientId, clientSecret })
497
+ if (authServer.openIdConfigurationEndpoint) {
498
+ return await this.oidc.configuration(authServer.openIdConfigurationEndpoint)
499
+ } else {
500
+ // If configuration uri does not exist but the auth server form has been filled in.
501
+ return await this.oidc.configuration({
502
+ issuer: authServer.issuer,
503
+ authorization_endpoint: authServer.authorizationEndpoint,
504
+ token_endpoint: authServer.tokenEndpoint,
505
+ userinfo_endpoint: authServer.userinfoEndpoint,
506
+ end_session_endpoint: authServer.endSessionEndpoint,
507
+ jwks_uri: authServer.jwksUri
508
+ })
509
+ }
510
+ }
511
+ }
512
+
513
+ module.exports = {
514
+ Hapi
515
+ }