@quiltdata/benchling-webhook 0.5.4-20251102T020826Z → 0.5.4-20251103T180145Z
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/README.md +26 -17
- package/dist/bin/benchling-webhook.d.ts +1 -1
- package/dist/bin/benchling-webhook.d.ts.map +1 -1
- package/dist/bin/benchling-webhook.js +8 -23
- package/dist/bin/benchling-webhook.js.map +1 -1
- package/dist/bin/cdk-dev.js +51 -0
- package/dist/bin/cli.js +8 -22
- package/dist/bin/cli.js.map +1 -1
- package/dist/bin/commands/deploy.d.ts +4 -2
- package/dist/bin/commands/deploy.d.ts.map +1 -1
- package/dist/bin/commands/deploy.js +88 -300
- package/dist/bin/commands/deploy.js.map +1 -1
- package/dist/bin/config-profiles.d.ts +59 -0
- package/dist/bin/config-profiles.d.ts.map +1 -0
- package/dist/bin/config-profiles.js +272 -0
- package/dist/bin/config-profiles.js.map +1 -0
- package/dist/bin/create-secret.d.ts +3 -0
- package/dist/bin/create-secret.d.ts.map +1 -1
- package/dist/bin/create-secret.js +51 -48
- package/dist/bin/create-secret.js.map +1 -1
- package/dist/lib/benchling-auth-validator.d.ts +65 -0
- package/dist/lib/benchling-auth-validator.d.ts.map +1 -0
- package/dist/lib/benchling-auth-validator.js +213 -0
- package/dist/lib/benchling-auth-validator.js.map +1 -0
- package/dist/lib/benchling-webhook-stack.d.ts +5 -23
- package/dist/lib/benchling-webhook-stack.d.ts.map +1 -1
- package/dist/lib/benchling-webhook-stack.js +25 -145
- package/dist/lib/benchling-webhook-stack.js.map +1 -1
- package/dist/lib/config-logger.d.ts +191 -0
- package/dist/lib/config-logger.d.ts.map +1 -0
- package/dist/lib/config-logger.js +372 -0
- package/dist/lib/config-logger.js.map +1 -0
- package/dist/lib/configuration-saver.d.ts +75 -0
- package/dist/lib/configuration-saver.d.ts.map +1 -0
- package/dist/lib/configuration-saver.js +145 -0
- package/dist/lib/configuration-saver.js.map +1 -0
- package/dist/lib/configuration-validator.d.ts +63 -0
- package/dist/lib/configuration-validator.d.ts.map +1 -0
- package/dist/lib/configuration-validator.js +136 -0
- package/dist/lib/configuration-validator.js.map +1 -0
- package/dist/lib/configuration-wizard.d.ts +52 -0
- package/dist/lib/configuration-wizard.d.ts.map +1 -0
- package/dist/lib/configuration-wizard.js +193 -0
- package/dist/lib/configuration-wizard.js.map +1 -0
- package/dist/lib/quilt-config-resolver.d.ts +53 -0
- package/dist/lib/quilt-config-resolver.d.ts.map +1 -0
- package/dist/lib/quilt-config-resolver.js +100 -0
- package/dist/lib/quilt-config-resolver.js.map +1 -0
- package/dist/lib/s3-bucket-validator.d.ts +76 -0
- package/dist/lib/s3-bucket-validator.d.ts.map +1 -0
- package/dist/lib/s3-bucket-validator.js +237 -0
- package/dist/lib/s3-bucket-validator.js.map +1 -0
- package/dist/lib/types/config.d.ts +398 -0
- package/dist/lib/types/config.d.ts.map +1 -0
- package/dist/lib/types/config.js +11 -0
- package/dist/lib/types/config.js.map +1 -0
- package/dist/lib/utils/config-loader.js.map +1 -1
- package/dist/lib/utils/config-resolver.d.ts +26 -26
- package/dist/lib/utils/config-resolver.d.ts.map +1 -1
- package/dist/lib/utils/config-resolver.js +29 -29
- package/dist/lib/utils/config-resolver.js.map +1 -1
- package/dist/lib/utils/config.d.ts +2 -0
- package/dist/lib/utils/config.d.ts.map +1 -1
- package/dist/lib/utils/config.js.map +1 -1
- package/dist/lib/xdg-cli-wrapper.d.ts +113 -0
- package/dist/lib/xdg-cli-wrapper.d.ts.map +1 -0
- package/dist/lib/xdg-cli-wrapper.js +288 -0
- package/dist/lib/xdg-cli-wrapper.js.map +1 -0
- package/dist/lib/xdg-config.d.ts +187 -0
- package/dist/lib/xdg-config.d.ts.map +1 -0
- package/dist/lib/xdg-config.js +562 -0
- package/dist/lib/xdg-config.js.map +1 -0
- package/dist/package.json +38 -26
- package/dist/scripts/config-health-check.d.ts +78 -0
- package/dist/scripts/config-health-check.d.ts.map +1 -0
- package/dist/scripts/config-health-check.js +559 -0
- package/dist/scripts/config-health-check.js.map +1 -0
- package/dist/scripts/infer-quilt-config.d.ts +50 -0
- package/dist/scripts/infer-quilt-config.d.ts.map +1 -0
- package/dist/scripts/infer-quilt-config.js +353 -0
- package/dist/scripts/infer-quilt-config.js.map +1 -0
- package/dist/scripts/install-wizard.d.ts +34 -0
- package/dist/scripts/install-wizard.d.ts.map +1 -0
- package/dist/scripts/install-wizard.js +719 -0
- package/dist/scripts/install-wizard.js.map +1 -0
- package/dist/scripts/sync-secrets.d.ts +63 -0
- package/dist/scripts/sync-secrets.d.ts.map +1 -0
- package/dist/scripts/sync-secrets.js +424 -0
- package/dist/scripts/sync-secrets.js.map +1 -0
- package/env.template +60 -47
- package/package.json +38 -26
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quilt-config-resolver.d.ts","sourceRoot":"","sources":["../../lib/quilt-config-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,qBAAa,mBAAmB;IAC5B;;;;;OAKG;WACiB,OAAO,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;IAoBtF;;;;;OAKG;IACU,iBAAiB,IAAI,OAAO,CAAC,WAAW,CAAC;IAItD;;;;;;OAMG;IACU,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAatE;;;;;OAKG;IACI,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW;CAuBxD"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Quilt Configuration Resolver
|
|
4
|
+
*
|
|
5
|
+
* Automatically infers Quilt configuration from the quilt3 CLI.
|
|
6
|
+
* Extracts catalog URL, S3 bucket, and region information.
|
|
7
|
+
*
|
|
8
|
+
* @module quilt-config-resolver
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.QuiltConfigResolver = void 0;
|
|
12
|
+
const child_process_1 = require("child_process");
|
|
13
|
+
/**
|
|
14
|
+
* Quilt Configuration Resolver
|
|
15
|
+
*
|
|
16
|
+
* Resolves Quilt configuration from the quilt3 CLI or user overrides.
|
|
17
|
+
*/
|
|
18
|
+
class QuiltConfigResolver {
|
|
19
|
+
/**
|
|
20
|
+
* Resolves Quilt configuration with optional manual overrides
|
|
21
|
+
*
|
|
22
|
+
* @param manualConfig - Optional manual configuration overrides
|
|
23
|
+
* @returns Resolved Quilt configuration
|
|
24
|
+
*/
|
|
25
|
+
static async resolve(manualConfig) {
|
|
26
|
+
const resolver = new QuiltConfigResolver();
|
|
27
|
+
// If manual config is provided, return it
|
|
28
|
+
if (manualConfig) {
|
|
29
|
+
return {
|
|
30
|
+
catalogUrl: manualConfig.catalogUrl,
|
|
31
|
+
userBucket: manualConfig.userBucket,
|
|
32
|
+
defaultRegion: manualConfig.defaultRegion,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
// Try to infer from quilt3 CLI
|
|
36
|
+
try {
|
|
37
|
+
return await resolver.resolveFromQuilt3();
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
throw new Error(`Quilt configuration not found: ${error.message}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Resolves configuration from quilt3 CLI
|
|
45
|
+
*
|
|
46
|
+
* @returns Resolved Quilt configuration
|
|
47
|
+
* @throws {Error} If quilt3 is not installed or configured
|
|
48
|
+
*/
|
|
49
|
+
async resolveFromQuilt3() {
|
|
50
|
+
return this.resolveWithCommand("quilt3 config");
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Resolves configuration using a custom command
|
|
54
|
+
*
|
|
55
|
+
* @param command - Command to execute
|
|
56
|
+
* @returns Resolved Quilt configuration
|
|
57
|
+
* @throws {Error} If command fails
|
|
58
|
+
*/
|
|
59
|
+
async resolveWithCommand(command) {
|
|
60
|
+
try {
|
|
61
|
+
const output = (0, child_process_1.execSync)(command, {
|
|
62
|
+
encoding: "utf-8",
|
|
63
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
64
|
+
}).trim();
|
|
65
|
+
return this.parseQuilt3Config(output);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
throw new Error(`Failed to execute command: ${command}. ${error.message}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Parses quilt3 config output
|
|
73
|
+
*
|
|
74
|
+
* @param output - Raw output from quilt3 config command
|
|
75
|
+
* @returns Parsed Quilt configuration
|
|
76
|
+
*/
|
|
77
|
+
parseQuilt3Config(output) {
|
|
78
|
+
if (!output) {
|
|
79
|
+
throw new Error("Empty quilt3 config output");
|
|
80
|
+
}
|
|
81
|
+
// quilt3 config returns the full URL (e.g., https://nightly.quilttest.com)
|
|
82
|
+
// We want just the domain
|
|
83
|
+
let catalogUrl = output.trim();
|
|
84
|
+
// Remove protocol if present
|
|
85
|
+
if (catalogUrl.startsWith("http://") || catalogUrl.startsWith("https://")) {
|
|
86
|
+
try {
|
|
87
|
+
const url = new URL(catalogUrl);
|
|
88
|
+
catalogUrl = url.hostname;
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// If URL parsing fails, use as-is
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
catalogUrl,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
exports.QuiltConfigResolver = QuiltConfigResolver;
|
|
100
|
+
//# sourceMappingURL=quilt-config-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quilt-config-resolver.js","sourceRoot":"","sources":["../../lib/quilt-config-resolver.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAEH,iDAAyC;AAWzC;;;;GAIG;AACH,MAAa,mBAAmB;IAC5B;;;;;OAKG;IACI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,YAAmC;QAC3D,MAAM,QAAQ,GAAG,IAAI,mBAAmB,EAAE,CAAC;QAE3C,0CAA0C;QAC1C,IAAI,YAAY,EAAE,CAAC;YACf,OAAO;gBACH,UAAU,EAAE,YAAY,CAAC,UAAU;gBACnC,UAAU,EAAE,YAAY,CAAC,UAAU;gBACnC,aAAa,EAAE,YAAY,CAAC,aAAa;aAC5C,CAAC;QACN,CAAC;QAED,+BAA+B;QAC/B,IAAI,CAAC;YACD,OAAO,MAAM,QAAQ,CAAC,iBAAiB,EAAE,CAAC;QAC9C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,kCAAmC,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QAClF,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,iBAAiB;QAC1B,OAAO,IAAI,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC;IACpD,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,kBAAkB,CAAC,OAAe;QAC3C,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,IAAA,wBAAQ,EAAC,OAAO,EAAE;gBAC7B,QAAQ,EAAE,OAAO;gBACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;aAClC,CAAC,CAAC,IAAI,EAAE,CAAC;YAEV,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,8BAA8B,OAAO,KAAM,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1F,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACI,iBAAiB,CAAC,MAAc;QACnC,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAClD,CAAC;QAED,2EAA2E;QAC3E,0BAA0B;QAC1B,IAAI,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;QAE/B,6BAA6B;QAC7B,IAAI,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YACxE,IAAI,CAAC;gBACD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;gBAChC,UAAU,GAAG,GAAG,CAAC,QAAQ,CAAC;YAC9B,CAAC;YAAC,MAAM,CAAC;gBACL,kCAAkC;YACtC,CAAC;QACL,CAAC;QAED,OAAO;YACH,UAAU;SACb,CAAC;IACN,CAAC;CACJ;AAtFD,kDAsFC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { S3Client } from "@aws-sdk/client-s3";
|
|
2
|
+
/**
|
|
3
|
+
* S3 bucket configuration
|
|
4
|
+
*/
|
|
5
|
+
export interface S3BucketConfig {
|
|
6
|
+
bucketName: string;
|
|
7
|
+
region: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* S3 bucket validation result
|
|
11
|
+
*/
|
|
12
|
+
export interface S3ValidationResult {
|
|
13
|
+
hasAccess: boolean;
|
|
14
|
+
isConfigured: boolean;
|
|
15
|
+
hasWritePermission?: boolean;
|
|
16
|
+
hasReadPermission?: boolean;
|
|
17
|
+
errors: string[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* S3 bucket access validator
|
|
21
|
+
*
|
|
22
|
+
* Validates S3 bucket access and permissions required for the webhook integration.
|
|
23
|
+
*/
|
|
24
|
+
export declare class S3BucketValidator {
|
|
25
|
+
/**
|
|
26
|
+
* Valid AWS region patterns
|
|
27
|
+
*/
|
|
28
|
+
private static readonly VALID_REGIONS;
|
|
29
|
+
/**
|
|
30
|
+
* Validate S3 bucket access and permissions
|
|
31
|
+
*
|
|
32
|
+
* @param config - S3 bucket configuration
|
|
33
|
+
* @returns Validation result with access status and errors
|
|
34
|
+
*/
|
|
35
|
+
static validate(config: S3BucketConfig): Promise<S3ValidationResult>;
|
|
36
|
+
/**
|
|
37
|
+
* Validate S3 bucket name format
|
|
38
|
+
*
|
|
39
|
+
* @param bucketName - Bucket name to validate
|
|
40
|
+
* @returns True if bucket name is valid
|
|
41
|
+
*/
|
|
42
|
+
static validateBucketName(bucketName: string): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Validate AWS region format
|
|
45
|
+
*
|
|
46
|
+
* @param region - AWS region to validate
|
|
47
|
+
* @returns True if region format is valid
|
|
48
|
+
*/
|
|
49
|
+
static validateRegion(region: string): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Check if S3 bucket exists
|
|
52
|
+
*
|
|
53
|
+
* @param bucketName - Name of the bucket
|
|
54
|
+
* @param region - AWS region
|
|
55
|
+
* @param s3Client - Optional S3 client instance
|
|
56
|
+
* @returns True if bucket exists
|
|
57
|
+
*/
|
|
58
|
+
static checkBucketExists(bucketName: string, region: string, s3Client?: S3Client): Promise<boolean>;
|
|
59
|
+
/**
|
|
60
|
+
* Test write permissions on S3 bucket
|
|
61
|
+
*
|
|
62
|
+
* @param bucketName - Name of the bucket
|
|
63
|
+
* @param s3Client - S3 client instance
|
|
64
|
+
* @returns True if write permission is granted
|
|
65
|
+
*/
|
|
66
|
+
private static testWritePermission;
|
|
67
|
+
/**
|
|
68
|
+
* Test read permissions on S3 bucket
|
|
69
|
+
*
|
|
70
|
+
* @param bucketName - Name of the bucket
|
|
71
|
+
* @param s3Client - S3 client instance
|
|
72
|
+
* @returns True if read permission is granted
|
|
73
|
+
*/
|
|
74
|
+
private static testReadPermission;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=s3-bucket-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3-bucket-validator.d.ts","sourceRoot":"","sources":["../../lib/s3-bucket-validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAA8E,MAAM,oBAAoB,CAAC;AAE1H;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;GAIG;AACH,qBAAa,iBAAiB;IAC1B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAoH;IAEzJ;;;;;OAKG;WACiB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA6FjF;;;;;OAKG;WACW,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAmB7D;;;;;OAKG;WACW,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAQrD;;;;;;;OAOG;WACiB,iBAAiB,CACjC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,QAAQ,GACpB,OAAO,CAAC,OAAO,CAAC;IAiBnB;;;;;;OAMG;mBACkB,mBAAmB;IAgCxC;;;;;;OAMG;mBACkB,kBAAkB;CAgD1C"}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.S3BucketValidator = void 0;
|
|
4
|
+
const client_s3_1 = require("@aws-sdk/client-s3");
|
|
5
|
+
/**
|
|
6
|
+
* S3 bucket access validator
|
|
7
|
+
*
|
|
8
|
+
* Validates S3 bucket access and permissions required for the webhook integration.
|
|
9
|
+
*/
|
|
10
|
+
class S3BucketValidator {
|
|
11
|
+
/**
|
|
12
|
+
* Validate S3 bucket access and permissions
|
|
13
|
+
*
|
|
14
|
+
* @param config - S3 bucket configuration
|
|
15
|
+
* @returns Validation result with access status and errors
|
|
16
|
+
*/
|
|
17
|
+
static async validate(config) {
|
|
18
|
+
const errors = [];
|
|
19
|
+
// Validate bucket name format
|
|
20
|
+
if (!S3BucketValidator.validateBucketName(config.bucketName)) {
|
|
21
|
+
errors.push("Invalid bucket name format");
|
|
22
|
+
return {
|
|
23
|
+
hasAccess: false,
|
|
24
|
+
isConfigured: false,
|
|
25
|
+
errors,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
// Validate region format
|
|
29
|
+
if (!S3BucketValidator.validateRegion(config.region)) {
|
|
30
|
+
errors.push("Invalid AWS region");
|
|
31
|
+
return {
|
|
32
|
+
hasAccess: false,
|
|
33
|
+
isConfigured: false,
|
|
34
|
+
errors,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
// Create S3 client
|
|
38
|
+
const s3Client = new client_s3_1.S3Client({ region: config.region });
|
|
39
|
+
try {
|
|
40
|
+
// Check if bucket exists
|
|
41
|
+
const bucketExists = await S3BucketValidator.checkBucketExists(config.bucketName, config.region, s3Client);
|
|
42
|
+
if (!bucketExists) {
|
|
43
|
+
errors.push("Bucket does not exist");
|
|
44
|
+
return {
|
|
45
|
+
hasAccess: false,
|
|
46
|
+
isConfigured: false,
|
|
47
|
+
errors,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
// Test write permissions
|
|
51
|
+
const hasWritePermission = await S3BucketValidator.testWritePermission(config.bucketName, s3Client);
|
|
52
|
+
if (!hasWritePermission) {
|
|
53
|
+
errors.push("Insufficient write permissions");
|
|
54
|
+
return {
|
|
55
|
+
hasAccess: false,
|
|
56
|
+
isConfigured: false,
|
|
57
|
+
hasWritePermission: false,
|
|
58
|
+
errors,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
// Test read permissions
|
|
62
|
+
const hasReadPermission = await S3BucketValidator.testReadPermission(config.bucketName, s3Client);
|
|
63
|
+
return {
|
|
64
|
+
hasAccess: true,
|
|
65
|
+
isConfigured: true,
|
|
66
|
+
hasWritePermission,
|
|
67
|
+
hasReadPermission,
|
|
68
|
+
errors: [],
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
if (error instanceof Error) {
|
|
73
|
+
const errorName = error.name || "";
|
|
74
|
+
if (errorName === "NoSuchBucket") {
|
|
75
|
+
errors.push("Bucket does not exist");
|
|
76
|
+
}
|
|
77
|
+
else if (errorName === "AccessDenied" || errorName === "Forbidden") {
|
|
78
|
+
errors.push("Insufficient write permissions");
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
errors.push(`Validation error: ${error.message}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
hasAccess: false,
|
|
86
|
+
isConfigured: false,
|
|
87
|
+
errors,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Validate S3 bucket name format
|
|
93
|
+
*
|
|
94
|
+
* @param bucketName - Bucket name to validate
|
|
95
|
+
* @returns True if bucket name is valid
|
|
96
|
+
*/
|
|
97
|
+
static validateBucketName(bucketName) {
|
|
98
|
+
if (!bucketName || bucketName.trim() === "") {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
// S3 bucket naming rules:
|
|
102
|
+
// - 3-63 characters
|
|
103
|
+
// - lowercase letters, numbers, hyphens, dots
|
|
104
|
+
// - must start and end with letter or number
|
|
105
|
+
const bucketRegex = /^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/;
|
|
106
|
+
// Reject names with uppercase (invalid for S3)
|
|
107
|
+
if (bucketName !== bucketName.toLowerCase()) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
return bucketRegex.test(bucketName);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Validate AWS region format
|
|
114
|
+
*
|
|
115
|
+
* @param region - AWS region to validate
|
|
116
|
+
* @returns True if region format is valid
|
|
117
|
+
*/
|
|
118
|
+
static validateRegion(region) {
|
|
119
|
+
if (!region || region.trim() === "") {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
return S3BucketValidator.VALID_REGIONS.test(region);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Check if S3 bucket exists
|
|
126
|
+
*
|
|
127
|
+
* @param bucketName - Name of the bucket
|
|
128
|
+
* @param region - AWS region
|
|
129
|
+
* @param s3Client - Optional S3 client instance
|
|
130
|
+
* @returns True if bucket exists
|
|
131
|
+
*/
|
|
132
|
+
static async checkBucketExists(bucketName, region, s3Client) {
|
|
133
|
+
const client = s3Client || new client_s3_1.S3Client({ region });
|
|
134
|
+
try {
|
|
135
|
+
const command = new client_s3_1.HeadBucketCommand({ Bucket: bucketName });
|
|
136
|
+
await client.send(command);
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
const errorName = error.name || "";
|
|
141
|
+
if (errorName === "NoSuchBucket" || errorName === "NotFound") {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
// For other errors (like AccessDenied), bucket exists but we can't access it
|
|
145
|
+
throw error;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Test write permissions on S3 bucket
|
|
150
|
+
*
|
|
151
|
+
* @param bucketName - Name of the bucket
|
|
152
|
+
* @param s3Client - S3 client instance
|
|
153
|
+
* @returns True if write permission is granted
|
|
154
|
+
*/
|
|
155
|
+
static async testWritePermission(bucketName, s3Client) {
|
|
156
|
+
const testKey = `.benchling-webhook-test-${Date.now()}`;
|
|
157
|
+
try {
|
|
158
|
+
// Attempt to write a test object
|
|
159
|
+
const putCommand = new client_s3_1.PutObjectCommand({
|
|
160
|
+
Bucket: bucketName,
|
|
161
|
+
Key: testKey,
|
|
162
|
+
Body: "test",
|
|
163
|
+
});
|
|
164
|
+
await s3Client.send(putCommand);
|
|
165
|
+
// Clean up test object
|
|
166
|
+
const deleteCommand = new client_s3_1.DeleteObjectCommand({
|
|
167
|
+
Bucket: bucketName,
|
|
168
|
+
Key: testKey,
|
|
169
|
+
});
|
|
170
|
+
await s3Client.send(deleteCommand);
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
const errorName = error.name || "";
|
|
175
|
+
if (errorName === "AccessDenied" || errorName === "Forbidden") {
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
throw error;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Test read permissions on S3 bucket
|
|
183
|
+
*
|
|
184
|
+
* @param bucketName - Name of the bucket
|
|
185
|
+
* @param s3Client - S3 client instance
|
|
186
|
+
* @returns True if read permission is granted
|
|
187
|
+
*/
|
|
188
|
+
static async testReadPermission(bucketName, s3Client) {
|
|
189
|
+
const testKey = `.benchling-webhook-test-${Date.now()}`;
|
|
190
|
+
try {
|
|
191
|
+
// First, write a test object
|
|
192
|
+
const putCommand = new client_s3_1.PutObjectCommand({
|
|
193
|
+
Bucket: bucketName,
|
|
194
|
+
Key: testKey,
|
|
195
|
+
Body: "test",
|
|
196
|
+
});
|
|
197
|
+
await s3Client.send(putCommand);
|
|
198
|
+
// Attempt to read the test object
|
|
199
|
+
const getCommand = new client_s3_1.GetObjectCommand({
|
|
200
|
+
Bucket: bucketName,
|
|
201
|
+
Key: testKey,
|
|
202
|
+
});
|
|
203
|
+
await s3Client.send(getCommand);
|
|
204
|
+
// Clean up test object
|
|
205
|
+
const deleteCommand = new client_s3_1.DeleteObjectCommand({
|
|
206
|
+
Bucket: bucketName,
|
|
207
|
+
Key: testKey,
|
|
208
|
+
});
|
|
209
|
+
await s3Client.send(deleteCommand);
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
const errorName = error.name || "";
|
|
214
|
+
if (errorName === "AccessDenied" || errorName === "Forbidden") {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
// If we can't read, still try to clean up
|
|
218
|
+
try {
|
|
219
|
+
const deleteCommand = new client_s3_1.DeleteObjectCommand({
|
|
220
|
+
Bucket: bucketName,
|
|
221
|
+
Key: testKey,
|
|
222
|
+
});
|
|
223
|
+
await s3Client.send(deleteCommand);
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
// Ignore cleanup errors
|
|
227
|
+
}
|
|
228
|
+
throw error;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
exports.S3BucketValidator = S3BucketValidator;
|
|
233
|
+
/**
|
|
234
|
+
* Valid AWS region patterns
|
|
235
|
+
*/
|
|
236
|
+
S3BucketValidator.VALID_REGIONS = /^(us|eu|ap|sa|ca|me|af|cn|us-gov)-(north|south|east|west|central|northeast|southeast|southwest|northwest)-\d+$/;
|
|
237
|
+
//# sourceMappingURL=s3-bucket-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3-bucket-validator.js","sourceRoot":"","sources":["../../lib/s3-bucket-validator.ts"],"names":[],"mappings":"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"}
|