@bitblit/ratchet-epsilon-common 4.0.115-alpha → 4.0.119-alpha
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/lib/background/background-dynamo-log-table-handler.d.ts +1 -1
- package/lib/background/background-handler.d.ts +1 -1
- package/lib/background/background-http-adapter-handler.d.ts +1 -1
- package/lib/background/background-validator.d.ts +1 -1
- package/lib/build/ratchet-epsilon-common-info.d.ts +1 -1
- package/lib/built-in/daemon/daemon-authorizer-function.d.ts +1 -1
- package/lib/built-in/daemon/daemon-handler.d.ts +2 -2
- package/lib/built-in/daemon/daemon-process-state-list.d.ts +1 -1
- package/lib/built-in/http/built-in-auth-filters.d.ts +1 -1
- package/lib/cli/ratchet-cli-handler.d.ts +2 -2
- package/lib/config/epsilon-logger-config.d.ts +2 -2
- package/lib/config/http/filter-chain-context.d.ts +1 -1
- package/lib/config/http/http-config.d.ts +1 -1
- package/lib/epsilon-global-handler.d.ts +1 -1
- package/lib/epsilon-instance.d.ts +1 -1
- package/lib/epsilon-logging-extension-processor.d.ts +2 -2
- package/lib/http/auth/auth0-web-token-manipulator.d.ts +1 -1
- package/lib/http/auth/google-web-token-manipulator.d.ts +1 -1
- package/lib/http/auth/jwt-ratchet-local-web-token-manipulator.d.ts +2 -2
- package/lib/http/auth/local-web-token-manipulator.d.ts +3 -3
- package/lib/http/auth/web-token-manipulator.d.ts +1 -1
- package/lib/http/event-util.d.ts +1 -1
- package/lib/http/response-util.d.ts +1 -1
- package/lib/http/route/epsilon-router.d.ts +1 -1
- package/lib/http/route/router-util.d.ts +2 -2
- package/lib/index.d.ts +132 -1
- package/lib/index.mjs +344 -0
- package/lib/index.mjs.map +1 -0
- package/lib/local-container-server.d.ts +1 -1
- package/lib/local-server.d.ts +1 -1
- package/lib/sample/test-error-server.d.ts +1 -1
- package/lib/util/epsilon-config-parser.d.ts +1 -1
- package/package.json +18 -19
- package/lib/background/background-dynamo-log-table-handler.js +0 -37
- package/lib/background/background-entry.js +0 -1
- package/lib/background/background-execution-event-type.js +0 -8
- package/lib/background/background-execution-event.js +0 -1
- package/lib/background/background-execution-listener.js +0 -1
- package/lib/background/background-handler.js +0 -273
- package/lib/background/background-http-adapter-handler.js +0 -128
- package/lib/background/background-meta-response-internal.js +0 -1
- package/lib/background/background-process-handling.js +0 -5
- package/lib/background/background-process-log-table-entry.js +0 -1
- package/lib/background/background-queue-response-internal.js +0 -1
- package/lib/background/background-validator.js +0 -86
- package/lib/background/epsilon-background-process-error.js +0 -93
- package/lib/background/internal-background-entry.js +0 -1
- package/lib/background/manager/abstract-background-manager.js +0 -89
- package/lib/background/manager/aws-sqs-sns-background-manager.js +0 -153
- package/lib/background/manager/background-manager-like.js +0 -1
- package/lib/background/manager/background-manager.spec.js +0 -73
- package/lib/background/manager/single-thread-local-background-manager.js +0 -45
- package/lib/background/s3-background-transaction-logger.js +0 -52
- package/lib/build/ratchet-epsilon-common-info.js +0 -14
- package/lib/built-in/background/echo-processor.js +0 -15
- package/lib/built-in/background/log-and-enqueue-echo-processor.js +0 -12
- package/lib/built-in/background/log-message-background-error-processor.js +0 -6
- package/lib/built-in/background/no-op-processor.js +0 -9
- package/lib/built-in/background/retry-processor.js +0 -40
- package/lib/built-in/background/sample-delay-processor.js +0 -13
- package/lib/built-in/background/sample-input-validated-processor-data.js +0 -1
- package/lib/built-in/background/sample-input-validated-processor.js +0 -12
- package/lib/built-in/built-in-trace-id-generators.js +0 -21
- package/lib/built-in/daemon/daemon-authorizer-function.js +0 -1
- package/lib/built-in/daemon/daemon-config.js +0 -1
- package/lib/built-in/daemon/daemon-group-selection-function.js +0 -1
- package/lib/built-in/daemon/daemon-handler.js +0 -59
- package/lib/built-in/daemon/daemon-process-state-list.js +0 -1
- package/lib/built-in/http/apollo-filter.js +0 -59
- package/lib/built-in/http/built-in-auth-filters.js +0 -107
- package/lib/built-in/http/built-in-authorizers.js +0 -39
- package/lib/built-in/http/built-in-filters.js +0 -208
- package/lib/built-in/http/built-in-handlers.js +0 -69
- package/lib/built-in/http/log-level-manipulation-filter.js +0 -16
- package/lib/built-in/http/run-handler-as-filter.js +0 -60
- package/lib/built-in/http/run-handler-as-filter.spec.js +0 -40
- package/lib/cli/ratchet-cli-handler.js +0 -20
- package/lib/cli/run-background-process-from-command-line.js +0 -22
- package/lib/config/background/background-aws-config.js +0 -1
- package/lib/config/background/background-config.js +0 -1
- package/lib/config/background/background-error-processor.js +0 -1
- package/lib/config/background/background-processor.js +0 -1
- package/lib/config/background/background-transaction-log.js +0 -1
- package/lib/config/background/background-transaction-logger.js +0 -1
- package/lib/config/cron/abstract-cron-entry.js +0 -1
- package/lib/config/cron/cron-background-entry.js +0 -1
- package/lib/config/cron/cron-config.js +0 -1
- package/lib/config/dynamo-db-config.js +0 -1
- package/lib/config/epsilon-config.js +0 -1
- package/lib/config/epsilon-lambda-event-handler.js +0 -1
- package/lib/config/epsilon-logger-config.js +0 -1
- package/lib/config/generic-aws-event-handler-function.js +0 -1
- package/lib/config/http/authorizer-function.js +0 -1
- package/lib/config/http/epsilon-authorization-context.js +0 -1
- package/lib/config/http/extended-api-gateway-event.js +0 -1
- package/lib/config/http/filter-chain-context.js +0 -1
- package/lib/config/http/filter-function.js +0 -1
- package/lib/config/http/handler-function.js +0 -1
- package/lib/config/http/http-config.js +0 -1
- package/lib/config/http/http-processing-config.js +0 -1
- package/lib/config/http/mapped-http-processing-config.js +0 -1
- package/lib/config/http/null-returned-object-handling.js +0 -6
- package/lib/config/inter-api/inter-api-aws-config.js +0 -1
- package/lib/config/inter-api/inter-api-config.js +0 -1
- package/lib/config/inter-api/inter-api-process-mapping.js +0 -1
- package/lib/config/logging-trace-id-generator.js +0 -1
- package/lib/config/open-api/open-api-document-components.js +0 -1
- package/lib/config/open-api/open-api-document-path.js +0 -1
- package/lib/config/open-api/open-api-document.js +0 -1
- package/lib/config/s3-config.js +0 -1
- package/lib/config/sns-config.js +0 -1
- package/lib/epsilon-build-properties.js +0 -24
- package/lib/epsilon-constants.js +0 -46
- package/lib/epsilon-global-handler.js +0 -154
- package/lib/epsilon-instance.js +0 -1
- package/lib/epsilon-logging-extension-processor.js +0 -15
- package/lib/http/auth/api-gateway-adapter-authentication-handler.js +0 -72
- package/lib/http/auth/auth0-web-token-manipulator.js +0 -61
- package/lib/http/auth/basic-auth-token.js +0 -1
- package/lib/http/auth/google-web-token-manipulator.js +0 -70
- package/lib/http/auth/google-web-token-manipulator.spec.js +0 -10
- package/lib/http/auth/jwt-ratchet-local-web-token-manipulator.js +0 -27
- package/lib/http/auth/local-web-token-manipulator.js +0 -74
- package/lib/http/auth/local-web-token-manipulator.spec.js +0 -24
- package/lib/http/auth/web-token-manipulator.js +0 -1
- package/lib/http/error/bad-gateway.js +0 -8
- package/lib/http/error/bad-request-error.js +0 -8
- package/lib/http/error/conflict-error.js +0 -8
- package/lib/http/error/epsilon-http-error.js +0 -133
- package/lib/http/error/epsilon-http-error.spec.js +0 -11
- package/lib/http/error/forbidden-error.js +0 -8
- package/lib/http/error/gateway-timeout.js +0 -8
- package/lib/http/error/method-not-allowed-error.js +0 -8
- package/lib/http/error/misconfigured-error.js +0 -8
- package/lib/http/error/not-found-error.js +0 -8
- package/lib/http/error/not-implemented.js +0 -8
- package/lib/http/error/request-timeout-error.js +0 -8
- package/lib/http/error/service-unavailable.js +0 -8
- package/lib/http/error/too-many-requests-error.js +0 -8
- package/lib/http/error/unauthorized-error.js +0 -8
- package/lib/http/event-util.js +0 -176
- package/lib/http/event-util.spec.js +0 -161
- package/lib/http/response-util.js +0 -141
- package/lib/http/response-util.spec.js +0 -92
- package/lib/http/route/epsilon-router.js +0 -1
- package/lib/http/route/extended-auth-response-context.js +0 -1
- package/lib/http/route/route-mapping.js +0 -1
- package/lib/http/route/route-validator-config.js +0 -1
- package/lib/http/route/router-util.js +0 -233
- package/lib/http/route/router-util.spec.js +0 -23
- package/lib/http/web-handler.js +0 -117
- package/lib/http/web-handler.spec.js +0 -32
- package/lib/http/web-v2-handler.js +0 -22
- package/lib/index.js +0 -1
- package/lib/inter-api/inter-api-entry.js +0 -1
- package/lib/inter-api/inter-api-util.js +0 -59
- package/lib/inter-api/inter-api-util.spec.js +0 -61
- package/lib/inter-api-manager.js +0 -65
- package/lib/lambda-event-handler/cron-epsilon-lambda-event-handler.js +0 -73
- package/lib/lambda-event-handler/cron-epsilon-lambda-event-handler.spec.js +0 -50
- package/lib/lambda-event-handler/dynamo-epsilon-lambda-event-handler.js +0 -33
- package/lib/lambda-event-handler/generic-sns-epsilon-lambda-event-handler.js +0 -29
- package/lib/lambda-event-handler/inter-api-epsilon-lambda-event-handler.js +0 -23
- package/lib/lambda-event-handler/s3-epsilon-lambda-event-handler.js +0 -41
- package/lib/local-container-server.js +0 -76
- package/lib/local-server-cert.js +0 -67
- package/lib/local-server.js +0 -162
- package/lib/open-api-util/open-api-doc-modifications.js +0 -1
- package/lib/open-api-util/open-api-doc-modifier.js +0 -79
- package/lib/open-api-util/open-api-doc-modifier.spec.js +0 -16
- package/lib/open-api-util/yaml-combiner.js +0 -27
- package/lib/open-api-util/yaml-combiner.spec.js +0 -22
- package/lib/sample/sample-server-components.js +0 -185
- package/lib/sample/sample-server-static-files.js +0 -593
- package/lib/sample/test-error-server.js +0 -44
- package/lib/util/aws-util.js +0 -65
- package/lib/util/context-util.js +0 -101
- package/lib/util/cron-util.js +0 -68
- package/lib/util/cron-util.spec.js +0 -124
- package/lib/util/epsilon-config-parser.js +0 -65
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { Logger } from '@bitblit/ratchet-common/lib/logger/logger.js';
|
|
2
|
-
import { StringRatchet } from '@bitblit/ratchet-common/lib/lang/string-ratchet.js';
|
|
3
|
-
import jwt from 'jsonwebtoken';
|
|
4
|
-
import jwks from 'jwks-rsa';
|
|
5
|
-
import fetch from 'cross-fetch';
|
|
6
|
-
export class GoogleWebTokenManipulator {
|
|
7
|
-
clientId;
|
|
8
|
-
static GOOGLE_DISCOVERY_DOCUMENT = 'https://accounts.google.com/.well-known/openid-configuration';
|
|
9
|
-
cacheGoogleDiscoveryDocument;
|
|
10
|
-
jwksClient;
|
|
11
|
-
constructor(clientId) {
|
|
12
|
-
this.clientId = clientId;
|
|
13
|
-
}
|
|
14
|
-
async extractTokenFromAuthorizationHeader(authHeader) {
|
|
15
|
-
let tokenString = StringRatchet.trimToEmpty(authHeader);
|
|
16
|
-
if (tokenString.toLowerCase().startsWith('bearer ')) {
|
|
17
|
-
tokenString = tokenString.substring(7);
|
|
18
|
-
}
|
|
19
|
-
const validated = !!tokenString ? await this.parseAndValidateGoogleToken(tokenString, false) : null;
|
|
20
|
-
return validated;
|
|
21
|
-
}
|
|
22
|
-
async parseAndValidateGoogleToken(googleToken, allowExpired = false) {
|
|
23
|
-
Logger.debug('Auth : %s', StringRatchet.obscure(googleToken, 4));
|
|
24
|
-
const fullToken = jwt.decode(googleToken, { complete: true });
|
|
25
|
-
const kid = fullToken.header.kid;
|
|
26
|
-
const nowEpochSeconds = Math.floor(new Date().getTime() / 1000);
|
|
27
|
-
const pubKey = await this.fetchSigningKey(kid);
|
|
28
|
-
const validated = jwt.verify(googleToken, pubKey, {
|
|
29
|
-
audience: this.clientId,
|
|
30
|
-
issuer: ['https://accounts.google.com', 'accounts.google.com'],
|
|
31
|
-
ignoreExpiration: allowExpired,
|
|
32
|
-
clockTimestamp: nowEpochSeconds,
|
|
33
|
-
});
|
|
34
|
-
return validated;
|
|
35
|
-
}
|
|
36
|
-
async fetchSigningKey(kid) {
|
|
37
|
-
const jClient = await this.fetchJwksClient();
|
|
38
|
-
return new Promise((res, rej) => {
|
|
39
|
-
jClient.getSigningKey(kid, (err, key) => {
|
|
40
|
-
if (err) {
|
|
41
|
-
rej(err);
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
res(key.publicKey || key.rsaPublicKey);
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
async fetchJwksClient() {
|
|
50
|
-
if (!this.jwksClient) {
|
|
51
|
-
const discDoc = await this.fetchGoogleDiscoveryDocument();
|
|
52
|
-
const client = jwks({
|
|
53
|
-
cache: true,
|
|
54
|
-
cacheMaxEntries: 5,
|
|
55
|
-
cacheMaxAge: 1000 * 60 * 60 * 10,
|
|
56
|
-
jwksUri: discDoc.jwks_uri,
|
|
57
|
-
});
|
|
58
|
-
this.jwksClient = client;
|
|
59
|
-
}
|
|
60
|
-
return this.jwksClient;
|
|
61
|
-
}
|
|
62
|
-
async fetchGoogleDiscoveryDocument() {
|
|
63
|
-
if (!this.cacheGoogleDiscoveryDocument) {
|
|
64
|
-
const resp = await fetch(GoogleWebTokenManipulator.GOOGLE_DISCOVERY_DOCUMENT);
|
|
65
|
-
const doc = await resp.json();
|
|
66
|
-
this.cacheGoogleDiscoveryDocument = doc;
|
|
67
|
-
}
|
|
68
|
-
return this.cacheGoogleDiscoveryDocument;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { GoogleWebTokenManipulator } from './google-web-token-manipulator.js';
|
|
2
|
-
describe('#googleWebTokenManipulator', function () {
|
|
3
|
-
xit('should extract a token', async () => {
|
|
4
|
-
const token = 'TOKEN_HERE';
|
|
5
|
-
const clientId = 'CLIENT_HERE';
|
|
6
|
-
const svc = new GoogleWebTokenManipulator(clientId);
|
|
7
|
-
const res = await svc.parseAndValidateGoogleToken(token, false);
|
|
8
|
-
expect(res).toBeTruthy();
|
|
9
|
-
});
|
|
10
|
-
});
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { StringRatchet } from '@bitblit/ratchet-common/lib/lang/string-ratchet.js';
|
|
2
|
-
import { RequireRatchet } from '@bitblit/ratchet-common/lib/lang/require-ratchet.js';
|
|
3
|
-
import { ExpiredJwtHandling } from '@bitblit/ratchet-common/lib/jwt/expired-jwt-handling.js';
|
|
4
|
-
export class JwtRatchetLocalWebTokenManipulator {
|
|
5
|
-
_jwtRatchet;
|
|
6
|
-
_issuer;
|
|
7
|
-
constructor(_jwtRatchet, _issuer) {
|
|
8
|
-
this._jwtRatchet = _jwtRatchet;
|
|
9
|
-
this._issuer = _issuer;
|
|
10
|
-
RequireRatchet.notNullOrUndefined(_jwtRatchet, '_jwtRatchet');
|
|
11
|
-
RequireRatchet.notNullOrUndefined(StringRatchet.trimToNull(_issuer), '_issuer');
|
|
12
|
-
}
|
|
13
|
-
get jwtRatchet() {
|
|
14
|
-
return this._jwtRatchet;
|
|
15
|
-
}
|
|
16
|
-
get issuer() {
|
|
17
|
-
return this._issuer;
|
|
18
|
-
}
|
|
19
|
-
async extractTokenFromAuthorizationHeader(header) {
|
|
20
|
-
let tokenString = StringRatchet.trimToEmpty(header);
|
|
21
|
-
if (tokenString.toLowerCase().startsWith('bearer ')) {
|
|
22
|
-
tokenString = tokenString.substring(7);
|
|
23
|
-
}
|
|
24
|
-
const validated = !!tokenString ? await this.jwtRatchet.decodeToken(tokenString, ExpiredJwtHandling.THROW_EXCEPTION) : null;
|
|
25
|
-
return validated;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { Logger } from '@bitblit/ratchet-common/lib/logger/logger.js';
|
|
2
|
-
import { UnauthorizedError } from '../error/unauthorized-error.js';
|
|
3
|
-
import { StringRatchet } from '@bitblit/ratchet-common/lib/lang/string-ratchet.js';
|
|
4
|
-
import { RequireRatchet } from '@bitblit/ratchet-common/lib/lang/require-ratchet.js';
|
|
5
|
-
import { JwtRatchet } from '@bitblit/ratchet-common/lib/jwt/jwt-ratchet.js';
|
|
6
|
-
import { ExpiredJwtHandling } from '@bitblit/ratchet-common/lib/jwt/expired-jwt-handling.js';
|
|
7
|
-
export class LocalWebTokenManipulator {
|
|
8
|
-
encryptionKeys;
|
|
9
|
-
issuer;
|
|
10
|
-
_ratchet;
|
|
11
|
-
constructor(encryptionKeys, issuer) {
|
|
12
|
-
this.encryptionKeys = encryptionKeys;
|
|
13
|
-
this.issuer = issuer;
|
|
14
|
-
RequireRatchet.notNullOrUndefined(encryptionKeys, 'encryptionKeys');
|
|
15
|
-
RequireRatchet.noNullOrUndefinedValuesInArray(encryptionKeys, encryptionKeys.length);
|
|
16
|
-
this._ratchet = new JwtRatchet(Promise.resolve(encryptionKeys));
|
|
17
|
-
}
|
|
18
|
-
withExtraDecryptionKeys(keys) {
|
|
19
|
-
RequireRatchet.notNullOrUndefined(keys, 'keys');
|
|
20
|
-
RequireRatchet.noNullOrUndefinedValuesInArray(keys, keys.length);
|
|
21
|
-
this._ratchet = new JwtRatchet(this._ratchet.encryptionKeyPromise, Promise.resolve(keys), this._ratchet.jtiGenerator, this._ratchet.decryptOnlyKeyUseLogLevel, this._ratchet.parseFailureLogLevel);
|
|
22
|
-
return this;
|
|
23
|
-
}
|
|
24
|
-
withParseFailureLogLevel(logLevel) {
|
|
25
|
-
this._ratchet = new JwtRatchet(this._ratchet.encryptionKeyPromise, this._ratchet.decryptKeysPromise, this._ratchet.jtiGenerator, this._ratchet.decryptOnlyKeyUseLogLevel, logLevel);
|
|
26
|
-
return this;
|
|
27
|
-
}
|
|
28
|
-
withOldKeyUseLogLevel(logLevel) {
|
|
29
|
-
this._ratchet = new JwtRatchet(this._ratchet.encryptionKeyPromise, this._ratchet.decryptKeysPromise, this._ratchet.jtiGenerator, logLevel, this._ratchet.parseFailureLogLevel);
|
|
30
|
-
return this;
|
|
31
|
-
}
|
|
32
|
-
get jwtRatchet() {
|
|
33
|
-
return this._ratchet;
|
|
34
|
-
}
|
|
35
|
-
get selectRandomEncryptionKey() {
|
|
36
|
-
return this._ratchet.selectRandomEncryptionKey();
|
|
37
|
-
}
|
|
38
|
-
createRefreshedJWTString(tokenString, expirationSeconds, allowExpired) {
|
|
39
|
-
return this._ratchet.refreshJWTString(tokenString, allowExpired || false, expirationSeconds);
|
|
40
|
-
}
|
|
41
|
-
async parseAndValidateJWTStringAsync(tokenString) {
|
|
42
|
-
const payload = await this._ratchet.decodeToken(tokenString, ExpiredJwtHandling.ADD_FLAG);
|
|
43
|
-
if (JwtRatchet.hasExpiredFlag(payload)) {
|
|
44
|
-
throw new UnauthorizedError('Failing JWT token read/validate - token expired on ' + payload.exp);
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
return payload;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
async createJWTStringAsync(principal, userObject, roles = ['USER'], expirationSeconds = 3600, proxyUser = null) {
|
|
51
|
-
Logger.info('Creating JWT token for %s that expires in %s', principal, expirationSeconds);
|
|
52
|
-
const now = new Date().getTime();
|
|
53
|
-
const expires = now + expirationSeconds * 1000;
|
|
54
|
-
const tokenData = {
|
|
55
|
-
exp: expires,
|
|
56
|
-
iss: this.issuer,
|
|
57
|
-
sub: principal,
|
|
58
|
-
iat: now,
|
|
59
|
-
user: userObject,
|
|
60
|
-
proxy: proxyUser,
|
|
61
|
-
roles: roles,
|
|
62
|
-
};
|
|
63
|
-
const token = await this._ratchet.createTokenString(tokenData, expirationSeconds);
|
|
64
|
-
return token;
|
|
65
|
-
}
|
|
66
|
-
async extractTokenFromAuthorizationHeader(header) {
|
|
67
|
-
let tokenString = StringRatchet.trimToEmpty(header);
|
|
68
|
-
if (tokenString.toLowerCase().startsWith('bearer ')) {
|
|
69
|
-
tokenString = tokenString.substring(7);
|
|
70
|
-
}
|
|
71
|
-
const validated = !!tokenString ? await this.parseAndValidateJWTStringAsync(tokenString) : null;
|
|
72
|
-
return validated;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { LocalWebTokenManipulator } from './local-web-token-manipulator.js';
|
|
2
|
-
import { Logger } from '@bitblit/ratchet-common/lib/logger/logger.js';
|
|
3
|
-
import { LoggerLevelName } from '@bitblit/ratchet-common/lib/logger/logger-level-name.js';
|
|
4
|
-
describe('#localWebTokenManipulator', function () {
|
|
5
|
-
it('should round trip a JWT token', async () => {
|
|
6
|
-
const svc = new LocalWebTokenManipulator(['1234567890'], 'test')
|
|
7
|
-
.withParseFailureLogLevel(LoggerLevelName.info)
|
|
8
|
-
.withExtraDecryptionKeys(['abcdefabcdef'])
|
|
9
|
-
.withOldKeyUseLogLevel(LoggerLevelName.info);
|
|
10
|
-
const testUser = {
|
|
11
|
-
data1: 'test',
|
|
12
|
-
data2: 15,
|
|
13
|
-
};
|
|
14
|
-
const token = await svc.createJWTStringAsync('test123@test.com', testUser);
|
|
15
|
-
Logger.info('Generated token : %s', token);
|
|
16
|
-
expect(token).toBeTruthy();
|
|
17
|
-
const outputUser = await svc.parseAndValidateJWTStringAsync(token);
|
|
18
|
-
Logger.info('Got result : %j', outputUser);
|
|
19
|
-
expect(outputUser).toBeTruthy();
|
|
20
|
-
expect(outputUser.user).toBeTruthy();
|
|
21
|
-
expect(outputUser.user['data1']).toEqual(testUser.data1);
|
|
22
|
-
expect(outputUser.user['data2']).toEqual(testUser.data2);
|
|
23
|
-
});
|
|
24
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import util from 'util';
|
|
2
|
-
import { NumberRatchet } from '@bitblit/ratchet-common/lib/lang/number-ratchet.js';
|
|
3
|
-
export class EpsilonHttpError extends Error {
|
|
4
|
-
static EPSILON_HTTP_ERROR_FLAG_KEY = '__epsilonHttpErrorFlag';
|
|
5
|
-
_httpStatusCode = 500;
|
|
6
|
-
_errors;
|
|
7
|
-
_detailErrorCode;
|
|
8
|
-
_endUserErrors;
|
|
9
|
-
_details;
|
|
10
|
-
_requestId;
|
|
11
|
-
_wrappedError;
|
|
12
|
-
constructor(...errors) {
|
|
13
|
-
super(EpsilonHttpError.combineErrorStringsWithDefault(errors));
|
|
14
|
-
Object.setPrototypeOf(this, EpsilonHttpError.prototype);
|
|
15
|
-
this._errors = errors;
|
|
16
|
-
this[EpsilonHttpError.EPSILON_HTTP_ERROR_FLAG_KEY] = true;
|
|
17
|
-
}
|
|
18
|
-
static combineErrorStringsWithDefault(errors, defMessage = 'Internal Server Error') {
|
|
19
|
-
return errors && errors.length > 0 ? errors.join(',') : defMessage;
|
|
20
|
-
}
|
|
21
|
-
setFormattedErrorMessage(format, ...input) {
|
|
22
|
-
const msg = util.format(format, ...input);
|
|
23
|
-
this.errors = [msg];
|
|
24
|
-
}
|
|
25
|
-
withFormattedErrorMessage(format, ...input) {
|
|
26
|
-
this.setFormattedErrorMessage(format, ...input);
|
|
27
|
-
return this;
|
|
28
|
-
}
|
|
29
|
-
withHttpStatusCode(httpStatusCode) {
|
|
30
|
-
this.httpStatusCode = httpStatusCode;
|
|
31
|
-
return this;
|
|
32
|
-
}
|
|
33
|
-
withErrors(errors) {
|
|
34
|
-
this.errors = errors;
|
|
35
|
-
return this;
|
|
36
|
-
}
|
|
37
|
-
withDetailErrorCode(detailErrorCode) {
|
|
38
|
-
this._detailErrorCode = detailErrorCode;
|
|
39
|
-
return this;
|
|
40
|
-
}
|
|
41
|
-
withEndUserErrors(endUserErrors) {
|
|
42
|
-
this._endUserErrors = endUserErrors;
|
|
43
|
-
return this;
|
|
44
|
-
}
|
|
45
|
-
withDetails(details) {
|
|
46
|
-
this._details = details;
|
|
47
|
-
return this;
|
|
48
|
-
}
|
|
49
|
-
withRequestId(requestId) {
|
|
50
|
-
this._requestId = requestId;
|
|
51
|
-
return this;
|
|
52
|
-
}
|
|
53
|
-
withWrappedError(err) {
|
|
54
|
-
this._wrappedError = err;
|
|
55
|
-
return this;
|
|
56
|
-
}
|
|
57
|
-
isWrappedError() {
|
|
58
|
-
return !!this._wrappedError;
|
|
59
|
-
}
|
|
60
|
-
static wrapError(err) {
|
|
61
|
-
let rval = null;
|
|
62
|
-
if (EpsilonHttpError.objectIsEpsilonHttpError(err)) {
|
|
63
|
-
rval = err;
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
rval = new EpsilonHttpError(err.message).withWrappedError(err).withHttpStatusCode(500);
|
|
67
|
-
}
|
|
68
|
-
return rval;
|
|
69
|
-
}
|
|
70
|
-
static objectIsEpsilonHttpError(obj) {
|
|
71
|
-
return obj && obj['__epsilonHttpErrorFlag'] === true;
|
|
72
|
-
}
|
|
73
|
-
get httpStatusCode() {
|
|
74
|
-
return this._httpStatusCode;
|
|
75
|
-
}
|
|
76
|
-
get errors() {
|
|
77
|
-
return this._errors;
|
|
78
|
-
}
|
|
79
|
-
get detailErrorCode() {
|
|
80
|
-
return this._detailErrorCode;
|
|
81
|
-
}
|
|
82
|
-
get endUserErrors() {
|
|
83
|
-
return this._endUserErrors;
|
|
84
|
-
}
|
|
85
|
-
get details() {
|
|
86
|
-
return this._details;
|
|
87
|
-
}
|
|
88
|
-
get requestId() {
|
|
89
|
-
return this._requestId;
|
|
90
|
-
}
|
|
91
|
-
get wrappedError() {
|
|
92
|
-
return this._wrappedError;
|
|
93
|
-
}
|
|
94
|
-
set httpStatusCode(value) {
|
|
95
|
-
this._httpStatusCode = value || 500;
|
|
96
|
-
}
|
|
97
|
-
set errors(value) {
|
|
98
|
-
this._errors = value || ['Internal Server Error'];
|
|
99
|
-
this.message = EpsilonHttpError.combineErrorStringsWithDefault(this._errors);
|
|
100
|
-
}
|
|
101
|
-
set detailErrorCode(value) {
|
|
102
|
-
this._detailErrorCode = value;
|
|
103
|
-
}
|
|
104
|
-
set endUserErrors(value) {
|
|
105
|
-
this._endUserErrors = value;
|
|
106
|
-
}
|
|
107
|
-
set details(value) {
|
|
108
|
-
this._details = value;
|
|
109
|
-
}
|
|
110
|
-
set requestId(value) {
|
|
111
|
-
this._requestId = value || 'MISSING';
|
|
112
|
-
}
|
|
113
|
-
set wrappedError(value) {
|
|
114
|
-
this._wrappedError = value;
|
|
115
|
-
}
|
|
116
|
-
static errorIsX0x(errIn, xClass) {
|
|
117
|
-
let rval = false;
|
|
118
|
-
if (errIn && EpsilonHttpError.objectIsEpsilonHttpError(errIn)) {
|
|
119
|
-
const err = errIn;
|
|
120
|
-
const val = NumberRatchet.safeNumber(err.httpStatusCode);
|
|
121
|
-
const bot = xClass * 100;
|
|
122
|
-
const top = bot + 99;
|
|
123
|
-
rval = val >= bot && val <= top;
|
|
124
|
-
}
|
|
125
|
-
return rval;
|
|
126
|
-
}
|
|
127
|
-
static errorIs40x(err) {
|
|
128
|
-
return EpsilonHttpError.errorIsX0x(err, 4);
|
|
129
|
-
}
|
|
130
|
-
static errorIs50x(err) {
|
|
131
|
-
return EpsilonHttpError.errorIsX0x(err, 5);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { EpsilonHttpError } from './epsilon-http-error.js';
|
|
2
|
-
describe('#epsilonHttpError', function () {
|
|
3
|
-
it('chould check if the error is a given class', async () => {
|
|
4
|
-
const testError = new EpsilonHttpError('test').withHttpStatusCode(404);
|
|
5
|
-
const nonHttpError = new Error('Not HTTP');
|
|
6
|
-
expect(EpsilonHttpError.errorIs40x(testError)).toBeTruthy();
|
|
7
|
-
expect(EpsilonHttpError.errorIs50x(testError)).toBeFalsy();
|
|
8
|
-
expect(EpsilonHttpError.errorIs40x(nonHttpError)).toBeFalsy();
|
|
9
|
-
expect(EpsilonHttpError.errorIs50x(testError)).toBeFalsy();
|
|
10
|
-
});
|
|
11
|
-
});
|
package/lib/http/event-util.js
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
import { UnauthorizedError } from './error/unauthorized-error.js';
|
|
2
|
-
import { BadRequestError } from './error/bad-request-error.js';
|
|
3
|
-
import { Logger } from '@bitblit/ratchet-common/lib/logger/logger.js';
|
|
4
|
-
import { StringRatchet } from '@bitblit/ratchet-common/lib/lang/string-ratchet.js';
|
|
5
|
-
import { MapRatchet } from '@bitblit/ratchet-common/lib/lang/map-ratchet.js';
|
|
6
|
-
import { LoggerLevelName } from '@bitblit/ratchet-common/lib/logger/logger-level-name.js';
|
|
7
|
-
import { EnumRatchet } from '@bitblit/ratchet-common/lib/lang/enum-ratchet.js';
|
|
8
|
-
import { Base64Ratchet } from '@bitblit/ratchet-common/lib/lang/base64-ratchet.js';
|
|
9
|
-
import jwt from 'jsonwebtoken';
|
|
10
|
-
import { EpsilonConstants } from '../epsilon-constants.js';
|
|
11
|
-
export class EventUtil {
|
|
12
|
-
constructor() { }
|
|
13
|
-
static extractStage(event) {
|
|
14
|
-
if (!event.path.startsWith('/')) {
|
|
15
|
-
throw new BadRequestError('Path should start with / but does not : ' + event.path);
|
|
16
|
-
}
|
|
17
|
-
const idx = event.path.indexOf('/', 1);
|
|
18
|
-
if (idx == -1) {
|
|
19
|
-
throw new BadRequestError('No second / found in the path : ' + event.path);
|
|
20
|
-
}
|
|
21
|
-
return event.path.substring(1, idx);
|
|
22
|
-
}
|
|
23
|
-
static extractHostHeader(event) {
|
|
24
|
-
return MapRatchet.extractValueFromMapIgnoreCase(event.headers, 'Host');
|
|
25
|
-
}
|
|
26
|
-
static extractProtocol(event) {
|
|
27
|
-
return MapRatchet.extractValueFromMapIgnoreCase(event.headers, 'X-Forwarded-Proto');
|
|
28
|
-
}
|
|
29
|
-
static extractApiGatewayStage(event) {
|
|
30
|
-
const rc = EventUtil.extractRequestContext(event);
|
|
31
|
-
return rc ? rc.stage : null;
|
|
32
|
-
}
|
|
33
|
-
static extractRequestContext(event) {
|
|
34
|
-
return event.requestContext;
|
|
35
|
-
}
|
|
36
|
-
static extractAuthorizer(event) {
|
|
37
|
-
const rc = EventUtil.extractRequestContext(event);
|
|
38
|
-
return rc ? rc.authorizer : null;
|
|
39
|
-
}
|
|
40
|
-
static ipAddressChain(event) {
|
|
41
|
-
const headerVal = event && event.headers ? MapRatchet.extractValueFromMapIgnoreCase(event.headers, 'X-Forwarded-For') : null;
|
|
42
|
-
let headerList = headerVal ? String(headerVal).split(',') : [];
|
|
43
|
-
headerList = headerList.map((s) => s.trim());
|
|
44
|
-
return headerList;
|
|
45
|
-
}
|
|
46
|
-
static ipAddress(event) {
|
|
47
|
-
const list = EventUtil.ipAddressChain(event);
|
|
48
|
-
return list && list.length > 0 ? list[0] : null;
|
|
49
|
-
}
|
|
50
|
-
static extractFullPath(event, overrideProtocol = null) {
|
|
51
|
-
const protocol = overrideProtocol || EventUtil.extractProtocol(event) || 'https';
|
|
52
|
-
return protocol + '://' + event.requestContext['domainName'] + event.requestContext.path;
|
|
53
|
-
}
|
|
54
|
-
static extractFullPrefix(event, overrideProtocol = null) {
|
|
55
|
-
const protocol = overrideProtocol || EventUtil.extractProtocol(event) || 'https';
|
|
56
|
-
const prefix = event.requestContext.path.substring(0, event.requestContext.path.indexOf('/', 1));
|
|
57
|
-
return protocol + '://' + event.requestContext['domainName'] + prefix;
|
|
58
|
-
}
|
|
59
|
-
static jsonBodyToObject(event) {
|
|
60
|
-
let rval = null;
|
|
61
|
-
if (event.body) {
|
|
62
|
-
const contentType = MapRatchet.extractValueFromMapIgnoreCase(event.headers, 'Content-Type') || 'application/octet-stream';
|
|
63
|
-
rval = event.body;
|
|
64
|
-
if (event.isBase64Encoded) {
|
|
65
|
-
rval = Buffer.from(rval, 'base64');
|
|
66
|
-
}
|
|
67
|
-
if (contentType.startsWith('application/json')) {
|
|
68
|
-
rval = JSON.parse(rval.toString('ascii'));
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return rval;
|
|
72
|
-
}
|
|
73
|
-
static calcLogLevelViaEventOrEnvParam(curLevel, event, rConfig) {
|
|
74
|
-
let rval = curLevel;
|
|
75
|
-
if (rConfig?.envParamLogLevelName && process.env[rConfig.envParamLogLevelName]) {
|
|
76
|
-
rval = EnumRatchet.keyToEnum(LoggerLevelName, process.env[rConfig.envParamLogLevelName]);
|
|
77
|
-
Logger.silly('Found env log level : %s', rval);
|
|
78
|
-
}
|
|
79
|
-
if (rConfig &&
|
|
80
|
-
rConfig.queryParamLogLevelName &&
|
|
81
|
-
event &&
|
|
82
|
-
event.queryStringParameters &&
|
|
83
|
-
event.queryStringParameters[rConfig.queryParamLogLevelName]) {
|
|
84
|
-
rval = EnumRatchet.keyToEnum(LoggerLevelName, event.queryStringParameters[rConfig.queryParamLogLevelName]);
|
|
85
|
-
Logger.silly('Found query log level : %s', rval);
|
|
86
|
-
}
|
|
87
|
-
return rval;
|
|
88
|
-
}
|
|
89
|
-
static fixStillEncodedQueryParams(event) {
|
|
90
|
-
if (event?.queryStringParameters) {
|
|
91
|
-
const newParams = {};
|
|
92
|
-
Object.keys(event.queryStringParameters).forEach((k) => {
|
|
93
|
-
const val = event.queryStringParameters[k];
|
|
94
|
-
if (k.toLowerCase().startsWith('amp;')) {
|
|
95
|
-
newParams[k.substring(4)] = val;
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
newParams[k] = val;
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
event.queryStringParameters = newParams;
|
|
102
|
-
}
|
|
103
|
-
if (event?.multiValueQueryStringParameters) {
|
|
104
|
-
const newParams = {};
|
|
105
|
-
Object.keys(event.multiValueQueryStringParameters).forEach((k) => {
|
|
106
|
-
const val = event.multiValueQueryStringParameters[k];
|
|
107
|
-
if (k.toLowerCase().startsWith('amp;')) {
|
|
108
|
-
newParams[k.substring(4)] = val;
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
newParams[k] = val;
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
event.multiValueQueryStringParameters = newParams;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
static applyTokenToEventForTesting(event, jwtToken) {
|
|
118
|
-
const jwtFullData = jwt.decode(jwtToken, { complete: true });
|
|
119
|
-
if (!jwtFullData['payload']) {
|
|
120
|
-
throw new Error('No payload found in passed token');
|
|
121
|
-
}
|
|
122
|
-
const jwtData = jwtFullData['payload'];
|
|
123
|
-
event.headers = event.headers || {};
|
|
124
|
-
event.headers[EpsilonConstants.AUTH_HEADER_NAME.toLowerCase()] = 'Bearer ' + jwtToken;
|
|
125
|
-
event.requestContext = event.requestContext || {};
|
|
126
|
-
const newAuth = Object.assign({}, event.requestContext.authorizer);
|
|
127
|
-
newAuth.userData = jwtData;
|
|
128
|
-
newAuth.userDataJSON = jwtData ? JSON.stringify(jwtData) : null;
|
|
129
|
-
newAuth.srcData = jwtToken;
|
|
130
|
-
event.requestContext.authorizer = newAuth;
|
|
131
|
-
}
|
|
132
|
-
static extractBasicAuthenticationToken(event, throwErrorOnMissingBad = false) {
|
|
133
|
-
let rval = null;
|
|
134
|
-
if (!!event && !!event.headers) {
|
|
135
|
-
const headerVal = EventUtil.extractAuthorizationHeaderCaseInsensitive(event);
|
|
136
|
-
if (!!headerVal && headerVal.startsWith('Basic ')) {
|
|
137
|
-
const parsed = Base64Ratchet.base64StringToString(headerVal.substring(6));
|
|
138
|
-
const sp = parsed.split(':');
|
|
139
|
-
Logger.silly('Parsed to %j', sp);
|
|
140
|
-
if (!!sp && sp.length === 2) {
|
|
141
|
-
rval = {
|
|
142
|
-
username: sp[0],
|
|
143
|
-
password: sp[1],
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
if (!rval && throwErrorOnMissingBad) {
|
|
149
|
-
throw new UnauthorizedError('Could not find valid basic authentication header');
|
|
150
|
-
}
|
|
151
|
-
return rval;
|
|
152
|
-
}
|
|
153
|
-
static eventIsAGraphQLIntrospection(event) {
|
|
154
|
-
let rval = false;
|
|
155
|
-
if (!!event) {
|
|
156
|
-
if (!!event.httpMethod && 'post' === event.httpMethod.toLowerCase()) {
|
|
157
|
-
if (!!event.path && event.path.endsWith('/graphql')) {
|
|
158
|
-
const body = EventUtil.jsonBodyToObject(event);
|
|
159
|
-
rval = !!body && !!body['operationName'] && body['operationName'] === 'IntrospectionQuery';
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
return rval;
|
|
164
|
-
}
|
|
165
|
-
static extractAuthorizationHeaderCaseInsensitive(evt) {
|
|
166
|
-
return MapRatchet.caseInsensitiveAccess(evt?.headers || {}, EpsilonConstants.AUTH_HEADER_NAME);
|
|
167
|
-
}
|
|
168
|
-
static extractBearerTokenFromEvent(evt) {
|
|
169
|
-
let rval = null;
|
|
170
|
-
const authHeader = StringRatchet.trimToEmpty(EventUtil.extractAuthorizationHeaderCaseInsensitive(evt));
|
|
171
|
-
if (authHeader.toLowerCase().startsWith('bearer ')) {
|
|
172
|
-
rval = authHeader.substring(7);
|
|
173
|
-
}
|
|
174
|
-
return rval;
|
|
175
|
-
}
|
|
176
|
-
}
|