@deployport/api-services-corelib 0.2.0 → 0.3.0

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.
@@ -1,61 +1,60 @@
1
1
  import { Sha256 } from '@aws-crypto/sha256-js';
2
2
  import { Runtime } from "@deployport/specular-runtime";
3
3
  import { SourceData } from "@aws-sdk/types";
4
- import { ServiceSignatureV1 } from '../specular.js';
4
+ import { ServiceSignatureV1, SignedOperationV1 } from '../specular.js';
5
+ import type { Config } from "./config.js";
5
6
 
6
7
  type Credentials = {
7
8
  keyID: string;
8
9
  secret: string;
9
10
  }
10
11
 
11
- export type Config = {
12
- deployport?: {
13
- region?: string;
14
- accessKeyID?: string;
15
- secretAccessKey?: string;
12
+ const VendorCode = 'dpp';
13
+
14
+ /**
15
+ * Replaces the `<region>` placeholder in the request URL and Host header with
16
+ * the given region. Mirrors Go's `ReplaceRegionInRequest`. Runs for every
17
+ * request that has a resolved region, whether or not the request is signed.
18
+ */
19
+ export function replaceRegionInRequest(request: Runtime.HTTPRequest, region: string): void {
20
+ if (request.url) {
21
+ request.url = request.url.replaceAll("<region>", region);
22
+ }
23
+ const host = request.headers["Host"];
24
+ if (typeof host === "string") {
25
+ request.headers["Host"] = host.replaceAll("<region>", region);
16
26
  }
17
27
  }
18
28
 
19
- const VendorCode = 'dpp';
20
-
21
29
  export async function ConfigureSignatureV1(submission: Runtime.Submission, config: Config): Promise<void> {
22
-
23
- // const { request } = submission;
24
- // const { headers } = request;
25
- // if (!headers["x-specular-signature"]) {
26
- // headers["x-specular-signature"] = "v1";
27
- // }
28
- console.log("Hello from ConfigureSignatureV1 in runtime/signer.ts!", submission)
30
+ // sign only operations that opted in via SignedOperationV1
31
+ const signedOperationV1 = submission.operation.annotations.find((a) => a instanceof SignedOperationV1);
32
+ if (!signedOperationV1) {
33
+ return;
34
+ }
29
35
  const annotations = submission.operation.resource.package.annotations;
30
- console.log("service annotations", annotations);
31
36
  const serviceSignatureV1 = annotations.find((a) => a instanceof ServiceSignatureV1);
32
37
  if (!serviceSignatureV1) {
33
38
  return;
34
39
  }
35
- console.log("signing using config", config)
36
40
  const { deployport } = config;
37
41
  if (!deployport) {
38
- console.warn("missing required deployport configuration for signing", config);
39
42
  return;
40
43
  }
41
44
  const { region, accessKeyID: keyID, secretAccessKey: secret } = deployport;
42
45
  if (!region || !keyID || !secret) {
43
- console.warn("missing required configuration for signing", deployport);
46
+ // Incomplete credentials/region: leave the request unsigned.
44
47
  return;
45
48
  }
46
49
  const { ServiceName: signingService } = serviceSignatureV1;
47
- console.log("annotations", annotations, VendorCode, signingService);
48
50
  const { longDate, shortDate } = formatDate(new Date());
49
51
  const signingScope = buildSigningScope(VendorCode, region, signingService, shortDate);
50
- console.log("signingScope", signingScope);
51
52
 
52
53
  const credentialPart = buildCredentialPart(keyID, signingScope);
53
- console.log("credentialPart", credentialPart);
54
54
 
55
55
  const authHeaderPrefix = vendorAlgorithm(VendorCode) + " " + credentialPart
56
56
 
57
57
  const bodyDigest = toHex(await hashSHA256(submission.request.body));
58
- console.log("bodyDigest", bodyDigest);
59
58
  const headers = submission.request.headers;
60
59
  headers[vendorDateHeaderKey(VendorCode)] = longDate;
61
60
  headers[vendorHeaderCanonicalNameKey(VendorCode, "Service")] = signingService;
@@ -63,7 +62,6 @@ export async function ConfigureSignatureV1(submission: Runtime.Submission, confi
63
62
  headers[vendorHeaderCanonicalNameKey(VendorCode, "Operation")] = submission.operation.name;
64
63
  headers[vendorRegionHeaderKey(VendorCode)] = region;
65
64
  headers[vendorHeaderCanonicalNameKey(VendorCode, "Content-Sha256")] = bodyDigest;
66
- console.log("headers", headers);
67
65
  const canonicalHeaders = getCanonicalHeaders(VendorCode, headers);
68
66
 
69
67
  const credentials: Credentials = {
@@ -85,7 +83,6 @@ export async function ConfigureSignatureV1(submission: Runtime.Submission, confi
85
83
  );
86
84
 
87
85
  headers["Authorization"] = [authHeaderPrefix, `SignedHeaders=${canonicalHeaders.signedHeaders}`, `Signature=${signature}`] as any;
88
- console.log("signed headers", headers);
89
86
  }
90
87
 
91
88
  function createCanonicalRequest(request: Runtime.HTTPRequest, canonicalHeaders: CanonicalHeaders, payloadHash: string): string {
@@ -104,7 +101,6 @@ function getCanonicalQuery({ path }: Runtime.HTTPRequest): string {
104
101
  }
105
102
 
106
103
  function getCanonicalPath({ path }: Runtime.HTTPRequest): string {
107
- console.log("getCanonicalPath path", path);
108
104
  return path;
109
105
  // if (this.uriEscapePath) {
110
106
  // Non-S3 services, we normalize the path and then double URI encode it.
@@ -131,7 +127,6 @@ function getCanonicalPath({ path }: Runtime.HTTPRequest): string {
131
127
  // my-object//example//photo.user should not be normalized to
132
128
  // my-object/example/photo.user
133
129
 
134
- console.log("getCanonicalPath path (curated)", path);
135
130
  return path;
136
131
  }
137
132
 
@@ -156,7 +151,6 @@ async function getSignature(
156
151
  canonicalRequest: string
157
152
  ): Promise<string> {
158
153
  const stringToSign = await createStringToSign(vendor, longDate, credentialScope, canonicalRequest);
159
- console.log("stringToSign", stringToSign);
160
154
 
161
155
  const hash = new Sha256(await keyPromise);
162
156
  hash.update(stringToSign);
@@ -169,7 +163,6 @@ async function createStringToSign(
169
163
  credentialScope: string,
170
164
  canonicalRequest: string
171
165
  ): Promise<string> {
172
- console.log('canonicalRequest', canonicalRequest);
173
166
  const hash = new Sha256();
174
167
  hash.update(canonicalRequest);
175
168
  const hashedRequest = await hash.digest();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deployport/api-services-corelib",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "",
5
5
  "main": "./specular.js",
6
6
  "types": "./specular.d.ts",
@@ -12,6 +12,17 @@
12
12
  "./configurator": {
13
13
  "types": "./configurator/index.d.ts",
14
14
  "default": "./configurator/index.js"
15
+ },
16
+ "./configurator/node": {
17
+ "types": "./configurator/loader.node.d.ts",
18
+ "default": "./configurator/loader.node.js"
19
+ }
20
+ },
21
+ "imports": {
22
+ "#config-loader": {
23
+ "browser": "./configurator/loader.browser.js",
24
+ "node": "./configurator/loader.node.js",
25
+ "default": "./configurator/loader.browser.js"
15
26
  }
16
27
  },
17
28
  "author": "bithavoc",
@@ -24,6 +35,7 @@
24
35
  "generate": "specular-standalone-compiler generate",
25
36
  "build-configurator": "tsc",
26
37
  "build": "npm run build-configurator",
38
+ "test": "vitest run",
27
39
  "clean": "rm -rf node_modules && rm -f **/*.js **/*.d.ts"
28
40
  },
29
41
  "type": "module",
@@ -31,11 +43,13 @@
31
43
  "dependencies": {
32
44
  "@aws-crypto/sha256-js": "^5.2.0",
33
45
  "@aws-sdk/types": "^3.515.0",
34
- "@deployport/specular-runtime": "^0.2.1"
46
+ "@deployport/specular-runtime": "^0.2.1",
47
+ "yaml": "^2.6.1"
35
48
  },
36
49
  "devDependencies": {
37
50
  "@tsconfig/node24": "^24.0.4",
38
51
  "@types/node": "^24.13.2",
39
- "typescript": "^6.0.3"
52
+ "typescript": "^6.0.3",
53
+ "vitest": "^3.0.0"
40
54
  }
41
- }
55
+ }
package/tsconfig.json CHANGED
@@ -4,5 +4,9 @@
4
4
  "declaration": true,
5
5
  "types": ["node"]
6
6
  },
7
- "files": ["configurator/index.ts"]
7
+ "files": [
8
+ "configurator/index.ts",
9
+ "configurator/loader.node.ts",
10
+ "configurator/loader.browser.ts"
11
+ ]
8
12
  }