@bitblit/ratchet-aws 4.0.80-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/dist/cjs/batch/aws-batch-background-processor.js +44 -0
- package/dist/cjs/batch/aws-batch-ratchet.js +55 -0
- package/dist/cjs/build/ratchet-aws-info.js +18 -0
- package/dist/cjs/cache/dynamo-db-storage-provider.js +111 -0
- package/dist/cjs/cache/s3-storage-provider.js +44 -0
- package/dist/cjs/cache/simple-cache-object-wrapper.js +2 -0
- package/dist/cjs/cache/simple-cache-read-options.js +2 -0
- package/dist/cjs/cache/simple-cache-storage-provider.js +2 -0
- package/dist/cjs/cache/simple-cache.js +66 -0
- package/dist/cjs/cloudwatch/cloud-watch-log-group-ratchet.js +73 -0
- package/dist/cjs/cloudwatch/cloud-watch-logs-ratchet.js +173 -0
- package/dist/cjs/cloudwatch/cloud-watch-metrics-ratchet.js +57 -0
- package/dist/cjs/daemon/daemon-like.js +2 -0
- package/dist/cjs/daemon/daemon-process-create-options.js +2 -0
- package/dist/cjs/daemon/daemon-process-state-public-token.js +2 -0
- package/dist/cjs/daemon/daemon-process-state.js +2 -0
- package/dist/cjs/daemon/daemon-util.js +152 -0
- package/dist/cjs/daemon/daemon.js +126 -0
- package/dist/cjs/dao/prototype-dao-config.js +2 -0
- package/dist/cjs/dao/prototype-dao-db.js +2 -0
- package/dist/cjs/dao/prototype-dao-provider.js +2 -0
- package/dist/cjs/dao/prototype-dao.js +88 -0
- package/dist/cjs/dao/s3-prototype-dao-provider.js +28 -0
- package/dist/cjs/dao/s3-simple-dao.js +78 -0
- package/dist/cjs/dao/simple-dao-item.js +2 -0
- package/dist/cjs/dynamodb/dynamo-ratchet-like.js +2 -0
- package/dist/cjs/dynamodb/dynamo-ratchet.js +667 -0
- package/dist/cjs/dynamodb/dynamo-table-ratchet.js +91 -0
- package/dist/cjs/dynamodb/hash-spreader.js +62 -0
- package/dist/cjs/ec2/ec2-ratchet.js +107 -0
- package/dist/cjs/environment/cascade-environment-service-provider.js +27 -0
- package/dist/cjs/environment/env-var-environment-service-provider.js +33 -0
- package/dist/cjs/environment/environment-service-config.js +2 -0
- package/dist/cjs/environment/environment-service-provider.js +2 -0
- package/dist/cjs/environment/environment-service.js +52 -0
- package/dist/cjs/environment/fixed-environment-service-provider.js +24 -0
- package/dist/cjs/environment/s3-environment-service-provider.js +29 -0
- package/dist/cjs/environment/ssm-environment-service-provider.js +61 -0
- package/dist/cjs/expiring-code/dynamo-expiring-code-provider.js +26 -0
- package/dist/cjs/expiring-code/expiring-code-params.js +2 -0
- package/dist/cjs/expiring-code/expiring-code-provider.js +2 -0
- package/dist/cjs/expiring-code/expiring-code-ratchet.js +37 -0
- package/dist/cjs/expiring-code/expiring-code.js +2 -0
- package/dist/cjs/expiring-code/s3-expiring-code-provider.js +49 -0
- package/dist/cjs/iam/aws-credentials-ratchet.js +21 -0
- package/dist/cjs/index.js +81 -0
- package/dist/cjs/lambda/lambda-event-detector.js +42 -0
- package/dist/cjs/lambda/lambda-event-type-guards.js +28 -0
- package/dist/cjs/model/cloud-watch-metrics-minute-level-dynamo-count-request.js +2 -0
- package/dist/cjs/model/cloud-watch-metrics-unit.js +33 -0
- package/dist/cjs/model/dynamo/doc-put-item-command-input.js +2 -0
- package/dist/cjs/model/dynamo/doc-query-command-input.js +2 -0
- package/dist/cjs/model/dynamo/doc-scan-command-input.js +2 -0
- package/dist/cjs/model/dynamo/doc-update-item-command-input.js +2 -0
- package/dist/cjs/model/dynamo-count-result.js +2 -0
- package/dist/cjs/route53/route-53-ratchet.js +57 -0
- package/dist/cjs/runtime-parameter/cached-stored-runtime-parameter.js +2 -0
- package/dist/cjs/runtime-parameter/dynamo-runtime-parameter-provider.js +38 -0
- package/dist/cjs/runtime-parameter/global-variable-override-runtime-parameter-provider.js +54 -0
- package/dist/cjs/runtime-parameter/memory-runtime-parameter-provider.js +30 -0
- package/dist/cjs/runtime-parameter/runtime-parameter-provider.js +2 -0
- package/dist/cjs/runtime-parameter/runtime-parameter-ratchet.js +74 -0
- package/dist/cjs/runtime-parameter/stored-runtime-parameter.js +2 -0
- package/dist/cjs/s3/s3-cache-ratchet.js +332 -0
- package/dist/cjs/s3/s3-cache-to-local-disk-ratchet.js +105 -0
- package/dist/cjs/s3/s3-location-sync-ratchet.js +142 -0
- package/dist/cjs/s3/s3-ratchet.js +26 -0
- package/dist/cjs/ses/email-attachment.js +2 -0
- package/dist/cjs/ses/mailer-config.js +2 -0
- package/dist/cjs/ses/mailer-like.js +2 -0
- package/dist/cjs/ses/mailer.js +208 -0
- package/dist/cjs/ses/ratchet-template-renderer.js +2 -0
- package/dist/cjs/ses/ready-to-send-email.js +2 -0
- package/dist/cjs/ses/remote-handlebars-template-renderer.js +79 -0
- package/dist/cjs/ses/resolved-ready-to-send-email.js +2 -0
- package/dist/cjs/sns/sns-ratchet.js +47 -0
- package/dist/cjs/sync-lock/dynamo-db-sync-lock.js +69 -0
- package/dist/cjs/sync-lock/memory-sync-lock.js +40 -0
- package/dist/cjs/sync-lock/sync-lock-provider.js +2 -0
- package/dist/es/batch/aws-batch-background-processor.js +40 -0
- package/dist/es/batch/aws-batch-ratchet.js +51 -0
- package/dist/es/build/ratchet-aws-info.js +14 -0
- package/dist/es/cache/dynamo-db-storage-provider.js +107 -0
- package/dist/es/cache/s3-storage-provider.js +40 -0
- package/dist/es/cache/simple-cache-object-wrapper.js +1 -0
- package/dist/es/cache/simple-cache-read-options.js +1 -0
- package/dist/es/cache/simple-cache-storage-provider.js +1 -0
- package/dist/es/cache/simple-cache.js +62 -0
- package/dist/es/cloudwatch/cloud-watch-log-group-ratchet.js +69 -0
- package/dist/es/cloudwatch/cloud-watch-logs-ratchet.js +169 -0
- package/dist/es/cloudwatch/cloud-watch-metrics-ratchet.js +53 -0
- package/dist/es/daemon/daemon-like.js +1 -0
- package/dist/es/daemon/daemon-process-create-options.js +1 -0
- package/dist/es/daemon/daemon-process-state-public-token.js +1 -0
- package/dist/es/daemon/daemon-process-state.js +1 -0
- package/dist/es/daemon/daemon-util.js +148 -0
- package/dist/es/daemon/daemon.js +122 -0
- package/dist/es/dao/prototype-dao-config.js +1 -0
- package/dist/es/dao/prototype-dao-db.js +1 -0
- package/dist/es/dao/prototype-dao-provider.js +1 -0
- package/dist/es/dao/prototype-dao.js +84 -0
- package/dist/es/dao/s3-prototype-dao-provider.js +24 -0
- package/dist/es/dao/s3-simple-dao.js +74 -0
- package/dist/es/dao/simple-dao-item.js +1 -0
- package/dist/es/dynamodb/dynamo-ratchet-like.js +1 -0
- package/dist/es/dynamodb/dynamo-ratchet.js +663 -0
- package/dist/es/dynamodb/dynamo-table-ratchet.js +87 -0
- package/dist/es/dynamodb/hash-spreader.js +58 -0
- package/dist/es/ec2/ec2-ratchet.js +103 -0
- package/dist/es/environment/cascade-environment-service-provider.js +23 -0
- package/dist/es/environment/env-var-environment-service-provider.js +29 -0
- package/dist/es/environment/environment-service-config.js +1 -0
- package/dist/es/environment/environment-service-provider.js +1 -0
- package/dist/es/environment/environment-service.js +48 -0
- package/dist/es/environment/fixed-environment-service-provider.js +20 -0
- package/dist/es/environment/s3-environment-service-provider.js +25 -0
- package/dist/es/environment/ssm-environment-service-provider.js +56 -0
- package/dist/es/expiring-code/dynamo-expiring-code-provider.js +22 -0
- package/dist/es/expiring-code/expiring-code-params.js +1 -0
- package/dist/es/expiring-code/expiring-code-provider.js +1 -0
- package/dist/es/expiring-code/expiring-code-ratchet.js +33 -0
- package/dist/es/expiring-code/expiring-code.js +1 -0
- package/dist/es/expiring-code/s3-expiring-code-provider.js +45 -0
- package/dist/es/iam/aws-credentials-ratchet.js +17 -0
- package/dist/es/index.js +78 -0
- package/dist/es/lambda/lambda-event-detector.js +38 -0
- package/dist/es/lambda/lambda-event-type-guards.js +24 -0
- package/dist/es/model/cloud-watch-metrics-minute-level-dynamo-count-request.js +1 -0
- package/dist/es/model/cloud-watch-metrics-unit.js +30 -0
- package/dist/es/model/dynamo/doc-put-item-command-input.js +1 -0
- package/dist/es/model/dynamo/doc-query-command-input.js +1 -0
- package/dist/es/model/dynamo/doc-scan-command-input.js +1 -0
- package/dist/es/model/dynamo/doc-update-item-command-input.js +1 -0
- package/dist/es/model/dynamo-count-result.js +1 -0
- package/dist/es/route53/route-53-ratchet.js +53 -0
- package/dist/es/runtime-parameter/cached-stored-runtime-parameter.js +1 -0
- package/dist/es/runtime-parameter/dynamo-runtime-parameter-provider.js +34 -0
- package/dist/es/runtime-parameter/global-variable-override-runtime-parameter-provider.js +49 -0
- package/dist/es/runtime-parameter/memory-runtime-parameter-provider.js +26 -0
- package/dist/es/runtime-parameter/runtime-parameter-provider.js +1 -0
- package/dist/es/runtime-parameter/runtime-parameter-ratchet.js +70 -0
- package/dist/es/runtime-parameter/stored-runtime-parameter.js +1 -0
- package/dist/es/s3/s3-cache-ratchet.js +328 -0
- package/dist/es/s3/s3-cache-to-local-disk-ratchet.js +100 -0
- package/dist/es/s3/s3-location-sync-ratchet.js +137 -0
- package/dist/es/s3/s3-ratchet.js +22 -0
- package/dist/es/ses/email-attachment.js +1 -0
- package/dist/es/ses/mailer-config.js +1 -0
- package/dist/es/ses/mailer-like.js +1 -0
- package/dist/es/ses/mailer.js +204 -0
- package/dist/es/ses/ratchet-template-renderer.js +1 -0
- package/dist/es/ses/ready-to-send-email.js +1 -0
- package/dist/es/ses/remote-handlebars-template-renderer.js +74 -0
- package/dist/es/ses/resolved-ready-to-send-email.js +1 -0
- package/dist/es/sns/sns-ratchet.js +43 -0
- package/dist/es/sync-lock/dynamo-db-sync-lock.js +65 -0
- package/dist/es/sync-lock/memory-sync-lock.js +36 -0
- package/dist/es/sync-lock/sync-lock-provider.js +1 -0
- package/dist/tsconfig.cjs.tsbuildinfo +1 -0
- package/dist/tsconfig.es.tsbuildinfo +1 -0
- package/dist/tsconfig.types.tsbuildinfo +1 -0
- package/dist/types/batch/aws-batch-background-processor.d.ts +12 -0
- package/dist/types/batch/aws-batch-ratchet.d.ts +16 -0
- package/dist/types/build/ratchet-aws-info.d.ts +5 -0
- package/dist/types/cache/dynamo-db-storage-provider.d.ts +25 -0
- package/dist/types/cache/s3-storage-provider.d.ts +14 -0
- package/dist/types/cache/simple-cache-object-wrapper.d.ts +7 -0
- package/dist/types/cache/simple-cache-read-options.d.ts +5 -0
- package/dist/types/cache/simple-cache-storage-provider.d.ts +8 -0
- package/dist/types/cache/simple-cache.d.ts +14 -0
- package/dist/types/cloudwatch/cloud-watch-log-group-ratchet.d.ts +9 -0
- package/dist/types/cloudwatch/cloud-watch-logs-ratchet.d.ts +14 -0
- package/dist/types/cloudwatch/cloud-watch-metrics-ratchet.d.ts +10 -0
- package/dist/types/daemon/daemon-like.d.ts +17 -0
- package/dist/types/daemon/daemon-process-create-options.d.ts +7 -0
- package/dist/types/daemon/daemon-process-state-public-token.d.ts +4 -0
- package/dist/types/daemon/daemon-process-state.d.ts +13 -0
- package/dist/types/daemon/daemon-util.d.ts +24 -0
- package/dist/types/daemon/daemon.d.ts +33 -0
- package/dist/types/dao/prototype-dao-config.d.ts +8 -0
- package/dist/types/dao/prototype-dao-db.d.ts +4 -0
- package/dist/types/dao/prototype-dao-provider.d.ts +5 -0
- package/dist/types/dao/prototype-dao.d.ts +15 -0
- package/dist/types/dao/s3-prototype-dao-provider.d.ts +10 -0
- package/dist/types/dao/s3-simple-dao.d.ts +15 -0
- package/dist/types/dao/simple-dao-item.d.ts +5 -0
- package/dist/types/dynamodb/dynamo-ratchet-like.d.ts +27 -0
- package/dist/types/dynamodb/dynamo-ratchet.d.ts +36 -0
- package/dist/types/dynamodb/dynamo-table-ratchet.d.ts +11 -0
- package/dist/types/dynamodb/hash-spreader.d.ts +15 -0
- package/dist/types/ec2/ec2-ratchet.d.ts +25 -0
- package/dist/types/environment/cascade-environment-service-provider.d.ts +9 -0
- package/dist/types/environment/env-var-environment-service-provider.d.ts +10 -0
- package/dist/types/environment/environment-service-config.d.ts +7 -0
- package/dist/types/environment/environment-service-provider.d.ts +7 -0
- package/dist/types/environment/environment-service.d.ts +14 -0
- package/dist/types/environment/fixed-environment-service-provider.d.ts +10 -0
- package/dist/types/environment/s3-environment-service-provider.d.ts +18 -0
- package/dist/types/environment/ssm-environment-service-provider.d.ts +12 -0
- package/dist/types/expiring-code/dynamo-expiring-code-provider.d.ts +12 -0
- package/dist/types/expiring-code/expiring-code-params.d.ts +7 -0
- package/dist/types/expiring-code/expiring-code-provider.d.ts +5 -0
- package/dist/types/expiring-code/expiring-code-ratchet.d.ts +13 -0
- package/dist/types/expiring-code/expiring-code.d.ts +6 -0
- package/dist/types/expiring-code/s3-expiring-code-provider.d.ts +17 -0
- package/dist/types/iam/aws-credentials-ratchet.d.ts +9 -0
- package/dist/types/index.d.ts +81 -0
- package/dist/types/lambda/lambda-event-detector.d.ts +14 -0
- package/dist/types/lambda/lambda-event-type-guards.d.ts +10 -0
- package/dist/types/model/cloud-watch-metrics-minute-level-dynamo-count-request.d.ts +12 -0
- package/dist/types/model/cloud-watch-metrics-unit.d.ts +29 -0
- package/dist/types/model/dynamo/doc-put-item-command-input.d.ts +4 -0
- package/dist/types/model/dynamo/doc-query-command-input.d.ts +5 -0
- package/dist/types/model/dynamo/doc-scan-command-input.d.ts +5 -0
- package/dist/types/model/dynamo/doc-update-item-command-input.d.ts +5 -0
- package/dist/types/model/dynamo-count-result.d.ts +5 -0
- package/dist/types/route53/route-53-ratchet.d.ts +7 -0
- package/dist/types/runtime-parameter/cached-stored-runtime-parameter.d.ts +4 -0
- package/dist/types/runtime-parameter/dynamo-runtime-parameter-provider.d.ts +11 -0
- package/dist/types/runtime-parameter/global-variable-override-runtime-parameter-provider.d.ts +24 -0
- package/dist/types/runtime-parameter/memory-runtime-parameter-provider.d.ts +13 -0
- package/dist/types/runtime-parameter/runtime-parameter-provider.d.ts +11 -0
- package/dist/types/runtime-parameter/runtime-parameter-ratchet.d.ts +15 -0
- package/dist/types/runtime-parameter/stored-runtime-parameter.d.ts +6 -0
- package/dist/types/s3/s3-cache-ratchet.d.ts +38 -0
- package/dist/types/s3/s3-cache-to-local-disk-ratchet.d.ts +21 -0
- package/dist/types/s3/s3-location-sync-ratchet.d.ts +21 -0
- package/dist/types/s3/s3-ratchet.d.ts +5 -0
- package/dist/types/ses/email-attachment.d.ts +23 -0
- package/dist/types/ses/mailer-config.d.ts +15 -0
- package/dist/types/ses/mailer-like.d.ts +18 -0
- package/dist/types/ses/mailer.d.ts +26 -0
- package/dist/types/ses/ratchet-template-renderer.d.ts +8 -0
- package/dist/types/ses/ready-to-send-email.d.ts +66 -0
- package/dist/types/ses/remote-handlebars-template-renderer.d.ts +15 -0
- package/dist/types/ses/resolved-ready-to-send-email.d.ts +16 -0
- package/dist/types/sns/sns-ratchet.d.ts +8 -0
- package/dist/types/sync-lock/dynamo-db-sync-lock.d.ts +10 -0
- package/dist/types/sync-lock/memory-sync-lock.d.ts +11 -0
- package/dist/types/sync-lock/sync-lock-provider.d.ts +5 -0
- package/package.json +112 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { CreateTableCommand, DeleteTableCommand, DescribeTableCommand, } from '@aws-sdk/client-dynamodb';
|
|
2
|
+
import { Logger } from '@bitblit/ratchet-common';
|
|
3
|
+
import { RequireRatchet } from '@bitblit/ratchet-common';
|
|
4
|
+
import { PromiseRatchet } from '@bitblit/ratchet-common';
|
|
5
|
+
import { ErrorRatchet } from '@bitblit/ratchet-common';
|
|
6
|
+
export class DynamoTableRatchet {
|
|
7
|
+
constructor(awsDDB) {
|
|
8
|
+
this.awsDDB = awsDDB;
|
|
9
|
+
if (!awsDDB) {
|
|
10
|
+
throw 'awsDDB may not be null';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
async deleteTable(tableName, waitForDelete = true) {
|
|
14
|
+
RequireRatchet.notNullOrUndefined(tableName);
|
|
15
|
+
const input = {
|
|
16
|
+
TableName: tableName,
|
|
17
|
+
};
|
|
18
|
+
Logger.debug('Deleting ddb table %s', tableName);
|
|
19
|
+
const rval = await this.awsDDB.send(new DeleteTableCommand(input));
|
|
20
|
+
if (waitForDelete) {
|
|
21
|
+
Logger.debug('Table marked for delete, waiting for deletion');
|
|
22
|
+
await this.waitForTableDelete(tableName);
|
|
23
|
+
}
|
|
24
|
+
return rval;
|
|
25
|
+
}
|
|
26
|
+
async createTable(input, waitForReady = true, replaceIfExists = false) {
|
|
27
|
+
RequireRatchet.notNullOrUndefined(input);
|
|
28
|
+
RequireRatchet.notNullOrUndefined(input.TableName);
|
|
29
|
+
Logger.debug('Creating new table : %j', input);
|
|
30
|
+
const exists = await this.tableExists(input.TableName);
|
|
31
|
+
if (exists) {
|
|
32
|
+
if (replaceIfExists) {
|
|
33
|
+
Logger.debug('Table %s exists and replace specified - deleting', input.TableName);
|
|
34
|
+
await this.deleteTable(input.TableName);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
ErrorRatchet.throwFormattedErr('Cannot create table %s - exists already and replace not specified', input.TableName);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const rval = await this.awsDDB.send(new CreateTableCommand(input));
|
|
41
|
+
if (waitForReady) {
|
|
42
|
+
Logger.debug('Table created, awaiting ready');
|
|
43
|
+
await this.waitForTableReady(input.TableName);
|
|
44
|
+
}
|
|
45
|
+
return rval;
|
|
46
|
+
}
|
|
47
|
+
async waitForTableReady(tableName) {
|
|
48
|
+
let rval = true;
|
|
49
|
+
let out = await this.safeDescribeTable(tableName);
|
|
50
|
+
while (!!out && !!out.Table && out.Table.TableStatus !== 'ACTIVE') {
|
|
51
|
+
Logger.silly('Table not ready - waiting 2 seconds');
|
|
52
|
+
await PromiseRatchet.wait(2000);
|
|
53
|
+
out = await this.safeDescribeTable(tableName);
|
|
54
|
+
}
|
|
55
|
+
if (!out && !out.Table) {
|
|
56
|
+
Logger.warn('Cannot wait for %s to be ready - table does not exist', tableName);
|
|
57
|
+
rval = false;
|
|
58
|
+
}
|
|
59
|
+
return rval;
|
|
60
|
+
}
|
|
61
|
+
async waitForTableDelete(tableName) {
|
|
62
|
+
let out = await this.safeDescribeTable(tableName);
|
|
63
|
+
while (!!out) {
|
|
64
|
+
Logger.silly('Table %s still exists, waiting 2 seconds (State is %s)', tableName, out.Table.TableStatus);
|
|
65
|
+
await PromiseRatchet.wait(2000);
|
|
66
|
+
out = await this.safeDescribeTable(tableName);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async tableExists(tableName) {
|
|
70
|
+
const desc = await this.safeDescribeTable(tableName);
|
|
71
|
+
return !!desc;
|
|
72
|
+
}
|
|
73
|
+
async safeDescribeTable(tableName) {
|
|
74
|
+
try {
|
|
75
|
+
const out = await this.awsDDB.send(new DescribeTableCommand({ TableName: tableName }));
|
|
76
|
+
return out;
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
if (!!err['code'] && err['code'] === 'ResourceNotFoundException') {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
throw err;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ErrorRatchet, RequireRatchet, StringRatchet } from '@bitblit/ratchet-common';
|
|
2
|
+
export class HashSpreader {
|
|
3
|
+
constructor(spots = 3, buckets = 16, separator = '_', alphabet = '0123456789ABCDEF') {
|
|
4
|
+
this.spots = spots;
|
|
5
|
+
this.buckets = buckets;
|
|
6
|
+
this.separator = separator;
|
|
7
|
+
this.alphabet = alphabet;
|
|
8
|
+
RequireRatchet.true(spots > 0, 'Spots must be larger than 0');
|
|
9
|
+
RequireRatchet.true(buckets > 1, 'Buckets must be larger than 1');
|
|
10
|
+
RequireRatchet.notNullOrUndefined(StringRatchet.trimToNull(alphabet), 'Alphabet may not be null or empty');
|
|
11
|
+
RequireRatchet.true(StringRatchet.allUnique(alphabet), 'Alphabet must be unique');
|
|
12
|
+
RequireRatchet.true(StringRatchet.stringContainsOnlyAlphanumeric(alphabet), 'Alphabet must be alphanumeric');
|
|
13
|
+
const permutations = Math.pow(alphabet.length, spots);
|
|
14
|
+
RequireRatchet.true(buckets < permutations, 'Buckets must be less than permutations (' + buckets + ' / ' + permutations + ')');
|
|
15
|
+
RequireRatchet.notNullOrUndefined(StringRatchet.trimToNull(this.separator), 'Separator must be nonnull and nonempty');
|
|
16
|
+
const allPerms = StringRatchet.allPermutationsOfLength(spots, alphabet);
|
|
17
|
+
this._allSlots = allPerms.slice(0, buckets);
|
|
18
|
+
}
|
|
19
|
+
get allBuckets() {
|
|
20
|
+
return Object.assign([], this._allSlots);
|
|
21
|
+
}
|
|
22
|
+
get randomBucket() {
|
|
23
|
+
return this._allSlots[Math.floor(Math.random() * this.buckets)];
|
|
24
|
+
}
|
|
25
|
+
allSpreadValues(input) {
|
|
26
|
+
RequireRatchet.notNullOrUndefined(StringRatchet.trimToNull(input), 'Cannot spread null/empty value');
|
|
27
|
+
const rval = this._allSlots.map((s) => input + this.separator + s);
|
|
28
|
+
return rval;
|
|
29
|
+
}
|
|
30
|
+
allSpreadValuesForArray(inputs) {
|
|
31
|
+
RequireRatchet.true(inputs && inputs.length > 0, 'Cannot spread null/empty array');
|
|
32
|
+
let rval = [];
|
|
33
|
+
inputs.forEach((i) => {
|
|
34
|
+
rval = rval.concat(this.allSpreadValues(i));
|
|
35
|
+
});
|
|
36
|
+
return rval;
|
|
37
|
+
}
|
|
38
|
+
addSpreader(input) {
|
|
39
|
+
RequireRatchet.notNullOrUndefined(StringRatchet.trimToNull(input), 'Cannot spread null/empty value');
|
|
40
|
+
return input + this.separator + this.randomBucket;
|
|
41
|
+
}
|
|
42
|
+
extractBucket(input) {
|
|
43
|
+
RequireRatchet.notNullOrUndefined(StringRatchet.trimToNull(input), 'Cannot extract from null or empty value');
|
|
44
|
+
const loc = input.length - this.spots;
|
|
45
|
+
if (loc < 0 || input.charAt(loc) !== this.separator) {
|
|
46
|
+
ErrorRatchet.throwFormattedErr('Cannot extract bucket, not created by this spreader (missing %s at location %d)', this.separator, loc);
|
|
47
|
+
}
|
|
48
|
+
return input.substring(loc);
|
|
49
|
+
}
|
|
50
|
+
removeBucket(input) {
|
|
51
|
+
RequireRatchet.notNullOrUndefined(StringRatchet.trimToNull(input), 'Cannot extract from null or empty value');
|
|
52
|
+
const loc = input.length - this.spots;
|
|
53
|
+
if (loc < 0 || input.charAt(loc) !== this.separator) {
|
|
54
|
+
ErrorRatchet.throwFormattedErr('Cannot remove bucket, not created by this spreader (missing %s at location %d)', this.separator, loc);
|
|
55
|
+
}
|
|
56
|
+
return input.substring(0, loc);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { DescribeInstancesCommand, EC2Client, StartInstancesCommand, StopInstancesCommand, } from '@aws-sdk/client-ec2';
|
|
2
|
+
import { EC2InstanceConnectClient, SendSSHPublicKeyCommand, } from '@aws-sdk/client-ec2-instance-connect';
|
|
3
|
+
import { Logger } from '@bitblit/ratchet-common';
|
|
4
|
+
import { DurationRatchet } from '@bitblit/ratchet-common';
|
|
5
|
+
import { PromiseRatchet } from '@bitblit/ratchet-common';
|
|
6
|
+
export class Ec2Ratchet {
|
|
7
|
+
constructor(region = 'us-east-1', availabilityZone = 'us-east-1a') {
|
|
8
|
+
this.region = region;
|
|
9
|
+
this.availabilityZone = availabilityZone;
|
|
10
|
+
this.ec2 = new EC2Client({ region: region });
|
|
11
|
+
this.ec2InstanceConnect = new EC2InstanceConnectClient({ region: region });
|
|
12
|
+
}
|
|
13
|
+
async stopInstance(instanceId, maxWaitForShutdownMS = 0) {
|
|
14
|
+
let rval = true;
|
|
15
|
+
try {
|
|
16
|
+
const stopParams = {
|
|
17
|
+
InstanceIds: [instanceId],
|
|
18
|
+
DryRun: false,
|
|
19
|
+
};
|
|
20
|
+
Logger.info('About to stop instances : %j', stopParams);
|
|
21
|
+
await this.ec2.send(new StopInstancesCommand(stopParams));
|
|
22
|
+
Logger.info('Stop instance command sent, waiting on shutdown');
|
|
23
|
+
let status = await this.describeInstance(instanceId);
|
|
24
|
+
if (maxWaitForShutdownMS > 0) {
|
|
25
|
+
const start = new Date().getTime();
|
|
26
|
+
while (!!status && status.State.Code !== 16 && new Date().getTime() - start < maxWaitForShutdownMS) {
|
|
27
|
+
Logger.debug('Instance status is %j - waiting for 5 seconds (up to %s)', status.State, DurationRatchet.formatMsDuration(maxWaitForShutdownMS));
|
|
28
|
+
await PromiseRatchet.wait(5000);
|
|
29
|
+
status = await this.describeInstance(instanceId);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
Logger.error('Failed to stop instance %s : %s', instanceId, err, err);
|
|
35
|
+
rval = false;
|
|
36
|
+
}
|
|
37
|
+
return rval;
|
|
38
|
+
}
|
|
39
|
+
async launchInstance(instanceId, maxWaitForStartupMS = 0) {
|
|
40
|
+
let rval = true;
|
|
41
|
+
try {
|
|
42
|
+
const startParams = {
|
|
43
|
+
InstanceIds: [instanceId],
|
|
44
|
+
DryRun: false,
|
|
45
|
+
};
|
|
46
|
+
Logger.info('About to start instance : %j', startParams);
|
|
47
|
+
await this.ec2.send(new StartInstancesCommand(startParams));
|
|
48
|
+
Logger.info('Start instance command sent, waiting on startup');
|
|
49
|
+
let status = await this.describeInstance(instanceId);
|
|
50
|
+
if (maxWaitForStartupMS > 0) {
|
|
51
|
+
const start = new Date().getTime();
|
|
52
|
+
while (!!status && status.State.Code !== 16 && new Date().getTime() - start < maxWaitForStartupMS) {
|
|
53
|
+
Logger.debug('Instance status is %j - waiting for 5 seconds (up to %s)', status.State, DurationRatchet.formatMsDuration(maxWaitForStartupMS));
|
|
54
|
+
await PromiseRatchet.wait(5000);
|
|
55
|
+
status = await this.describeInstance(instanceId);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (!!status && !!status.PublicIpAddress) {
|
|
59
|
+
Logger.info('Instance address is %s', status.PublicIpAddress);
|
|
60
|
+
Logger.info('SSH command : ssh -i path_to_pem_file ec2-user@%s', status.PublicIpAddress);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
Logger.error('Failed to start instance %s : %s', instanceId, err, err);
|
|
65
|
+
rval = false;
|
|
66
|
+
}
|
|
67
|
+
return rval;
|
|
68
|
+
}
|
|
69
|
+
async describeInstance(instanceId) {
|
|
70
|
+
const res = await this.listAllInstances([instanceId]);
|
|
71
|
+
return res.length === 1 ? res[0] : null;
|
|
72
|
+
}
|
|
73
|
+
async listAllInstances(instanceIds = []) {
|
|
74
|
+
let rval = [];
|
|
75
|
+
const req = {
|
|
76
|
+
NextToken: null,
|
|
77
|
+
};
|
|
78
|
+
if (instanceIds && instanceIds.length > 0) {
|
|
79
|
+
req.InstanceIds = instanceIds;
|
|
80
|
+
}
|
|
81
|
+
do {
|
|
82
|
+
Logger.debug('Pulling instances... (%j)', req);
|
|
83
|
+
const res = await this.ec2.send(new DescribeInstancesCommand(req));
|
|
84
|
+
res.Reservations.forEach((r) => {
|
|
85
|
+
rval = rval.concat(r.Instances);
|
|
86
|
+
});
|
|
87
|
+
req.NextToken = res.NextToken;
|
|
88
|
+
} while (req.NextToken);
|
|
89
|
+
Logger.debug('Finished pulling instances (found %d)', rval.length);
|
|
90
|
+
return rval;
|
|
91
|
+
}
|
|
92
|
+
async sendPublicKeyToEc2Instance(instanceId, publicKeyString, instanceOsUser) {
|
|
93
|
+
const userName = instanceOsUser || 'ec2-user';
|
|
94
|
+
const req = {
|
|
95
|
+
InstanceId: instanceId,
|
|
96
|
+
AvailabilityZone: this.availabilityZone,
|
|
97
|
+
InstanceOSUser: userName,
|
|
98
|
+
SSHPublicKey: publicKeyString,
|
|
99
|
+
};
|
|
100
|
+
const rval = await this.ec2InstanceConnect.send(new SendSSHPublicKeyCommand(req));
|
|
101
|
+
return rval;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Logger } from '@bitblit/ratchet-common';
|
|
2
|
+
import { RequireRatchet } from '@bitblit/ratchet-common';
|
|
3
|
+
export class CascadeEnvironmentServiceProvider {
|
|
4
|
+
constructor(providers) {
|
|
5
|
+
this.providers = providers;
|
|
6
|
+
RequireRatchet.notNullOrUndefined(providers);
|
|
7
|
+
RequireRatchet.true(providers.length > 0);
|
|
8
|
+
}
|
|
9
|
+
async fetchConfig(name) {
|
|
10
|
+
Logger.silly('CascadeEnvironmentServiceProvider fetch for %s', name);
|
|
11
|
+
let rval = null;
|
|
12
|
+
for (let i = 0; i < this.providers.length && !rval; i++) {
|
|
13
|
+
try {
|
|
14
|
+
rval = await this.providers[i].fetchConfig(name);
|
|
15
|
+
}
|
|
16
|
+
catch (err) {
|
|
17
|
+
Logger.error('Provider %d failed - trying next : %s', i, err, err);
|
|
18
|
+
rval = null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return rval;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Logger } from '@bitblit/ratchet-common';
|
|
2
|
+
import { RequireRatchet } from '@bitblit/ratchet-common';
|
|
3
|
+
import { ErrorRatchet } from '@bitblit/ratchet-common';
|
|
4
|
+
import { StringRatchet } from '@bitblit/ratchet-common';
|
|
5
|
+
export class EnvVarEnvironmentServiceProvider {
|
|
6
|
+
constructor(envVarName) {
|
|
7
|
+
this.envVarName = envVarName;
|
|
8
|
+
RequireRatchet.notNullOrUndefined(envVarName);
|
|
9
|
+
}
|
|
10
|
+
async fetchConfig() {
|
|
11
|
+
Logger.silly('EnvVarEnvironmentServiceProvider fetch for %s', this.envVarName);
|
|
12
|
+
let rval = null;
|
|
13
|
+
const src = process ? process.env : global ? global : {};
|
|
14
|
+
const toParse = StringRatchet.trimToNull(src[this.envVarName]);
|
|
15
|
+
if (toParse) {
|
|
16
|
+
try {
|
|
17
|
+
rval = JSON.parse(toParse);
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
Logger.error('Failed to read env - null or invalid JSON : %s : %s', err, toParse, err);
|
|
21
|
+
throw err;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
ErrorRatchet.throwFormattedErr('Could not find env var with name : %s', this.envVarName);
|
|
26
|
+
}
|
|
27
|
+
return rval;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Logger } from '@bitblit/ratchet-common';
|
|
2
|
+
import { PromiseRatchet } from '@bitblit/ratchet-common';
|
|
3
|
+
import { RequireRatchet } from '@bitblit/ratchet-common';
|
|
4
|
+
import { ErrorRatchet } from '@bitblit/ratchet-common';
|
|
5
|
+
export class EnvironmentService {
|
|
6
|
+
static defaultEnvironmentServiceConfig() {
|
|
7
|
+
const rval = {
|
|
8
|
+
maxRetries: 3,
|
|
9
|
+
backoffMultiplierMS: 500,
|
|
10
|
+
};
|
|
11
|
+
return rval;
|
|
12
|
+
}
|
|
13
|
+
constructor(provider, cfg = EnvironmentService.defaultEnvironmentServiceConfig()) {
|
|
14
|
+
this.provider = provider;
|
|
15
|
+
this.cfg = cfg;
|
|
16
|
+
this.readPromiseCache = new Map();
|
|
17
|
+
RequireRatchet.notNullOrUndefined(provider);
|
|
18
|
+
RequireRatchet.notNullOrUndefined(cfg);
|
|
19
|
+
}
|
|
20
|
+
async getConfig(name) {
|
|
21
|
+
Logger.silly('EnvService:Request to read config %s', name);
|
|
22
|
+
if (!this.readPromiseCache.has(name)) {
|
|
23
|
+
Logger.silly('EnvService: Nothing in cache - adding');
|
|
24
|
+
this.readPromiseCache.set(name, this.getConfigUncached(name));
|
|
25
|
+
}
|
|
26
|
+
return this.readPromiseCache.get(name);
|
|
27
|
+
}
|
|
28
|
+
async getConfigUncached(name) {
|
|
29
|
+
let tryCount = 1;
|
|
30
|
+
let rval = null;
|
|
31
|
+
while (!rval && tryCount < this.cfg.maxRetries) {
|
|
32
|
+
tryCount++;
|
|
33
|
+
Logger.silly('Attempting fetch of %s', name);
|
|
34
|
+
try {
|
|
35
|
+
rval = await this.provider.fetchConfig(name);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
const waitMS = tryCount * this.cfg.backoffMultiplierMS;
|
|
39
|
+
Logger.info('Error attempting to fetch config %s (try %d of %d, waiting %s MS): %s', name, tryCount, this.cfg.maxRetries, waitMS, err, err);
|
|
40
|
+
await PromiseRatchet.wait(waitMS);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (!rval) {
|
|
44
|
+
ErrorRatchet.throwFormattedErr('Was unable to fetch config %s even after %d retries', name, this.cfg.maxRetries);
|
|
45
|
+
}
|
|
46
|
+
return rval;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Logger } from '@bitblit/ratchet-common';
|
|
2
|
+
import { RequireRatchet } from '@bitblit/ratchet-common';
|
|
3
|
+
export class FixedEnvironmentServiceProvider {
|
|
4
|
+
constructor(value) {
|
|
5
|
+
this.value = value;
|
|
6
|
+
RequireRatchet.notNullOrUndefined(value);
|
|
7
|
+
}
|
|
8
|
+
static fromRecord(record) {
|
|
9
|
+
const m = new Map();
|
|
10
|
+
Object.keys(record).forEach((k) => {
|
|
11
|
+
m.set(k, record[k]);
|
|
12
|
+
});
|
|
13
|
+
return new FixedEnvironmentServiceProvider(m);
|
|
14
|
+
}
|
|
15
|
+
async fetchConfig(name) {
|
|
16
|
+
Logger.silly('FixedEnvironmentServiceProvider fetch for %s', name);
|
|
17
|
+
const rval = this.value.get(name);
|
|
18
|
+
return rval;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { S3CacheRatchet } from '../s3/s3-cache-ratchet';
|
|
2
|
+
import { RequireRatchet } from '@bitblit/ratchet-common';
|
|
3
|
+
import { StopWatch } from '@bitblit/ratchet-common';
|
|
4
|
+
import { Logger } from '@bitblit/ratchet-common';
|
|
5
|
+
import { StringRatchet } from '@bitblit/ratchet-common';
|
|
6
|
+
import { S3Client } from '@aws-sdk/client-s3';
|
|
7
|
+
export class S3EnvironmentServiceProvider {
|
|
8
|
+
constructor(cfg) {
|
|
9
|
+
this.cfg = cfg;
|
|
10
|
+
RequireRatchet.notNullOrUndefined(cfg);
|
|
11
|
+
RequireRatchet.notNullOrUndefined(cfg.bucketName);
|
|
12
|
+
RequireRatchet.notNullOrUndefined(cfg.region);
|
|
13
|
+
RequireRatchet.true(!!cfg.s3Override || !!cfg.region, 'You must set either region or S3Override');
|
|
14
|
+
const s3 = cfg.s3Override || new S3Client({ region: cfg.region });
|
|
15
|
+
this.ratchet = new S3CacheRatchet(s3, cfg.bucketName);
|
|
16
|
+
}
|
|
17
|
+
async fetchConfig(name) {
|
|
18
|
+
const readPath = StringRatchet.trimToEmpty(this.cfg.pathPrefix) + name + StringRatchet.trimToEmpty(this.cfg.pathSuffix);
|
|
19
|
+
Logger.silly('S3EnvironmentServiceProvider:Request to read config from : %s / %s', this.cfg.bucketName, readPath);
|
|
20
|
+
const sw = new StopWatch();
|
|
21
|
+
const rval = await this.ratchet.fetchCacheFileAsObject(readPath);
|
|
22
|
+
sw.log();
|
|
23
|
+
return rval;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Logger } from '@bitblit/ratchet-common';
|
|
2
|
+
import { GetParameterCommand, SSMClient } from '@aws-sdk/client-ssm';
|
|
3
|
+
import { PromiseRatchet } from '@bitblit/ratchet-common';
|
|
4
|
+
import { RequireRatchet } from '@bitblit/ratchet-common';
|
|
5
|
+
import { ErrorRatchet } from '@bitblit/ratchet-common';
|
|
6
|
+
import { StringRatchet } from '@bitblit/ratchet-common';
|
|
7
|
+
export class SsmEnvironmentServiceProvider {
|
|
8
|
+
constructor(region = 'us-east-1', ssmEncrypted = true) {
|
|
9
|
+
this.region = region;
|
|
10
|
+
this.ssmEncrypted = ssmEncrypted;
|
|
11
|
+
RequireRatchet.notNullOrUndefined(region);
|
|
12
|
+
RequireRatchet.notNullOrUndefined(ssmEncrypted);
|
|
13
|
+
this.ssm = new SSMClient({ region: this.region });
|
|
14
|
+
}
|
|
15
|
+
async fetchConfig(name) {
|
|
16
|
+
Logger.silly('SsmEnvironmentServiceProvider fetch for %s', name);
|
|
17
|
+
const params = {
|
|
18
|
+
Name: name,
|
|
19
|
+
WithDecryption: this.ssmEncrypted,
|
|
20
|
+
};
|
|
21
|
+
let rval = null;
|
|
22
|
+
let toParse = null;
|
|
23
|
+
try {
|
|
24
|
+
const value = await this.ssm.send(new GetParameterCommand(params));
|
|
25
|
+
toParse = StringRatchet.trimToNull(value?.Parameter?.Value);
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
const errCode = err['code'] || '';
|
|
29
|
+
if (errCode.toLowerCase().indexOf('throttlingexception') !== -1) {
|
|
30
|
+
Logger.warn('Throttled while trying to read parameters - waiting 1 second before allowing retry');
|
|
31
|
+
await PromiseRatchet.wait(1000);
|
|
32
|
+
}
|
|
33
|
+
else if (errCode.toLowerCase().indexOf('parameternotfound') !== -1) {
|
|
34
|
+
const errMsg = Logger.warn('AWS could not find parameter %s - are you using the right AWS key?', name);
|
|
35
|
+
throw new Error(errMsg);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
Logger.error('Final environment fetch error (cannot retry) : %s', err, err);
|
|
39
|
+
throw err;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (toParse) {
|
|
43
|
+
try {
|
|
44
|
+
rval = JSON.parse(toParse);
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
Logger.error('Failed to read env - null or invalid JSON : %s : %s', err, toParse, err);
|
|
48
|
+
throw err;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
ErrorRatchet.throwFormattedErr('Could not find system parameter with name : %s in this account', name);
|
|
53
|
+
}
|
|
54
|
+
return rval;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export class DynamoExpiringCodeProvider {
|
|
2
|
+
constructor(tableName, dynamoRatchet) {
|
|
3
|
+
this.tableName = tableName;
|
|
4
|
+
this.dynamoRatchet = dynamoRatchet;
|
|
5
|
+
}
|
|
6
|
+
async checkCode(code, context, deleteOnMatch) {
|
|
7
|
+
const keys = { code: code, context: context };
|
|
8
|
+
const expCode = await this.dynamoRatchet.simpleGet(this.tableName, keys);
|
|
9
|
+
const rval = expCode && expCode.expiresEpochMS > Date.now();
|
|
10
|
+
if (rval && deleteOnMatch) {
|
|
11
|
+
await this.dynamoRatchet.simpleDelete(this.tableName, keys);
|
|
12
|
+
}
|
|
13
|
+
return rval;
|
|
14
|
+
}
|
|
15
|
+
async storeCode(code) {
|
|
16
|
+
const output = await this.dynamoRatchet.simplePut(this.tableName, code);
|
|
17
|
+
return output && output.ConsumedCapacity.CapacityUnits > 0;
|
|
18
|
+
}
|
|
19
|
+
async createTableIfMissing(dtr) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { RequireRatchet } from '@bitblit/ratchet-common';
|
|
2
|
+
import { StringRatchet } from '@bitblit/ratchet-common';
|
|
3
|
+
export class ExpiringCodeRatchet {
|
|
4
|
+
constructor(provider) {
|
|
5
|
+
this.provider = provider;
|
|
6
|
+
}
|
|
7
|
+
static generateCode(params) {
|
|
8
|
+
RequireRatchet.notNullOrUndefined(params, 'params');
|
|
9
|
+
RequireRatchet.notNullOrUndefined(params.context, 'params.context');
|
|
10
|
+
RequireRatchet.notNullOrUndefined(params.length, 'params.length');
|
|
11
|
+
RequireRatchet.notNullOrUndefined(params.alphabet, 'params.alphabet');
|
|
12
|
+
let code = '';
|
|
13
|
+
for (let i = 0; i < params.length; i++) {
|
|
14
|
+
code += params.alphabet.charAt(Math.floor(params.alphabet.length * Math.random()));
|
|
15
|
+
}
|
|
16
|
+
const rval = {
|
|
17
|
+
code: code,
|
|
18
|
+
context: params.context,
|
|
19
|
+
tags: params.tags,
|
|
20
|
+
expiresEpochMS: Date.now() + params.timeToLiveSeconds * 1000,
|
|
21
|
+
};
|
|
22
|
+
return rval;
|
|
23
|
+
}
|
|
24
|
+
async createNewCode(params) {
|
|
25
|
+
const value = ExpiringCodeRatchet.generateCode(params);
|
|
26
|
+
const rval = await this.provider.storeCode(value);
|
|
27
|
+
return rval ? value : null;
|
|
28
|
+
}
|
|
29
|
+
async checkCode(code, context, deleteOnMatch) {
|
|
30
|
+
const rval = await this.provider.checkCode(StringRatchet.trimToEmpty(code), StringRatchet.trimToEmpty(context), deleteOnMatch);
|
|
31
|
+
return rval;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Logger, RequireRatchet } from '@bitblit/ratchet-common';
|
|
2
|
+
export class S3ExpiringCodeProvider {
|
|
3
|
+
constructor(s3CacheRatchet, keyName) {
|
|
4
|
+
this.s3CacheRatchet = s3CacheRatchet;
|
|
5
|
+
this.keyName = keyName;
|
|
6
|
+
RequireRatchet.notNullOrUndefined(s3CacheRatchet, 's3CacheRatchet');
|
|
7
|
+
RequireRatchet.notNullUndefinedOrOnlyWhitespaceString(s3CacheRatchet.getDefaultBucket(), 's3CacheRatchet.defaultBucket');
|
|
8
|
+
RequireRatchet.notNullUndefinedOrOnlyWhitespaceString(keyName, 'keyName');
|
|
9
|
+
}
|
|
10
|
+
async fetchFile() {
|
|
11
|
+
const rval = (await this.s3CacheRatchet.fetchCacheFileAsObject(this.keyName)) || {
|
|
12
|
+
data: [],
|
|
13
|
+
lastModifiedEpochMS: Date.now(),
|
|
14
|
+
};
|
|
15
|
+
return rval;
|
|
16
|
+
}
|
|
17
|
+
async updateFile(vals) {
|
|
18
|
+
const next = {
|
|
19
|
+
data: vals || [],
|
|
20
|
+
lastModifiedEpochMS: Date.now(),
|
|
21
|
+
};
|
|
22
|
+
next.data = next.data.filter((d) => d.expiresEpochMS > Date.now());
|
|
23
|
+
Logger.info('Updating code file to %s codes', next.data.length);
|
|
24
|
+
const rval = await this.s3CacheRatchet.writeObjectToCacheFile(this.keyName, next);
|
|
25
|
+
return rval;
|
|
26
|
+
}
|
|
27
|
+
async checkCode(code, context, deleteOnMatch) {
|
|
28
|
+
const val = await this.fetchFile();
|
|
29
|
+
const rval = val.data.find((d) => d?.code?.toUpperCase() === code?.toUpperCase() && d?.context?.toUpperCase() === context?.toUpperCase());
|
|
30
|
+
if (rval) {
|
|
31
|
+
if (deleteOnMatch || rval.expiresEpochMS < Date.now()) {
|
|
32
|
+
Logger.info('Stripping used/expired code from the database');
|
|
33
|
+
const newData = val.data.filter((d) => d != rval);
|
|
34
|
+
await this.updateFile(newData);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return !!rval && rval.expiresEpochMS > Date.now();
|
|
38
|
+
}
|
|
39
|
+
async storeCode(code) {
|
|
40
|
+
const old = await this.fetchFile();
|
|
41
|
+
old.data.push(code);
|
|
42
|
+
const wrote = await this.updateFile(old.data);
|
|
43
|
+
return !!wrote;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ErrorRatchet, StringRatchet } from '@bitblit/ratchet-common';
|
|
2
|
+
export class AwsCredentialsRatchet {
|
|
3
|
+
constructor() { }
|
|
4
|
+
static applySetProfileEnvironmentalVariable(newProfile) {
|
|
5
|
+
if (!!process.env) {
|
|
6
|
+
if (StringRatchet.trimToNull(newProfile)) {
|
|
7
|
+
process.env['AWS_PROFILE'] = newProfile;
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
ErrorRatchet.throwFormattedErr('Cannot set profile to null/empty string');
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
ErrorRatchet.throwFormattedErr('Cannot set profile - not in a node environment - process missing');
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|