@cloud-copilot/iam-utils 0.0.1 → 0.0.3
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 +3 -0
- package/dist/cjs/arn.d.ts +26 -0
- package/dist/cjs/arn.d.ts.map +1 -0
- package/dist/cjs/arn.js +67 -0
- package/dist/cjs/arn.js.map +1 -0
- package/dist/cjs/index.d.ts +3 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +12 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/principals.d.ts +37 -0
- package/dist/cjs/principals.d.ts.map +1 -0
- package/dist/cjs/principals.js +62 -0
- package/dist/cjs/principals.js.map +1 -0
- package/dist/esm/arn.d.ts +26 -0
- package/dist/esm/arn.d.ts.map +1 -0
- package/dist/esm/arn.js +63 -0
- package/dist/esm/arn.js.map +1 -0
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +3 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/principals.d.ts +37 -0
- package/dist/esm/principals.d.ts.map +1 -0
- package/{src/principals.ts → dist/esm/principals.js} +19 -26
- package/dist/esm/principals.js.map +1 -0
- package/package.json +12 -2
- package/.github/workflows/guarddog.yml +0 -31
- package/.github/workflows/pr-checks.yml +0 -86
- package/.github/workflows/release.yml +0 -33
- package/.github/workflows/update-dependencies.yml +0 -16
- package/postbuild.sh +0 -11
- package/src/arn.test.ts +0 -126
- package/src/arn.ts +0 -81
- package/src/index.ts +0 -7
- package/src/principals.test.ts +0 -183
- package/tsconfig.cjs.json +0 -11
- package/tsconfig.esm.json +0 -14
- package/tsconfig.json +0 -26
package/README.md
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# iam-utils
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@cloud-copilot/iam-utils) [](LICENSE.txt) [](https://github.com/cloud-copilot/iam-utils/actions/workflows/guarddog.yml) [](https://snyk.io/test/github/cloud-copilot/iam-utils?targetFile=package.json)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface ArnParts {
|
|
2
|
+
partition: string | undefined;
|
|
3
|
+
service: string | undefined;
|
|
4
|
+
region: string | undefined;
|
|
5
|
+
accountId: string | undefined;
|
|
6
|
+
resource: string | undefined;
|
|
7
|
+
resourceType: string | undefined;
|
|
8
|
+
resourcePath: string | undefined;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Split an ARN into its parts
|
|
12
|
+
*
|
|
13
|
+
* @param arn the arn to split
|
|
14
|
+
* @returns the parts of the ARN
|
|
15
|
+
*/
|
|
16
|
+
export declare function splitArnParts(arn: string): ArnParts;
|
|
17
|
+
/**
|
|
18
|
+
* Get the product/id segments of the resource portion of an ARN.
|
|
19
|
+
* The first segment is the product segment and the second segment is the resource id segment.
|
|
20
|
+
* This could be split by a colon or a slash, so it checks for both. It also checks for S3 buckets/objects.
|
|
21
|
+
*
|
|
22
|
+
* @param resource The resource to get the resource segments. Must be an ARN resource.
|
|
23
|
+
* @returns a tuple with the first segment being the product segment (without the separator) and the second segment being the resource id.
|
|
24
|
+
*/
|
|
25
|
+
export declare function getResourceSegments(service: string, accountId: string, region: string, resourceString: string): [string, string];
|
|
26
|
+
//# sourceMappingURL=arn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arn.d.ts","sourceRoot":"","sources":["../../src/arn.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5B,YAAY,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAA;CACjC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAkBnD;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,GACrB,CAAC,MAAM,EAAE,MAAM,CAAC,CA+BlB"}
|
package/dist/cjs/arn.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.splitArnParts = splitArnParts;
|
|
4
|
+
exports.getResourceSegments = getResourceSegments;
|
|
5
|
+
/**
|
|
6
|
+
* Split an ARN into its parts
|
|
7
|
+
*
|
|
8
|
+
* @param arn the arn to split
|
|
9
|
+
* @returns the parts of the ARN
|
|
10
|
+
*/
|
|
11
|
+
function splitArnParts(arn) {
|
|
12
|
+
const parts = arn.split(':');
|
|
13
|
+
const partition = parts.at(1);
|
|
14
|
+
const service = parts.at(2);
|
|
15
|
+
const region = parts.at(3);
|
|
16
|
+
const accountId = parts.at(4);
|
|
17
|
+
const resource = parts.slice(5).join(':');
|
|
18
|
+
const [resourceType, resourcePath] = getResourceSegments(service, accountId, region, resource);
|
|
19
|
+
return {
|
|
20
|
+
partition,
|
|
21
|
+
service,
|
|
22
|
+
region,
|
|
23
|
+
accountId,
|
|
24
|
+
resource,
|
|
25
|
+
resourceType,
|
|
26
|
+
resourcePath
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Get the product/id segments of the resource portion of an ARN.
|
|
31
|
+
* The first segment is the product segment and the second segment is the resource id segment.
|
|
32
|
+
* This could be split by a colon or a slash, so it checks for both. It also checks for S3 buckets/objects.
|
|
33
|
+
*
|
|
34
|
+
* @param resource The resource to get the resource segments. Must be an ARN resource.
|
|
35
|
+
* @returns a tuple with the first segment being the product segment (without the separator) and the second segment being the resource id.
|
|
36
|
+
*/
|
|
37
|
+
function getResourceSegments(service, accountId, region, resourceString) {
|
|
38
|
+
// This is terrible, and I hate it
|
|
39
|
+
if ((service === 's3' && accountId === '' && region === '') ||
|
|
40
|
+
service === 'sns' ||
|
|
41
|
+
service === 'sqs') {
|
|
42
|
+
return ['', resourceString];
|
|
43
|
+
}
|
|
44
|
+
if (resourceString.startsWith('/')) {
|
|
45
|
+
resourceString = resourceString.slice(1);
|
|
46
|
+
}
|
|
47
|
+
const slashIndex = resourceString.indexOf('/');
|
|
48
|
+
const colonIndex = resourceString.indexOf(':');
|
|
49
|
+
let splitIndex = slashIndex;
|
|
50
|
+
if (slashIndex != -1 && colonIndex != -1) {
|
|
51
|
+
splitIndex = Math.min(slashIndex, colonIndex) + 1;
|
|
52
|
+
}
|
|
53
|
+
else if (slashIndex == -1 && colonIndex == -1) {
|
|
54
|
+
splitIndex = resourceString.length + 1;
|
|
55
|
+
}
|
|
56
|
+
else if (colonIndex == -1) {
|
|
57
|
+
splitIndex = slashIndex + 1;
|
|
58
|
+
}
|
|
59
|
+
else if (slashIndex == -1) {
|
|
60
|
+
splitIndex = colonIndex + 1;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
throw new Error(`Unable to split resource ${resourceString}`);
|
|
64
|
+
}
|
|
65
|
+
return [resourceString.slice(0, splitIndex - 1), resourceString.slice(splitIndex)];
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=arn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arn.js","sourceRoot":"","sources":["../../src/arn.ts"],"names":[],"mappings":";;AAgBA,sCAkBC;AAUD,kDAoCC;AAtED;;;;;GAKG;AACH,SAAgB,aAAa,CAAC,GAAW;IACvC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC5B,MAAM,SAAS,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IAC7B,MAAM,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAE,CAAA;IAC5B,MAAM,MAAM,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAE,CAAA;IAC3B,MAAM,SAAS,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAE,CAAA;IAC9B,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACzC,MAAM,CAAC,YAAY,EAAE,YAAY,CAAC,GAAG,mBAAmB,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAA;IAE9F,OAAO;QACL,SAAS;QACT,OAAO;QACP,MAAM;QACN,SAAS;QACT,QAAQ;QACR,YAAY;QACZ,YAAY;KACb,CAAA;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,mBAAmB,CACjC,OAAe,EACf,SAAiB,EACjB,MAAc,EACd,cAAsB;IAEtB,kCAAkC;IAClC,IACE,CAAC,OAAO,KAAK,IAAI,IAAI,SAAS,KAAK,EAAE,IAAI,MAAM,KAAK,EAAE,CAAC;QACvD,OAAO,KAAK,KAAK;QACjB,OAAO,KAAK,KAAK,EACjB,CAAC;QACD,OAAO,CAAC,EAAE,EAAE,cAAc,CAAC,CAAA;IAC7B,CAAC;IAED,IAAI,cAAc,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,cAAc,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAC1C,CAAC;IAED,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAC9C,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAE9C,IAAI,UAAU,GAAG,UAAU,CAAA;IAC3B,IAAI,UAAU,IAAI,CAAC,CAAC,IAAI,UAAU,IAAI,CAAC,CAAC,EAAE,CAAC;QACzC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,CAAA;IACnD,CAAC;SAAM,IAAI,UAAU,IAAI,CAAC,CAAC,IAAI,UAAU,IAAI,CAAC,CAAC,EAAE,CAAC;QAChD,UAAU,GAAG,cAAc,CAAC,MAAM,GAAG,CAAC,CAAA;IACxC,CAAC;SAAM,IAAI,UAAU,IAAI,CAAC,CAAC,EAAE,CAAC;QAC5B,UAAU,GAAG,UAAU,GAAG,CAAC,CAAA;IAC7B,CAAC;SAAM,IAAI,UAAU,IAAI,CAAC,CAAC,EAAE,CAAC;QAC5B,UAAU,GAAG,UAAU,GAAG,CAAC,CAAA;IAC7B,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CAAC,4BAA4B,cAAc,EAAE,CAAC,CAAA;IAC/D,CAAC;IAED,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,CAAC,EAAE,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAA;AACpF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,MAAM,OAAO,CAAA;AACzE,OAAO,EACL,8BAA8B,EAC9B,8BAA8B,EAC9B,gBAAgB,EAChB,YAAY,EACb,MAAM,cAAc,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isIamUserArn = exports.isAssumedRoleArn = exports.convertRoleArnToAssumedRoleArn = exports.convertAssumedRoleArnToRoleArn = exports.splitArnParts = exports.getResourceSegments = void 0;
|
|
4
|
+
var arn_1 = require("./arn");
|
|
5
|
+
Object.defineProperty(exports, "getResourceSegments", { enumerable: true, get: function () { return arn_1.getResourceSegments; } });
|
|
6
|
+
Object.defineProperty(exports, "splitArnParts", { enumerable: true, get: function () { return arn_1.splitArnParts; } });
|
|
7
|
+
var principals_1 = require("./principals");
|
|
8
|
+
Object.defineProperty(exports, "convertAssumedRoleArnToRoleArn", { enumerable: true, get: function () { return principals_1.convertAssumedRoleArnToRoleArn; } });
|
|
9
|
+
Object.defineProperty(exports, "convertRoleArnToAssumedRoleArn", { enumerable: true, get: function () { return principals_1.convertRoleArnToAssumedRoleArn; } });
|
|
10
|
+
Object.defineProperty(exports, "isAssumedRoleArn", { enumerable: true, get: function () { return principals_1.isAssumedRoleArn; } });
|
|
11
|
+
Object.defineProperty(exports, "isIamUserArn", { enumerable: true, get: function () { return principals_1.isIamUserArn; } });
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,6BAAyE;AAAhE,0GAAA,mBAAmB,OAAA;AAAE,oGAAA,aAAa,OAAA;AAC3C,2CAKqB;AAJnB,4HAAA,8BAA8B,OAAA;AAC9B,4HAAA,8BAA8B,OAAA;AAC9B,8GAAA,gBAAgB,OAAA;AAChB,0GAAA,YAAY,OAAA"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transform an assumed role session ARN into a role ARN
|
|
3
|
+
*
|
|
4
|
+
* @param assumedRoleArn the assumed role session ARN
|
|
5
|
+
* @returns the role ARN for the assumed role session
|
|
6
|
+
*/
|
|
7
|
+
export declare function convertAssumedRoleArnToRoleArn(assumedRoleArn: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Create an assumed role ARN from a role ARN and a session name
|
|
10
|
+
*
|
|
11
|
+
* @param roleArn the role ARN to create an assumed role ARN from
|
|
12
|
+
* @param sessionName the session name to use
|
|
13
|
+
* @returns the assumed role ARN
|
|
14
|
+
*/
|
|
15
|
+
export declare function convertRoleArnToAssumedRoleArn(roleArn: string, sessionName: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Tests if a principal string is an assumed role ARN
|
|
18
|
+
*
|
|
19
|
+
* @param principal the principal string to test
|
|
20
|
+
* @returns true if the principal is an assumed role ARN, false otherwise
|
|
21
|
+
*/
|
|
22
|
+
export declare function isAssumedRoleArn(principal: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Test if a principal string is an IAM user ARN
|
|
25
|
+
*
|
|
26
|
+
* @param principal the principal string to test
|
|
27
|
+
* @returns true if the principal is an IAM user ARN, false otherwise
|
|
28
|
+
*/
|
|
29
|
+
export declare function isIamUserArn(principal: string): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Test if a principal string is a federated user ARN
|
|
32
|
+
*
|
|
33
|
+
* @param principal the principal string to test
|
|
34
|
+
* @returns true if the principal is a federated user ARN, false otherwise
|
|
35
|
+
*/
|
|
36
|
+
export declare function isFederatedUserArn(principal: string): boolean;
|
|
37
|
+
//# sourceMappingURL=principals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"principals.d.ts","sourceRoot":"","sources":["../../src/principals.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAI7E;AAED;;;;;;GAMG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAI3F;AAID;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE3D;AAID;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAEvD;AAID;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE7D"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.convertAssumedRoleArnToRoleArn = convertAssumedRoleArnToRoleArn;
|
|
4
|
+
exports.convertRoleArnToAssumedRoleArn = convertRoleArnToAssumedRoleArn;
|
|
5
|
+
exports.isAssumedRoleArn = isAssumedRoleArn;
|
|
6
|
+
exports.isIamUserArn = isIamUserArn;
|
|
7
|
+
exports.isFederatedUserArn = isFederatedUserArn;
|
|
8
|
+
const arn_js_1 = require("./arn.js");
|
|
9
|
+
/**
|
|
10
|
+
* Transform an assumed role session ARN into a role ARN
|
|
11
|
+
*
|
|
12
|
+
* @param assumedRoleArn the assumed role session ARN
|
|
13
|
+
* @returns the role ARN for the assumed role session
|
|
14
|
+
*/
|
|
15
|
+
function convertAssumedRoleArnToRoleArn(assumedRoleArn) {
|
|
16
|
+
const arnParts = (0, arn_js_1.splitArnParts)(assumedRoleArn);
|
|
17
|
+
const rolePathAndName = arnParts.resourcePath?.split('/').slice(0, -1).join('/');
|
|
18
|
+
return `arn:${arnParts.partition}:iam::${arnParts.accountId}:role/${rolePathAndName}`;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Create an assumed role ARN from a role ARN and a session name
|
|
22
|
+
*
|
|
23
|
+
* @param roleArn the role ARN to create an assumed role ARN from
|
|
24
|
+
* @param sessionName the session name to use
|
|
25
|
+
* @returns the assumed role ARN
|
|
26
|
+
*/
|
|
27
|
+
function convertRoleArnToAssumedRoleArn(roleArn, sessionName) {
|
|
28
|
+
const arnParts = (0, arn_js_1.splitArnParts)(roleArn);
|
|
29
|
+
const rolePathAndName = arnParts.resourcePath;
|
|
30
|
+
return `arn:${arnParts.partition}:sts::${arnParts.accountId}:assumed-role/${rolePathAndName}/${sessionName}`;
|
|
31
|
+
}
|
|
32
|
+
const assumedRoleArnRegex = /^arn:[a-zA-Z\-]+:sts::\d{12}:assumed-role\/.*$/;
|
|
33
|
+
/**
|
|
34
|
+
* Tests if a principal string is an assumed role ARN
|
|
35
|
+
*
|
|
36
|
+
* @param principal the principal string to test
|
|
37
|
+
* @returns true if the principal is an assumed role ARN, false otherwise
|
|
38
|
+
*/
|
|
39
|
+
function isAssumedRoleArn(principal) {
|
|
40
|
+
return assumedRoleArnRegex.test(principal);
|
|
41
|
+
}
|
|
42
|
+
const userArnRegex = /^arn:[a-zA-Z\-]+:iam::\d{12}:user\/.*$/;
|
|
43
|
+
/**
|
|
44
|
+
* Test if a principal string is an IAM user ARN
|
|
45
|
+
*
|
|
46
|
+
* @param principal the principal string to test
|
|
47
|
+
* @returns true if the principal is an IAM user ARN, false otherwise
|
|
48
|
+
*/
|
|
49
|
+
function isIamUserArn(principal) {
|
|
50
|
+
return userArnRegex.test(principal);
|
|
51
|
+
}
|
|
52
|
+
const federatedUserArnRegex = /^arn:[a-zA-Z\-]+:sts::\d{12}:federated-user\/.*$/;
|
|
53
|
+
/**
|
|
54
|
+
* Test if a principal string is a federated user ARN
|
|
55
|
+
*
|
|
56
|
+
* @param principal the principal string to test
|
|
57
|
+
* @returns true if the principal is a federated user ARN, false otherwise
|
|
58
|
+
*/
|
|
59
|
+
function isFederatedUserArn(principal) {
|
|
60
|
+
return federatedUserArnRegex.test(principal);
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=principals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"principals.js","sourceRoot":"","sources":["../../src/principals.ts"],"names":[],"mappings":";;AAQA,wEAIC;AASD,wEAIC;AAUD,4CAEC;AAUD,oCAEC;AAUD,gDAEC;AA7DD,qCAAwC;AAExC;;;;;GAKG;AACH,SAAgB,8BAA8B,CAAC,cAAsB;IACnE,MAAM,QAAQ,GAAG,IAAA,sBAAa,EAAC,cAAc,CAAC,CAAA;IAC9C,MAAM,eAAe,GAAG,QAAQ,CAAC,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAChF,OAAO,OAAO,QAAQ,CAAC,SAAS,SAAS,QAAQ,CAAC,SAAS,SAAS,eAAe,EAAE,CAAA;AACvF,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,8BAA8B,CAAC,OAAe,EAAE,WAAmB;IACjF,MAAM,QAAQ,GAAG,IAAA,sBAAa,EAAC,OAAO,CAAC,CAAA;IACvC,MAAM,eAAe,GAAG,QAAQ,CAAC,YAAY,CAAA;IAC7C,OAAO,OAAO,QAAQ,CAAC,SAAS,SAAS,QAAQ,CAAC,SAAS,iBAAiB,eAAe,IAAI,WAAW,EAAE,CAAA;AAC9G,CAAC;AAED,MAAM,mBAAmB,GAAG,gDAAgD,CAAA;AAE5E;;;;;GAKG;AACH,SAAgB,gBAAgB,CAAC,SAAiB;IAChD,OAAO,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;AAC5C,CAAC;AAED,MAAM,YAAY,GAAG,wCAAwC,CAAA;AAE7D;;;;;GAKG;AACH,SAAgB,YAAY,CAAC,SAAiB;IAC5C,OAAO,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;AACrC,CAAC;AAED,MAAM,qBAAqB,GAAG,kDAAkD,CAAA;AAEhF;;;;;GAKG;AACH,SAAgB,kBAAkB,CAAC,SAAiB;IAClD,OAAO,qBAAqB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;AAC9C,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface ArnParts {
|
|
2
|
+
partition: string | undefined;
|
|
3
|
+
service: string | undefined;
|
|
4
|
+
region: string | undefined;
|
|
5
|
+
accountId: string | undefined;
|
|
6
|
+
resource: string | undefined;
|
|
7
|
+
resourceType: string | undefined;
|
|
8
|
+
resourcePath: string | undefined;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Split an ARN into its parts
|
|
12
|
+
*
|
|
13
|
+
* @param arn the arn to split
|
|
14
|
+
* @returns the parts of the ARN
|
|
15
|
+
*/
|
|
16
|
+
export declare function splitArnParts(arn: string): ArnParts;
|
|
17
|
+
/**
|
|
18
|
+
* Get the product/id segments of the resource portion of an ARN.
|
|
19
|
+
* The first segment is the product segment and the second segment is the resource id segment.
|
|
20
|
+
* This could be split by a colon or a slash, so it checks for both. It also checks for S3 buckets/objects.
|
|
21
|
+
*
|
|
22
|
+
* @param resource The resource to get the resource segments. Must be an ARN resource.
|
|
23
|
+
* @returns a tuple with the first segment being the product segment (without the separator) and the second segment being the resource id.
|
|
24
|
+
*/
|
|
25
|
+
export declare function getResourceSegments(service: string, accountId: string, region: string, resourceString: string): [string, string];
|
|
26
|
+
//# sourceMappingURL=arn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arn.d.ts","sourceRoot":"","sources":["../../src/arn.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5B,YAAY,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAA;CACjC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAkBnD;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,GACrB,CAAC,MAAM,EAAE,MAAM,CAAC,CA+BlB"}
|
package/dist/esm/arn.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Split an ARN into its parts
|
|
3
|
+
*
|
|
4
|
+
* @param arn the arn to split
|
|
5
|
+
* @returns the parts of the ARN
|
|
6
|
+
*/
|
|
7
|
+
export function splitArnParts(arn) {
|
|
8
|
+
const parts = arn.split(':');
|
|
9
|
+
const partition = parts.at(1);
|
|
10
|
+
const service = parts.at(2);
|
|
11
|
+
const region = parts.at(3);
|
|
12
|
+
const accountId = parts.at(4);
|
|
13
|
+
const resource = parts.slice(5).join(':');
|
|
14
|
+
const [resourceType, resourcePath] = getResourceSegments(service, accountId, region, resource);
|
|
15
|
+
return {
|
|
16
|
+
partition,
|
|
17
|
+
service,
|
|
18
|
+
region,
|
|
19
|
+
accountId,
|
|
20
|
+
resource,
|
|
21
|
+
resourceType,
|
|
22
|
+
resourcePath
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get the product/id segments of the resource portion of an ARN.
|
|
27
|
+
* The first segment is the product segment and the second segment is the resource id segment.
|
|
28
|
+
* This could be split by a colon or a slash, so it checks for both. It also checks for S3 buckets/objects.
|
|
29
|
+
*
|
|
30
|
+
* @param resource The resource to get the resource segments. Must be an ARN resource.
|
|
31
|
+
* @returns a tuple with the first segment being the product segment (without the separator) and the second segment being the resource id.
|
|
32
|
+
*/
|
|
33
|
+
export function getResourceSegments(service, accountId, region, resourceString) {
|
|
34
|
+
// This is terrible, and I hate it
|
|
35
|
+
if ((service === 's3' && accountId === '' && region === '') ||
|
|
36
|
+
service === 'sns' ||
|
|
37
|
+
service === 'sqs') {
|
|
38
|
+
return ['', resourceString];
|
|
39
|
+
}
|
|
40
|
+
if (resourceString.startsWith('/')) {
|
|
41
|
+
resourceString = resourceString.slice(1);
|
|
42
|
+
}
|
|
43
|
+
const slashIndex = resourceString.indexOf('/');
|
|
44
|
+
const colonIndex = resourceString.indexOf(':');
|
|
45
|
+
let splitIndex = slashIndex;
|
|
46
|
+
if (slashIndex != -1 && colonIndex != -1) {
|
|
47
|
+
splitIndex = Math.min(slashIndex, colonIndex) + 1;
|
|
48
|
+
}
|
|
49
|
+
else if (slashIndex == -1 && colonIndex == -1) {
|
|
50
|
+
splitIndex = resourceString.length + 1;
|
|
51
|
+
}
|
|
52
|
+
else if (colonIndex == -1) {
|
|
53
|
+
splitIndex = slashIndex + 1;
|
|
54
|
+
}
|
|
55
|
+
else if (slashIndex == -1) {
|
|
56
|
+
splitIndex = colonIndex + 1;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
throw new Error(`Unable to split resource ${resourceString}`);
|
|
60
|
+
}
|
|
61
|
+
return [resourceString.slice(0, splitIndex - 1), resourceString.slice(splitIndex)];
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=arn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arn.js","sourceRoot":"","sources":["../../src/arn.ts"],"names":[],"mappings":"AAUA;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC5B,MAAM,SAAS,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IAC7B,MAAM,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAE,CAAA;IAC5B,MAAM,MAAM,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAE,CAAA;IAC3B,MAAM,SAAS,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAE,CAAA;IAC9B,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACzC,MAAM,CAAC,YAAY,EAAE,YAAY,CAAC,GAAG,mBAAmB,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAA;IAE9F,OAAO;QACL,SAAS;QACT,OAAO;QACP,MAAM;QACN,SAAS;QACT,QAAQ;QACR,YAAY;QACZ,YAAY;KACb,CAAA;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAAe,EACf,SAAiB,EACjB,MAAc,EACd,cAAsB;IAEtB,kCAAkC;IAClC,IACE,CAAC,OAAO,KAAK,IAAI,IAAI,SAAS,KAAK,EAAE,IAAI,MAAM,KAAK,EAAE,CAAC;QACvD,OAAO,KAAK,KAAK;QACjB,OAAO,KAAK,KAAK,EACjB,CAAC;QACD,OAAO,CAAC,EAAE,EAAE,cAAc,CAAC,CAAA;IAC7B,CAAC;IAED,IAAI,cAAc,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,cAAc,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAC1C,CAAC;IAED,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAC9C,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAE9C,IAAI,UAAU,GAAG,UAAU,CAAA;IAC3B,IAAI,UAAU,IAAI,CAAC,CAAC,IAAI,UAAU,IAAI,CAAC,CAAC,EAAE,CAAC;QACzC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,CAAA;IACnD,CAAC;SAAM,IAAI,UAAU,IAAI,CAAC,CAAC,IAAI,UAAU,IAAI,CAAC,CAAC,EAAE,CAAC;QAChD,UAAU,GAAG,cAAc,CAAC,MAAM,GAAG,CAAC,CAAA;IACxC,CAAC;SAAM,IAAI,UAAU,IAAI,CAAC,CAAC,EAAE,CAAC;QAC5B,UAAU,GAAG,UAAU,GAAG,CAAC,CAAA;IAC7B,CAAC;SAAM,IAAI,UAAU,IAAI,CAAC,CAAC,EAAE,CAAC;QAC5B,UAAU,GAAG,UAAU,GAAG,CAAC,CAAA;IAC7B,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CAAC,4BAA4B,cAAc,EAAE,CAAC,CAAA;IAC/D,CAAC;IAED,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,CAAC,EAAE,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAA;AACpF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,MAAM,OAAO,CAAA;AACzE,OAAO,EACL,8BAA8B,EAC9B,8BAA8B,EAC9B,gBAAgB,EAChB,YAAY,EACb,MAAM,cAAc,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAiB,MAAM,OAAO,CAAA;AACzE,OAAO,EACL,8BAA8B,EAC9B,8BAA8B,EAC9B,gBAAgB,EAChB,YAAY,EACb,MAAM,cAAc,CAAA"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transform an assumed role session ARN into a role ARN
|
|
3
|
+
*
|
|
4
|
+
* @param assumedRoleArn the assumed role session ARN
|
|
5
|
+
* @returns the role ARN for the assumed role session
|
|
6
|
+
*/
|
|
7
|
+
export declare function convertAssumedRoleArnToRoleArn(assumedRoleArn: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Create an assumed role ARN from a role ARN and a session name
|
|
10
|
+
*
|
|
11
|
+
* @param roleArn the role ARN to create an assumed role ARN from
|
|
12
|
+
* @param sessionName the session name to use
|
|
13
|
+
* @returns the assumed role ARN
|
|
14
|
+
*/
|
|
15
|
+
export declare function convertRoleArnToAssumedRoleArn(roleArn: string, sessionName: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Tests if a principal string is an assumed role ARN
|
|
18
|
+
*
|
|
19
|
+
* @param principal the principal string to test
|
|
20
|
+
* @returns true if the principal is an assumed role ARN, false otherwise
|
|
21
|
+
*/
|
|
22
|
+
export declare function isAssumedRoleArn(principal: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Test if a principal string is an IAM user ARN
|
|
25
|
+
*
|
|
26
|
+
* @param principal the principal string to test
|
|
27
|
+
* @returns true if the principal is an IAM user ARN, false otherwise
|
|
28
|
+
*/
|
|
29
|
+
export declare function isIamUserArn(principal: string): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Test if a principal string is a federated user ARN
|
|
32
|
+
*
|
|
33
|
+
* @param principal the principal string to test
|
|
34
|
+
* @returns true if the principal is a federated user ARN, false otherwise
|
|
35
|
+
*/
|
|
36
|
+
export declare function isFederatedUserArn(principal: string): boolean;
|
|
37
|
+
//# sourceMappingURL=principals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"principals.d.ts","sourceRoot":"","sources":["../../src/principals.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAI7E;AAED;;;;;;GAMG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAI3F;AAID;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE3D;AAID;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAEvD;AAID;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE7D"}
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import { splitArnParts } from './arn.js'
|
|
2
|
-
|
|
1
|
+
import { splitArnParts } from './arn.js';
|
|
3
2
|
/**
|
|
4
3
|
* Transform an assumed role session ARN into a role ARN
|
|
5
4
|
*
|
|
6
5
|
* @param assumedRoleArn the assumed role session ARN
|
|
7
6
|
* @returns the role ARN for the assumed role session
|
|
8
7
|
*/
|
|
9
|
-
export function convertAssumedRoleArnToRoleArn(assumedRoleArn
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
export function convertAssumedRoleArnToRoleArn(assumedRoleArn) {
|
|
9
|
+
const arnParts = splitArnParts(assumedRoleArn);
|
|
10
|
+
const rolePathAndName = arnParts.resourcePath?.split('/').slice(0, -1).join('/');
|
|
11
|
+
return `arn:${arnParts.partition}:iam::${arnParts.accountId}:role/${rolePathAndName}`;
|
|
13
12
|
}
|
|
14
|
-
|
|
15
13
|
/**
|
|
16
14
|
* Create an assumed role ARN from a role ARN and a session name
|
|
17
15
|
*
|
|
@@ -19,44 +17,39 @@ export function convertAssumedRoleArnToRoleArn(assumedRoleArn: string): string {
|
|
|
19
17
|
* @param sessionName the session name to use
|
|
20
18
|
* @returns the assumed role ARN
|
|
21
19
|
*/
|
|
22
|
-
export function convertRoleArnToAssumedRoleArn(roleArn
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
export function convertRoleArnToAssumedRoleArn(roleArn, sessionName) {
|
|
21
|
+
const arnParts = splitArnParts(roleArn);
|
|
22
|
+
const rolePathAndName = arnParts.resourcePath;
|
|
23
|
+
return `arn:${arnParts.partition}:sts::${arnParts.accountId}:assumed-role/${rolePathAndName}/${sessionName}`;
|
|
26
24
|
}
|
|
27
|
-
|
|
28
|
-
const assumedRoleArnRegex = /^arn:[a-zA-Z\-]+:sts::\d{12}:assumed-role\/.*$/
|
|
29
|
-
|
|
25
|
+
const assumedRoleArnRegex = /^arn:[a-zA-Z\-]+:sts::\d{12}:assumed-role\/.*$/;
|
|
30
26
|
/**
|
|
31
27
|
* Tests if a principal string is an assumed role ARN
|
|
32
28
|
*
|
|
33
29
|
* @param principal the principal string to test
|
|
34
30
|
* @returns true if the principal is an assumed role ARN, false otherwise
|
|
35
31
|
*/
|
|
36
|
-
export function isAssumedRoleArn(principal
|
|
37
|
-
|
|
32
|
+
export function isAssumedRoleArn(principal) {
|
|
33
|
+
return assumedRoleArnRegex.test(principal);
|
|
38
34
|
}
|
|
39
|
-
|
|
40
|
-
const userArnRegex = /^arn:[a-zA-Z\-]+:iam::\d{12}:user\/.*$/
|
|
41
|
-
|
|
35
|
+
const userArnRegex = /^arn:[a-zA-Z\-]+:iam::\d{12}:user\/.*$/;
|
|
42
36
|
/**
|
|
43
37
|
* Test if a principal string is an IAM user ARN
|
|
44
38
|
*
|
|
45
39
|
* @param principal the principal string to test
|
|
46
40
|
* @returns true if the principal is an IAM user ARN, false otherwise
|
|
47
41
|
*/
|
|
48
|
-
export function isIamUserArn(principal
|
|
49
|
-
|
|
42
|
+
export function isIamUserArn(principal) {
|
|
43
|
+
return userArnRegex.test(principal);
|
|
50
44
|
}
|
|
51
|
-
|
|
52
|
-
const federatedUserArnRegex = /^arn:[a-zA-Z\-]+:sts::\d{12}:federated-user\/.*$/
|
|
53
|
-
|
|
45
|
+
const federatedUserArnRegex = /^arn:[a-zA-Z\-]+:sts::\d{12}:federated-user\/.*$/;
|
|
54
46
|
/**
|
|
55
47
|
* Test if a principal string is a federated user ARN
|
|
56
48
|
*
|
|
57
49
|
* @param principal the principal string to test
|
|
58
50
|
* @returns true if the principal is a federated user ARN, false otherwise
|
|
59
51
|
*/
|
|
60
|
-
export function isFederatedUserArn(principal
|
|
61
|
-
|
|
52
|
+
export function isFederatedUserArn(principal) {
|
|
53
|
+
return federatedUserArnRegex.test(principal);
|
|
62
54
|
}
|
|
55
|
+
//# sourceMappingURL=principals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"principals.js","sourceRoot":"","sources":["../../src/principals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC;;;;;GAKG;AACH,MAAM,UAAU,8BAA8B,CAAC,cAAsB;IACnE,MAAM,QAAQ,GAAG,aAAa,CAAC,cAAc,CAAC,CAAA;IAC9C,MAAM,eAAe,GAAG,QAAQ,CAAC,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAChF,OAAO,OAAO,QAAQ,CAAC,SAAS,SAAS,QAAQ,CAAC,SAAS,SAAS,eAAe,EAAE,CAAA;AACvF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,8BAA8B,CAAC,OAAe,EAAE,WAAmB;IACjF,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;IACvC,MAAM,eAAe,GAAG,QAAQ,CAAC,YAAY,CAAA;IAC7C,OAAO,OAAO,QAAQ,CAAC,SAAS,SAAS,QAAQ,CAAC,SAAS,iBAAiB,eAAe,IAAI,WAAW,EAAE,CAAA;AAC9G,CAAC;AAED,MAAM,mBAAmB,GAAG,gDAAgD,CAAA;AAE5E;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAiB;IAChD,OAAO,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;AAC5C,CAAC;AAED,MAAM,YAAY,GAAG,wCAAwC,CAAA;AAE7D;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,SAAiB;IAC5C,OAAO,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;AACrC,CAAC;AAED,MAAM,qBAAqB,GAAG,kDAAkD,CAAA;AAEhF;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,SAAiB;IAClD,OAAO,qBAAqB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;AAC9C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloud-copilot/iam-utils",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "",
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "Various utilities for working with AWS IAM information",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"import": "./dist/esm/index.js",
|
|
8
|
+
"require": "./dist/cjs/index.js"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist/**/*"
|
|
13
|
+
],
|
|
14
|
+
"types": "dist/cjs/index.d.ts",
|
|
5
15
|
"keywords": [
|
|
6
16
|
"aws",
|
|
7
17
|
"iam",
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
name: GuardDog
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- main
|
|
7
|
-
workflow_dispatch:
|
|
8
|
-
|
|
9
|
-
permissions:
|
|
10
|
-
contents: read
|
|
11
|
-
|
|
12
|
-
jobs:
|
|
13
|
-
guarddog:
|
|
14
|
-
permissions:
|
|
15
|
-
contents: read
|
|
16
|
-
name: Scan Dependencies and Source Code
|
|
17
|
-
runs-on: ubuntu-latest
|
|
18
|
-
|
|
19
|
-
steps:
|
|
20
|
-
- uses: actions/checkout@v4
|
|
21
|
-
|
|
22
|
-
- name: Set up Python
|
|
23
|
-
uses: actions/setup-python@v5
|
|
24
|
-
with:
|
|
25
|
-
python-version: '3.10'
|
|
26
|
-
|
|
27
|
-
- name: Install GuardDog
|
|
28
|
-
run: pip install guarddog
|
|
29
|
-
|
|
30
|
-
- run: guarddog npm scan src/ --exit-non-zero-on-finding
|
|
31
|
-
- run: guarddog npm verify package.json --exclude-rules empty_information --exit-non-zero-on-finding
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
name: 'Lint PR'
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
pull_request_target:
|
|
5
|
-
types:
|
|
6
|
-
- opened
|
|
7
|
-
- edited
|
|
8
|
-
- synchronize
|
|
9
|
-
- reopened
|
|
10
|
-
|
|
11
|
-
permissions:
|
|
12
|
-
contents: read
|
|
13
|
-
|
|
14
|
-
jobs:
|
|
15
|
-
main:
|
|
16
|
-
name: Validate PR title
|
|
17
|
-
runs-on: ubuntu-latest
|
|
18
|
-
steps:
|
|
19
|
-
- uses: amannn/action-semantic-pull-request@v5
|
|
20
|
-
env:
|
|
21
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
22
|
-
|
|
23
|
-
lint:
|
|
24
|
-
name: Code Formatting Check
|
|
25
|
-
runs-on: ubuntu-latest
|
|
26
|
-
steps:
|
|
27
|
-
- name: Check out the repository
|
|
28
|
-
uses: actions/checkout@v4
|
|
29
|
-
with:
|
|
30
|
-
ref: ${{ github.event.pull_request.head.sha }}
|
|
31
|
-
|
|
32
|
-
- name: Set up Node
|
|
33
|
-
uses: actions/setup-node@v4
|
|
34
|
-
with:
|
|
35
|
-
node-version: '22'
|
|
36
|
-
|
|
37
|
-
- name: Install dependencies
|
|
38
|
-
run: npm ci
|
|
39
|
-
|
|
40
|
-
- name: Check Code Formatting
|
|
41
|
-
run: npm run format-check
|
|
42
|
-
|
|
43
|
-
test:
|
|
44
|
-
name: Build and Test
|
|
45
|
-
runs-on: ubuntu-latest
|
|
46
|
-
steps:
|
|
47
|
-
- name: Check out the repository
|
|
48
|
-
uses: actions/checkout@v4
|
|
49
|
-
with:
|
|
50
|
-
ref: ${{ github.event.pull_request.head.sha }}
|
|
51
|
-
|
|
52
|
-
- name: Set up Node
|
|
53
|
-
uses: actions/setup-node@v4
|
|
54
|
-
with:
|
|
55
|
-
node-version: '22'
|
|
56
|
-
|
|
57
|
-
- name: Install dependencies
|
|
58
|
-
run: npm ci
|
|
59
|
-
|
|
60
|
-
- name: Build
|
|
61
|
-
run: npm run build
|
|
62
|
-
|
|
63
|
-
- name: Check Tests
|
|
64
|
-
run: npm test
|
|
65
|
-
|
|
66
|
-
guarddog:
|
|
67
|
-
permissions:
|
|
68
|
-
contents: read
|
|
69
|
-
name: GuardDog Check
|
|
70
|
-
runs-on: ubuntu-latest
|
|
71
|
-
|
|
72
|
-
steps:
|
|
73
|
-
- name: Check out the repository
|
|
74
|
-
uses: actions/checkout@v4
|
|
75
|
-
with:
|
|
76
|
-
ref: ${{ github.event.pull_request.head.sha }}
|
|
77
|
-
|
|
78
|
-
- name: Set up Python
|
|
79
|
-
uses: actions/setup-python@v5
|
|
80
|
-
with:
|
|
81
|
-
python-version: '3.10'
|
|
82
|
-
|
|
83
|
-
- name: Install GuardDog
|
|
84
|
-
run: pip install guarddog
|
|
85
|
-
|
|
86
|
-
- run: guarddog npm scan src/ --exit-non-zero-on-finding
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
name: Release
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- main
|
|
7
|
-
workflow_dispatch:
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
release:
|
|
11
|
-
runs-on: ubuntu-latest
|
|
12
|
-
permissions:
|
|
13
|
-
contents: write
|
|
14
|
-
issues: write
|
|
15
|
-
steps:
|
|
16
|
-
- name: Check out
|
|
17
|
-
uses: actions/checkout@v4
|
|
18
|
-
|
|
19
|
-
- name: Set up Node
|
|
20
|
-
uses: actions/setup-node@v4
|
|
21
|
-
with:
|
|
22
|
-
node-version: '22'
|
|
23
|
-
|
|
24
|
-
- name: Run semantic-release
|
|
25
|
-
env:
|
|
26
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
27
|
-
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
28
|
-
run: |
|
|
29
|
-
npm ci
|
|
30
|
-
npm run format-check
|
|
31
|
-
npm run build
|
|
32
|
-
npm run test
|
|
33
|
-
npx semantic-release
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
name: Update Dependencies
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
schedule:
|
|
5
|
-
- cron: '0 12 * * 6' # Every Saturday at 12:00 PM UTC
|
|
6
|
-
workflow_dispatch:
|
|
7
|
-
|
|
8
|
-
jobs:
|
|
9
|
-
update-dependencies:
|
|
10
|
-
runs-on: ubuntu-latest
|
|
11
|
-
permissions:
|
|
12
|
-
contents: write # Push branches
|
|
13
|
-
pull-requests: write # Create PRs
|
|
14
|
-
steps:
|
|
15
|
-
- name: Run dependency update
|
|
16
|
-
uses: cloud-copilot/update-dependencies@main
|
package/postbuild.sh
DELETED
package/src/arn.test.ts
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import { ArnParts, splitArnParts } from './arn.js'
|
|
3
|
-
|
|
4
|
-
const splitArnPartsTests: {
|
|
5
|
-
name: string
|
|
6
|
-
arn: string
|
|
7
|
-
expected: ArnParts
|
|
8
|
-
only?: boolean
|
|
9
|
-
}[] = [
|
|
10
|
-
{
|
|
11
|
-
name: 'should split a full ARN',
|
|
12
|
-
arn: 'arn:aws:iam::123456789012:user/Development/user1',
|
|
13
|
-
expected: {
|
|
14
|
-
partition: 'aws',
|
|
15
|
-
service: 'iam',
|
|
16
|
-
region: '',
|
|
17
|
-
accountId: '123456789012',
|
|
18
|
-
resource: 'user/Development/user1',
|
|
19
|
-
resourceType: 'user',
|
|
20
|
-
resourcePath: 'Development/user1'
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
name: 'should split an S3 bucket ARN',
|
|
25
|
-
arn: 'arn:aws:s3:::my_corporate_bucket',
|
|
26
|
-
expected: {
|
|
27
|
-
partition: 'aws',
|
|
28
|
-
service: 's3',
|
|
29
|
-
region: '',
|
|
30
|
-
accountId: '',
|
|
31
|
-
resource: 'my_corporate_bucket',
|
|
32
|
-
resourceType: '',
|
|
33
|
-
resourcePath: 'my_corporate_bucket'
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
name: 'should split an S3 object ARN',
|
|
38
|
-
arn: 'arn:aws:s3:::my_corporate_bucket/my_corporate_object.txt',
|
|
39
|
-
expected: {
|
|
40
|
-
partition: 'aws',
|
|
41
|
-
service: 's3',
|
|
42
|
-
region: '',
|
|
43
|
-
accountId: '',
|
|
44
|
-
resource: 'my_corporate_bucket/my_corporate_object.txt',
|
|
45
|
-
resourceType: '',
|
|
46
|
-
resourcePath: 'my_corporate_bucket/my_corporate_object.txt'
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
name: 'should split an SNS topic ARN',
|
|
51
|
-
arn: 'arn:aws:sns:us-east-1:123456789012:MyTopic',
|
|
52
|
-
expected: {
|
|
53
|
-
partition: 'aws',
|
|
54
|
-
service: 'sns',
|
|
55
|
-
region: 'us-east-1',
|
|
56
|
-
accountId: '123456789012',
|
|
57
|
-
resource: 'MyTopic',
|
|
58
|
-
resourceType: '',
|
|
59
|
-
resourcePath: 'MyTopic'
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
name: 'should split an SQS queue ARN',
|
|
64
|
-
arn: 'arn:aws:sqs:us-east-1:123456789012:MyQueue',
|
|
65
|
-
expected: {
|
|
66
|
-
partition: 'aws',
|
|
67
|
-
service: 'sqs',
|
|
68
|
-
region: 'us-east-1',
|
|
69
|
-
accountId: '123456789012',
|
|
70
|
-
resource: 'MyQueue',
|
|
71
|
-
resourceType: '',
|
|
72
|
-
resourcePath: 'MyQueue'
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
name: 'should split a Lambda function ARN',
|
|
77
|
-
arn: 'arn:aws:lambda:us-west-2:123456789012:function:my-function',
|
|
78
|
-
expected: {
|
|
79
|
-
partition: 'aws',
|
|
80
|
-
service: 'lambda',
|
|
81
|
-
region: 'us-west-2',
|
|
82
|
-
accountId: '123456789012',
|
|
83
|
-
resource: 'function:my-function',
|
|
84
|
-
resourceType: 'function',
|
|
85
|
-
resourcePath: 'my-function'
|
|
86
|
-
}
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
name: 'rest api ARN',
|
|
90
|
-
arn: 'arn:aws:apigateway:us-east-1::/restapis/1234567890',
|
|
91
|
-
expected: {
|
|
92
|
-
partition: 'aws',
|
|
93
|
-
service: 'apigateway',
|
|
94
|
-
region: 'us-east-1',
|
|
95
|
-
accountId: '',
|
|
96
|
-
resource: '/restapis/1234567890',
|
|
97
|
-
resourceType: 'restapis',
|
|
98
|
-
resourcePath: '1234567890'
|
|
99
|
-
}
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
name: 'should split a glue root catalog ARN',
|
|
103
|
-
arn: 'arn:aws:glue:us-east-1:111111111111:catalog',
|
|
104
|
-
expected: {
|
|
105
|
-
partition: 'aws',
|
|
106
|
-
service: 'glue',
|
|
107
|
-
region: 'us-east-1',
|
|
108
|
-
accountId: '111111111111',
|
|
109
|
-
resource: 'catalog',
|
|
110
|
-
resourceType: 'catalog',
|
|
111
|
-
resourcePath: ''
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
]
|
|
115
|
-
|
|
116
|
-
describe('splitArnParts', () => {
|
|
117
|
-
for (const test of splitArnPartsTests) {
|
|
118
|
-
const { name, arn, expected, only } = test
|
|
119
|
-
const testFn = only ? it.only : it
|
|
120
|
-
|
|
121
|
-
testFn(name, () => {
|
|
122
|
-
const result = splitArnParts(arn)
|
|
123
|
-
expect(result).toEqual(expected)
|
|
124
|
-
})
|
|
125
|
-
}
|
|
126
|
-
})
|
package/src/arn.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
export interface ArnParts {
|
|
2
|
-
partition: string | undefined
|
|
3
|
-
service: string | undefined
|
|
4
|
-
region: string | undefined
|
|
5
|
-
accountId: string | undefined
|
|
6
|
-
resource: string | undefined
|
|
7
|
-
resourceType: string | undefined
|
|
8
|
-
resourcePath: string | undefined
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Split an ARN into its parts
|
|
13
|
-
*
|
|
14
|
-
* @param arn the arn to split
|
|
15
|
-
* @returns the parts of the ARN
|
|
16
|
-
*/
|
|
17
|
-
export function splitArnParts(arn: string): ArnParts {
|
|
18
|
-
const parts = arn.split(':')
|
|
19
|
-
const partition = parts.at(1)
|
|
20
|
-
const service = parts.at(2)!
|
|
21
|
-
const region = parts.at(3)!
|
|
22
|
-
const accountId = parts.at(4)!
|
|
23
|
-
const resource = parts.slice(5).join(':')
|
|
24
|
-
const [resourceType, resourcePath] = getResourceSegments(service, accountId, region, resource)
|
|
25
|
-
|
|
26
|
-
return {
|
|
27
|
-
partition,
|
|
28
|
-
service,
|
|
29
|
-
region,
|
|
30
|
-
accountId,
|
|
31
|
-
resource,
|
|
32
|
-
resourceType,
|
|
33
|
-
resourcePath
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Get the product/id segments of the resource portion of an ARN.
|
|
39
|
-
* The first segment is the product segment and the second segment is the resource id segment.
|
|
40
|
-
* This could be split by a colon or a slash, so it checks for both. It also checks for S3 buckets/objects.
|
|
41
|
-
*
|
|
42
|
-
* @param resource The resource to get the resource segments. Must be an ARN resource.
|
|
43
|
-
* @returns a tuple with the first segment being the product segment (without the separator) and the second segment being the resource id.
|
|
44
|
-
*/
|
|
45
|
-
export function getResourceSegments(
|
|
46
|
-
service: string,
|
|
47
|
-
accountId: string,
|
|
48
|
-
region: string,
|
|
49
|
-
resourceString: string
|
|
50
|
-
): [string, string] {
|
|
51
|
-
// This is terrible, and I hate it
|
|
52
|
-
if (
|
|
53
|
-
(service === 's3' && accountId === '' && region === '') ||
|
|
54
|
-
service === 'sns' ||
|
|
55
|
-
service === 'sqs'
|
|
56
|
-
) {
|
|
57
|
-
return ['', resourceString]
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (resourceString.startsWith('/')) {
|
|
61
|
-
resourceString = resourceString.slice(1)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const slashIndex = resourceString.indexOf('/')
|
|
65
|
-
const colonIndex = resourceString.indexOf(':')
|
|
66
|
-
|
|
67
|
-
let splitIndex = slashIndex
|
|
68
|
-
if (slashIndex != -1 && colonIndex != -1) {
|
|
69
|
-
splitIndex = Math.min(slashIndex, colonIndex) + 1
|
|
70
|
-
} else if (slashIndex == -1 && colonIndex == -1) {
|
|
71
|
-
splitIndex = resourceString.length + 1
|
|
72
|
-
} else if (colonIndex == -1) {
|
|
73
|
-
splitIndex = slashIndex + 1
|
|
74
|
-
} else if (slashIndex == -1) {
|
|
75
|
-
splitIndex = colonIndex + 1
|
|
76
|
-
} else {
|
|
77
|
-
throw new Error(`Unable to split resource ${resourceString}`)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return [resourceString.slice(0, splitIndex - 1), resourceString.slice(splitIndex)]
|
|
81
|
-
}
|
package/src/index.ts
DELETED
package/src/principals.test.ts
DELETED
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import {
|
|
3
|
-
convertAssumedRoleArnToRoleArn,
|
|
4
|
-
convertRoleArnToAssumedRoleArn,
|
|
5
|
-
isAssumedRoleArn,
|
|
6
|
-
isFederatedUserArn,
|
|
7
|
-
isIamUserArn
|
|
8
|
-
} from './principals.js'
|
|
9
|
-
|
|
10
|
-
describe('convertAssumedRoleArnToRoleArn', () => {
|
|
11
|
-
it('should return the role ARN from an assumed role ARN', () => {
|
|
12
|
-
//Given an assumed role ARN
|
|
13
|
-
const assumedRoleArn = 'arn:aws:sts::123456789012:assumed-role/role-name/session-name'
|
|
14
|
-
|
|
15
|
-
//When we get the role ARN from the assumed role ARN
|
|
16
|
-
const result = convertAssumedRoleArnToRoleArn(assumedRoleArn)
|
|
17
|
-
|
|
18
|
-
//Then it should return the role ARN
|
|
19
|
-
expect(result).toBe('arn:aws:iam::123456789012:role/role-name')
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
it('should return the role ARN from an assumed role ARN with a path', () => {
|
|
23
|
-
//Given an assumed role ARN
|
|
24
|
-
const assumedRoleArn = 'arn:aws:sts::123456789012:assumed-role/admin/global-admin/session-name'
|
|
25
|
-
|
|
26
|
-
//When we get the role ARN from the assumed role ARN
|
|
27
|
-
const result = convertAssumedRoleArnToRoleArn(assumedRoleArn)
|
|
28
|
-
|
|
29
|
-
//Then it should return the role ARN
|
|
30
|
-
expect(result).toBe('arn:aws:iam::123456789012:role/admin/global-admin')
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
it('should work in a different partition', () => {
|
|
34
|
-
//Given an assumed role ARN with a different partition
|
|
35
|
-
const assumedRoleArn = 'arn:aws-cn:sts::123456789012:assumed-role/role-name/session-name'
|
|
36
|
-
|
|
37
|
-
//When we get the role ARN from the assumed role ARN
|
|
38
|
-
const result = convertAssumedRoleArnToRoleArn(assumedRoleArn)
|
|
39
|
-
|
|
40
|
-
//Then it should return the role ARN
|
|
41
|
-
expect(result).toBe('arn:aws-cn:iam::123456789012:role/role-name')
|
|
42
|
-
})
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
describe('convertRoleArnToAssumedRoleArn', () => {
|
|
46
|
-
it('should return the assumed role ARN from a role ARN', () => {
|
|
47
|
-
//Given a role ARN
|
|
48
|
-
const roleArn = 'arn:aws:iam::123456789012:role/role-name'
|
|
49
|
-
|
|
50
|
-
//When we get the assumed role ARN from the role ARN
|
|
51
|
-
const result = convertRoleArnToAssumedRoleArn(roleArn, 'session-name')
|
|
52
|
-
|
|
53
|
-
//Then it should return the assumed role ARN
|
|
54
|
-
expect(result).toBe('arn:aws:sts::123456789012:assumed-role/role-name/session-name')
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
it('should return the assumed role ARN from a role ARN with a path', () => {
|
|
58
|
-
//Given a role ARN
|
|
59
|
-
const roleArn = 'arn:aws:iam::123456789012:role/admin/global-admin'
|
|
60
|
-
|
|
61
|
-
//When we get the assumed role ARN from the role ARN
|
|
62
|
-
const result = convertRoleArnToAssumedRoleArn(roleArn, 'session-name')
|
|
63
|
-
|
|
64
|
-
//Then it should return the assumed role ARN
|
|
65
|
-
expect(result).toBe('arn:aws:sts::123456789012:assumed-role/admin/global-admin/session-name')
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
it('should work with a different partition', () => {
|
|
69
|
-
//Given a role ARN with a different partition
|
|
70
|
-
const roleArn = 'arn:aws-cn:iam::123456789012:role/role-name'
|
|
71
|
-
|
|
72
|
-
//When we get the assumed role ARN from the role ARN
|
|
73
|
-
const result = convertRoleArnToAssumedRoleArn(roleArn, 'session-name')
|
|
74
|
-
|
|
75
|
-
//Then it should return the assumed role ARN
|
|
76
|
-
expect(result).toBe('arn:aws-cn:sts::123456789012:assumed-role/role-name/session-name')
|
|
77
|
-
})
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
describe('isAssumedRoleArn', () => {
|
|
81
|
-
it('should return true for assumed role ARN', () => {
|
|
82
|
-
//Given an assumed role ARN
|
|
83
|
-
const assumedRoleArn = 'arn:aws:sts::123456789012:assumed-role/role-name/session-name'
|
|
84
|
-
|
|
85
|
-
//When we check if it is an assumed role ARN
|
|
86
|
-
const result = isAssumedRoleArn(assumedRoleArn)
|
|
87
|
-
|
|
88
|
-
//Then it should return true
|
|
89
|
-
expect(result).toBe(true)
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
it('should return false for non-assumed role ARN', () => {
|
|
93
|
-
//Given a non-assumed role ARN
|
|
94
|
-
const userArn = 'arn:aws:iam::123456789012:user/user-name'
|
|
95
|
-
|
|
96
|
-
//When we check if it is an assumed role ARN
|
|
97
|
-
const result = isAssumedRoleArn(userArn)
|
|
98
|
-
|
|
99
|
-
//Then it should return false
|
|
100
|
-
expect(result).toBe(false)
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
it('should work for a different partition', () => {
|
|
104
|
-
//Given an assumed role ARN with a different partition
|
|
105
|
-
const assumedRoleArn = 'arn:aws-cn:sts::123456789012:assumed-role/role-name/session-name'
|
|
106
|
-
|
|
107
|
-
//When we check if it is an assumed role ARN
|
|
108
|
-
const result = isAssumedRoleArn(assumedRoleArn)
|
|
109
|
-
|
|
110
|
-
//Then it should return true
|
|
111
|
-
expect(result).toBe(true)
|
|
112
|
-
})
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
describe('isIamUserArn', () => {
|
|
116
|
-
it('should return true for IAM user ARN', () => {
|
|
117
|
-
//Given an IAM user ARN
|
|
118
|
-
const userArn = 'arn:aws:iam::123456789012:user/user-name'
|
|
119
|
-
|
|
120
|
-
//When we check if it is an IAM user ARN
|
|
121
|
-
const result = isIamUserArn(userArn)
|
|
122
|
-
|
|
123
|
-
//Then it should return true
|
|
124
|
-
expect(result).toBe(true)
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
it('should return false for non-IAM user ARN', () => {
|
|
128
|
-
//Given a non-IAM user ARN
|
|
129
|
-
const roleArn = 'arn:aws:sts::123456789012:assumed-role/role-name/session-name'
|
|
130
|
-
|
|
131
|
-
//When we check if it is an IAM user ARN
|
|
132
|
-
const result = isIamUserArn(roleArn)
|
|
133
|
-
|
|
134
|
-
//Then it should return false
|
|
135
|
-
expect(result).toBe(false)
|
|
136
|
-
})
|
|
137
|
-
|
|
138
|
-
it('should work for a different partition', () => {
|
|
139
|
-
//Given an IAM user ARN with a different partition
|
|
140
|
-
const userArn = 'arn:aws-cn:iam::123456789012:user/user-name'
|
|
141
|
-
|
|
142
|
-
//When we check if it is an IAM user ARN
|
|
143
|
-
const result = isIamUserArn(userArn)
|
|
144
|
-
|
|
145
|
-
//Then it should return true
|
|
146
|
-
expect(result).toBe(true)
|
|
147
|
-
})
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
describe('isFederatedUserArn', () => {
|
|
151
|
-
it('should return true for federated user ARN', () => {
|
|
152
|
-
//Given a federated user ARN
|
|
153
|
-
const federatedUserArn = 'arn:aws:sts::123456789012:federated-user/user-name'
|
|
154
|
-
|
|
155
|
-
//When we check if it is a federated user ARN
|
|
156
|
-
const result = isFederatedUserArn(federatedUserArn)
|
|
157
|
-
|
|
158
|
-
//Then it should return true
|
|
159
|
-
expect(result).toBe(true)
|
|
160
|
-
})
|
|
161
|
-
|
|
162
|
-
it('should return false for non-federated user ARN', () => {
|
|
163
|
-
//Given a non-federated user ARN
|
|
164
|
-
const roleArn = 'arn:aws:sts::123456789012:assumed-role/role-name/session-name'
|
|
165
|
-
|
|
166
|
-
//When we check if it is a federated user ARN
|
|
167
|
-
const result = isFederatedUserArn(roleArn)
|
|
168
|
-
|
|
169
|
-
//Then it should return false
|
|
170
|
-
expect(result).toBe(false)
|
|
171
|
-
})
|
|
172
|
-
|
|
173
|
-
it('should work for a different partition', () => {
|
|
174
|
-
//Given a federated user ARN with a different partition
|
|
175
|
-
const federatedUserArn = 'arn:aws-cn:sts::123456789012:federated-user/user-name'
|
|
176
|
-
|
|
177
|
-
//When we check if it is a federated user ARN
|
|
178
|
-
const result = isFederatedUserArn(federatedUserArn)
|
|
179
|
-
|
|
180
|
-
//Then it should return true
|
|
181
|
-
expect(result).toBe(true)
|
|
182
|
-
})
|
|
183
|
-
})
|
package/tsconfig.cjs.json
DELETED
package/tsconfig.esm.json
DELETED
package/tsconfig.json
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"module": "commonjs",
|
|
4
|
-
"target": "es2022",
|
|
5
|
-
"outDir": "dist",
|
|
6
|
-
"rootDir": "src",
|
|
7
|
-
"sourceMap": true,
|
|
8
|
-
"strict": true,
|
|
9
|
-
"declaration": true,
|
|
10
|
-
"declarationMap": true,
|
|
11
|
-
"lib": ["es2023", "DOM"],
|
|
12
|
-
"noUnusedLocals": false,
|
|
13
|
-
"noUnusedParameters": false,
|
|
14
|
-
"noImplicitReturns": true,
|
|
15
|
-
"noFallthroughCasesInSwitch": false,
|
|
16
|
-
"experimentalDecorators": true,
|
|
17
|
-
"emitDecoratorMetadata": true,
|
|
18
|
-
"esModuleInterop": false,
|
|
19
|
-
"forceConsistentCasingInFileNames": true,
|
|
20
|
-
"paths": {
|
|
21
|
-
// workaround for: https://github.com/vitest-dev/vitest/issues/4567
|
|
22
|
-
"rollup/parseAst": ["./node_modules/rollup/dist/parseAst"]
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
"exclude": ["tests", "test", "dist", "bin", "**/bin", "**/dist", "node_modules", "cdk.out"],
|
|
26
|
-
}
|