@zuplo/cli 6.70.15 → 6.70.21
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/ca-certificate/create/handler.d.ts +3 -0
- package/dist/ca-certificate/create/handler.d.ts.map +1 -0
- package/dist/ca-certificate/create/handler.js +46 -0
- package/dist/ca-certificate/create/handler.js.map +1 -0
- package/dist/ca-certificate/delete/handler.d.ts +3 -0
- package/dist/ca-certificate/delete/handler.d.ts.map +1 -0
- package/dist/ca-certificate/delete/handler.js +18 -0
- package/dist/ca-certificate/delete/handler.js.map +1 -0
- package/dist/ca-certificate/describe/handler.d.ts +3 -0
- package/dist/ca-certificate/describe/handler.d.ts.map +1 -0
- package/dist/ca-certificate/describe/handler.js +32 -0
- package/dist/ca-certificate/describe/handler.js.map +1 -0
- package/dist/ca-certificate/list/handler.d.ts +3 -0
- package/dist/ca-certificate/list/handler.d.ts.map +1 -0
- package/dist/ca-certificate/list/handler.js +28 -0
- package/dist/ca-certificate/list/handler.js.map +1 -0
- package/dist/ca-certificate/models.d.ts +51 -0
- package/dist/ca-certificate/models.d.ts.map +1 -0
- package/dist/ca-certificate/models.js +2 -0
- package/dist/ca-certificate/models.js.map +1 -0
- package/dist/ca-certificate/update/handler.d.ts +3 -0
- package/dist/ca-certificate/update/handler.d.ts.map +1 -0
- package/dist/ca-certificate/update/handler.js +26 -0
- package/dist/ca-certificate/update/handler.js.map +1 -0
- package/dist/ca-certificate/validation.d.ts +21 -0
- package/dist/ca-certificate/validation.d.ts.map +1 -0
- package/dist/ca-certificate/validation.js +135 -0
- package/dist/ca-certificate/validation.js.map +1 -0
- package/dist/ca-certificate/validation.test.d.ts +2 -0
- package/dist/ca-certificate/validation.test.d.ts.map +1 -0
- package/dist/ca-certificate/validation.test.js +131 -0
- package/dist/ca-certificate/validation.test.js.map +1 -0
- package/dist/cli.js +2 -6
- package/dist/cli.js.map +1 -1
- package/dist/cmds/ca-certificate/create.d.ts +9 -0
- package/dist/cmds/ca-certificate/create.d.ts.map +1 -0
- package/dist/cmds/ca-certificate/create.js +66 -0
- package/dist/cmds/ca-certificate/create.js.map +1 -0
- package/dist/cmds/ca-certificate/delete.d.ts +9 -0
- package/dist/cmds/ca-certificate/delete.d.ts.map +1 -0
- package/dist/cmds/ca-certificate/delete.js +56 -0
- package/dist/cmds/ca-certificate/delete.js.map +1 -0
- package/dist/cmds/ca-certificate/describe.d.ts +9 -0
- package/dist/cmds/ca-certificate/describe.d.ts.map +1 -0
- package/dist/cmds/ca-certificate/describe.js +56 -0
- package/dist/cmds/ca-certificate/describe.js.map +1 -0
- package/dist/cmds/ca-certificate/index.d.ts +4 -0
- package/dist/cmds/ca-certificate/index.d.ts.map +1 -0
- package/dist/cmds/ca-certificate/index.js +18 -0
- package/dist/cmds/ca-certificate/index.js.map +1 -0
- package/dist/cmds/ca-certificate/list.d.ts +9 -0
- package/dist/cmds/ca-certificate/list.d.ts.map +1 -0
- package/dist/cmds/ca-certificate/list.js +48 -0
- package/dist/cmds/ca-certificate/list.js.map +1 -0
- package/dist/cmds/ca-certificate/update.d.ts +9 -0
- package/dist/cmds/ca-certificate/update.d.ts.map +1 -0
- package/dist/cmds/ca-certificate/update.js +56 -0
- package/dist/cmds/ca-certificate/update.js.map +1 -0
- package/dist/cmds/mtls-certificates/index.js +1 -1
- package/dist/cmds/mtls-certificates/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/node_modules/@cfworker/json-schema/README.md +75 -0
- package/node_modules/@cfworker/json-schema/dist/commonjs/deep-compare-strict.d.ts +1 -0
- package/node_modules/@cfworker/json-schema/dist/commonjs/deep-compare-strict.js +42 -0
- package/node_modules/@cfworker/json-schema/dist/commonjs/dereference.d.ts +7 -0
- package/node_modules/@cfworker/json-schema/dist/commonjs/dereference.js +147 -0
- package/node_modules/@cfworker/json-schema/dist/commonjs/format.d.ts +1 -0
- package/node_modules/@cfworker/json-schema/dist/commonjs/format.js +111 -0
- package/node_modules/@cfworker/json-schema/dist/commonjs/index.d.ts +8 -0
- package/node_modules/@cfworker/json-schema/dist/commonjs/index.js +24 -0
- package/node_modules/@cfworker/json-schema/dist/commonjs/package.json +3 -0
- package/node_modules/@cfworker/json-schema/dist/commonjs/pointer.d.ts +2 -0
- package/node_modules/@cfworker/json-schema/dist/commonjs/pointer.js +10 -0
- package/node_modules/@cfworker/json-schema/dist/commonjs/types.d.ts +72 -0
- package/node_modules/@cfworker/json-schema/dist/commonjs/types.js +9 -0
- package/node_modules/@cfworker/json-schema/dist/commonjs/ucs2-length.d.ts +1 -0
- package/node_modules/@cfworker/json-schema/dist/commonjs/ucs2-length.js +20 -0
- package/node_modules/@cfworker/json-schema/dist/commonjs/validate.d.ts +3 -0
- package/node_modules/@cfworker/json-schema/dist/commonjs/validate.js +805 -0
- package/node_modules/@cfworker/json-schema/dist/commonjs/validator.d.ts +10 -0
- package/node_modules/@cfworker/json-schema/dist/commonjs/validator.js +27 -0
- package/node_modules/@cfworker/json-schema/dist/esm/deep-compare-strict.d.ts +1 -0
- package/node_modules/@cfworker/json-schema/dist/esm/deep-compare-strict.js +39 -0
- package/node_modules/@cfworker/json-schema/dist/esm/dereference.d.ts +7 -0
- package/node_modules/@cfworker/json-schema/dist/esm/dereference.js +143 -0
- package/node_modules/@cfworker/json-schema/dist/esm/format.d.ts +1 -0
- package/node_modules/@cfworker/json-schema/dist/esm/format.js +108 -0
- package/node_modules/@cfworker/json-schema/dist/esm/index.d.ts +8 -0
- package/node_modules/@cfworker/json-schema/dist/esm/index.js +8 -0
- package/node_modules/@cfworker/json-schema/dist/esm/package.json +3 -0
- package/node_modules/@cfworker/json-schema/dist/esm/pointer.d.ts +2 -0
- package/node_modules/@cfworker/json-schema/dist/esm/pointer.js +6 -0
- package/node_modules/@cfworker/json-schema/dist/esm/types.d.ts +72 -0
- package/node_modules/@cfworker/json-schema/dist/esm/types.js +6 -0
- package/node_modules/@cfworker/json-schema/dist/esm/ucs2-length.d.ts +1 -0
- package/node_modules/@cfworker/json-schema/dist/esm/ucs2-length.js +17 -0
- package/node_modules/@cfworker/json-schema/dist/esm/validate.d.ts +3 -0
- package/node_modules/@cfworker/json-schema/dist/esm/validate.js +802 -0
- package/node_modules/@cfworker/json-schema/dist/esm/validator.d.ts +10 -0
- package/node_modules/@cfworker/json-schema/dist/esm/validator.js +23 -0
- package/node_modules/@cfworker/json-schema/package.json +68 -0
- package/node_modules/@cfworker/json-schema/src/deep-compare-strict.d.ts +1 -0
- package/node_modules/@cfworker/json-schema/src/deep-compare-strict.ts +39 -0
- package/node_modules/@cfworker/json-schema/src/dereference.d.ts +12 -0
- package/node_modules/@cfworker/json-schema/src/dereference.ts +188 -0
- package/node_modules/@cfworker/json-schema/src/format.d.ts +2 -0
- package/node_modules/@cfworker/json-schema/src/format.ts +164 -0
- package/node_modules/@cfworker/json-schema/src/index.d.ts +8 -0
- package/node_modules/@cfworker/json-schema/src/index.ts +8 -0
- package/node_modules/@cfworker/json-schema/src/pointer.d.ts +2 -0
- package/node_modules/@cfworker/json-schema/src/pointer.ts +7 -0
- package/node_modules/@cfworker/json-schema/src/types.d.ts +79 -0
- package/node_modules/@cfworker/json-schema/src/types.ts +92 -0
- package/node_modules/@cfworker/json-schema/src/ucs2-length.d.ts +1 -0
- package/node_modules/@cfworker/json-schema/src/ucs2-length.ts +24 -0
- package/node_modules/@cfworker/json-schema/src/validate.d.ts +13 -0
- package/node_modules/@cfworker/json-schema/src/validate.ts +1168 -0
- package/node_modules/@cfworker/json-schema/src/validator.d.ts +14 -0
- package/node_modules/@cfworker/json-schema/src/validator.ts +32 -0
- package/node_modules/@zuplo/core/package.json +1 -1
- package/node_modules/@zuplo/graphql/package.json +1 -1
- package/node_modules/@zuplo/openapi-tools/package.json +1 -1
- package/node_modules/@zuplo/otel/package.json +1 -1
- package/node_modules/@zuplo/runtime/out/esm/{chunk-YJ3VHQXF.js → chunk-2ZQVIVZ3.js} +2 -2
- package/node_modules/@zuplo/runtime/out/esm/{chunk-STBDRSX7.js → chunk-UMZORQLU.js} +67 -66
- package/node_modules/@zuplo/runtime/out/esm/chunk-UMZORQLU.js.map +1 -0
- package/node_modules/@zuplo/runtime/out/esm/{chunk-KWR5BV7H.js → chunk-YGYFQCBA.js} +6 -6
- package/node_modules/@zuplo/runtime/out/esm/chunk-YGYFQCBA.js.map +1 -0
- package/node_modules/@zuplo/runtime/out/esm/{chunk-NJNTFB34.js → chunk-ZS34EO4B.js} +2 -2
- package/node_modules/@zuplo/runtime/out/esm/{chunk-NJNTFB34.js.map → chunk-ZS34EO4B.js.map} +1 -1
- package/node_modules/@zuplo/runtime/out/esm/index.js +1 -1
- package/node_modules/@zuplo/runtime/out/esm/index.js.map +1 -1
- package/node_modules/@zuplo/runtime/out/esm/internal/index.js +1 -1
- package/node_modules/@zuplo/runtime/out/esm/mcp-gateway/index.js +208 -72
- package/node_modules/@zuplo/runtime/out/esm/mcp-gateway/index.js.map +1 -1
- package/node_modules/@zuplo/runtime/out/esm/mocks/index.js +1 -1
- package/node_modules/@zuplo/runtime/out/types/index.d.ts +61 -12
- package/node_modules/@zuplo/runtime/out/types/mcp-gateway/index.d.ts +8 -17
- package/node_modules/@zuplo/runtime/out/types/mocks/index.d.ts +3 -12
- package/node_modules/@zuplo/runtime/package.json +3 -2
- package/node_modules/agent-base/README.md +145 -0
- package/node_modules/agent-base/dist/src/index.d.ts +78 -0
- package/node_modules/agent-base/dist/src/index.js +203 -0
- package/node_modules/agent-base/dist/src/index.js.map +1 -0
- package/node_modules/agent-base/dist/src/promisify.d.ts +4 -0
- package/node_modules/agent-base/dist/src/promisify.js +18 -0
- package/node_modules/agent-base/dist/src/promisify.js.map +1 -0
- package/node_modules/agent-base/package.json +64 -0
- package/node_modules/agent-base/src/index.ts +345 -0
- package/node_modules/agent-base/src/promisify.ts +33 -0
- package/node_modules/axios/CHANGELOG.md +71 -0
- package/node_modules/axios/README.md +46 -11
- package/node_modules/axios/dist/axios.js +81 -53
- package/node_modules/axios/dist/axios.js.map +1 -1
- package/node_modules/axios/dist/axios.min.js +2 -2
- package/node_modules/axios/dist/axios.min.js.map +1 -1
- package/node_modules/axios/dist/browser/axios.cjs +96 -64
- package/node_modules/axios/dist/browser/axios.cjs.map +1 -1
- package/node_modules/axios/dist/esm/axios.js +96 -64
- package/node_modules/axios/dist/esm/axios.js.map +1 -1
- package/node_modules/axios/dist/esm/axios.min.js +2 -2
- package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
- package/node_modules/axios/dist/node/axios.cjs +206 -85
- package/node_modules/axios/dist/node/axios.cjs.map +1 -1
- package/node_modules/axios/index.d.cts +1 -1
- package/node_modules/axios/index.d.ts +1 -1
- package/node_modules/axios/lib/adapters/fetch.js +6 -2
- package/node_modules/axios/lib/adapters/http.js +139 -29
- package/node_modules/axios/lib/adapters/xhr.js +2 -1
- package/node_modules/axios/lib/core/AxiosHeaders.js +1 -33
- package/node_modules/axios/lib/env/data.js +1 -1
- package/node_modules/axios/lib/helpers/composeSignals.js +48 -47
- package/node_modules/axios/lib/helpers/formDataToJSON.js +1 -1
- package/node_modules/axios/lib/helpers/fromDataURI.js +18 -5
- package/node_modules/axios/lib/helpers/progressEventReducer.js +3 -0
- package/node_modules/axios/lib/helpers/sanitizeHeaderValue.js +60 -0
- package/node_modules/axios/lib/utils.js +8 -7
- package/node_modules/axios/package.json +3 -1
- package/node_modules/https-proxy-agent/README.md +137 -0
- package/node_modules/https-proxy-agent/dist/agent.d.ts +30 -0
- package/node_modules/https-proxy-agent/dist/agent.js +177 -0
- package/node_modules/https-proxy-agent/dist/agent.js.map +1 -0
- package/node_modules/https-proxy-agent/dist/index.d.ts +23 -0
- package/node_modules/https-proxy-agent/dist/index.js +14 -0
- package/node_modules/https-proxy-agent/dist/index.js.map +1 -0
- package/node_modules/https-proxy-agent/dist/parse-proxy-response.d.ts +7 -0
- package/node_modules/https-proxy-agent/dist/parse-proxy-response.js +66 -0
- package/node_modules/https-proxy-agent/dist/parse-proxy-response.js.map +1 -0
- package/node_modules/https-proxy-agent/package.json +56 -0
- package/node_modules/type-is/index.js +8 -18
- package/node_modules/type-is/node_modules/content-type/LICENSE +22 -0
- package/node_modules/type-is/node_modules/content-type/README.md +69 -0
- package/node_modules/type-is/node_modules/content-type/dist/index.d.ts +26 -0
- package/node_modules/type-is/node_modules/content-type/dist/index.js +170 -0
- package/node_modules/type-is/node_modules/content-type/dist/index.js.map +1 -0
- package/node_modules/type-is/node_modules/content-type/package.json +52 -0
- package/node_modules/type-is/package.json +9 -5
- package/package.json +6 -6
- package/node_modules/@zuplo/runtime/out/esm/chunk-KWR5BV7H.js.map +0 -1
- package/node_modules/@zuplo/runtime/out/esm/chunk-STBDRSX7.js.map +0 -1
- /package/node_modules/@zuplo/runtime/out/esm/{chunk-YJ3VHQXF.js.map → chunk-2ZQVIVZ3.js.map} +0 -0
- /package/node_modules/@zuplo/runtime/out/esm/{chunk-STBDRSX7.js.LEGAL.txt → chunk-UMZORQLU.js.LEGAL.txt} +0 -0
- /package/node_modules/@zuplo/runtime/out/esm/{chunk-KWR5BV7H.js.LEGAL.txt → chunk-YGYFQCBA.js.LEGAL.txt} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/ca-certificate/create/handler.ts"],"names":[],"mappings":"AAQA,OAAO,EAAiB,eAAe,EAAE,MAAM,cAAc,CAAC;AAO9D,wBAAsB,MAAM,CAAC,IAAI,EAAE,eAAe,iBAwDjD"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { createApiClient } from "../../common/api/client.js";
|
|
3
|
+
import { logger } from "../../common/logger.js";
|
|
4
|
+
import { printDiagnosticsToConsole, printJsonToConsoleAndExitGracefully, printResultToConsole, } from "../../common/output.js";
|
|
5
|
+
import { isValidationError, parseAndValidateCaCertificate, validateName, } from "../validation.js";
|
|
6
|
+
export async function create(argv) {
|
|
7
|
+
const { account } = argv;
|
|
8
|
+
const nameError = validateName(argv.name);
|
|
9
|
+
if (nameError) {
|
|
10
|
+
printDiagnosticsToConsole(`Error: --name is invalid. ${nameError.message}`);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
let certificate;
|
|
14
|
+
try {
|
|
15
|
+
certificate = readFileSync(argv.cert, "utf-8");
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
logger.error(error, "Failed to read CA certificate file");
|
|
19
|
+
printDiagnosticsToConsole(`Error: Failed to read CA certificate file at ${argv.cert}`, error instanceof Error ? error.message : String(error));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const parsed = parseAndValidateCaCertificate(certificate);
|
|
23
|
+
if (isValidationError(parsed)) {
|
|
24
|
+
printDiagnosticsToConsole(`Error: ${argv.cert} is not a valid CA certificate. ${parsed.message}`, parsed.hint);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const client = createApiClient({ authToken: argv.authToken });
|
|
28
|
+
const cert = await client.post(`/v1/accounts/${account}/client-mtls-ca-certificates`, {
|
|
29
|
+
operation: "Failed to create CA certificate",
|
|
30
|
+
errorMessage: "Error: Failed to create CA certificate. Check the arguments.",
|
|
31
|
+
body: {
|
|
32
|
+
name: argv.name,
|
|
33
|
+
certificate,
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
if (argv.output === "json") {
|
|
37
|
+
await printJsonToConsoleAndExitGracefully(cert);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const subject = cert.certificateInfo.subject.replace(/\n/g, ", ");
|
|
41
|
+
printResultToConsole(`CA certificate '${cert.name}' (${cert.id}) created successfully\n` +
|
|
42
|
+
` Subject: ${subject}\n` +
|
|
43
|
+
` Valid from: ${cert.certificateInfo.validFrom}\n` +
|
|
44
|
+
` Valid to: ${cert.certificateInfo.validTo}`);
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/ca-certificate/create/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EACL,yBAAyB,EACzB,mCAAmC,EACnC,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,iBAAiB,EACjB,6BAA6B,EAC7B,YAAY,GACb,MAAM,kBAAkB,CAAC;AAE1B,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAqB;IAChD,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAEzB,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,SAAS,EAAE,CAAC;QACd,yBAAyB,CAAC,6BAA6B,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5E,OAAO;IACT,CAAC;IAED,IAAI,WAAmB,CAAC;IACxB,IAAI,CAAC;QACH,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,oCAAoC,CAAC,CAAC;QAC1D,yBAAyB,CACvB,gDAAgD,IAAI,CAAC,IAAI,EAAE,EAC3D,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACvD,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,6BAA6B,CAAC,WAAW,CAAC,CAAC;IAC1D,IAAI,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,yBAAyB,CACvB,UAAU,IAAI,CAAC,IAAI,mCAAmC,MAAM,CAAC,OAAO,EAAE,EACtE,MAAM,CAAC,IAAI,CACZ,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,eAAe,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IAC9D,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAC5B,gBAAgB,OAAO,8BAA8B,EACrD;QACE,SAAS,EAAE,iCAAiC;QAC5C,YAAY,EACV,8DAA8D;QAChE,IAAI,EAAE;YACJ,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW;SACZ;KACF,CACF,CAAC;IAEF,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC3B,MAAM,mCAAmC,CAAC,IAAI,CAAC,CAAC;QAChD,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAClE,oBAAoB,CAClB,mBAAmB,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,0BAA0B;QACjE,cAAc,OAAO,IAAI;QACzB,iBAAiB,IAAI,CAAC,eAAe,CAAC,SAAS,IAAI;QACnD,eAAe,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,CAChD,CAAC;AACJ,CAAC","sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { createApiClient } from \"../../common/api/client.js\";\nimport { logger } from \"../../common/logger.js\";\nimport {\n printDiagnosticsToConsole,\n printJsonToConsoleAndExitGracefully,\n printResultToConsole,\n} from \"../../common/output.js\";\nimport { CaCertificate, CreateArguments } from \"../models.js\";\nimport {\n isValidationError,\n parseAndValidateCaCertificate,\n validateName,\n} from \"../validation.js\";\n\nexport async function create(argv: CreateArguments) {\n const { account } = argv;\n\n const nameError = validateName(argv.name);\n if (nameError) {\n printDiagnosticsToConsole(`Error: --name is invalid. ${nameError.message}`);\n return;\n }\n\n let certificate: string;\n try {\n certificate = readFileSync(argv.cert, \"utf-8\");\n } catch (error) {\n logger.error(error, \"Failed to read CA certificate file\");\n printDiagnosticsToConsole(\n `Error: Failed to read CA certificate file at ${argv.cert}`,\n error instanceof Error ? error.message : String(error)\n );\n return;\n }\n\n const parsed = parseAndValidateCaCertificate(certificate);\n if (isValidationError(parsed)) {\n printDiagnosticsToConsole(\n `Error: ${argv.cert} is not a valid CA certificate. ${parsed.message}`,\n parsed.hint\n );\n return;\n }\n\n const client = createApiClient({ authToken: argv.authToken });\n const cert = await client.post<CaCertificate>(\n `/v1/accounts/${account}/client-mtls-ca-certificates`,\n {\n operation: \"Failed to create CA certificate\",\n errorMessage:\n \"Error: Failed to create CA certificate. Check the arguments.\",\n body: {\n name: argv.name,\n certificate,\n },\n }\n );\n\n if (argv.output === \"json\") {\n await printJsonToConsoleAndExitGracefully(cert);\n return;\n }\n\n const subject = cert.certificateInfo.subject.replace(/\\n/g, \", \");\n printResultToConsole(\n `CA certificate '${cert.name}' (${cert.id}) created successfully\\n` +\n ` Subject: ${subject}\\n` +\n ` Valid from: ${cert.certificateInfo.validFrom}\\n` +\n ` Valid to: ${cert.certificateInfo.validTo}`\n );\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/ca-certificate/delete/handler.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,wBAAsB,aAAa,CAAC,IAAI,EAAE,eAAe,iBAoBxD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { createApiClient } from "../../common/api/client.js";
|
|
2
|
+
import { printJsonToConsoleAndExitGracefully, printResultToConsole, } from "../../common/output.js";
|
|
3
|
+
export async function deleteCommand(argv) {
|
|
4
|
+
const { account } = argv;
|
|
5
|
+
const certId = argv["cert-id"];
|
|
6
|
+
const client = createApiClient({ authToken: argv.authToken });
|
|
7
|
+
await client.delete(`/v1/accounts/${account}/client-mtls-ca-certificates/${encodeURIComponent(certId)}`, {
|
|
8
|
+
operation: "Failed to delete CA certificate",
|
|
9
|
+
errorMessage: "Error: Failed to delete CA certificate.",
|
|
10
|
+
emptyResponse: true,
|
|
11
|
+
});
|
|
12
|
+
if (argv.output === "json") {
|
|
13
|
+
await printJsonToConsoleAndExitGracefully({ id: certId, deleted: true });
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
printResultToConsole(`CA certificate ${certId} deleted successfully`);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/ca-certificate/delete/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EACL,mCAAmC,EACnC,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAGhC,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAqB;IACvD,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACzB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;IAE/B,MAAM,MAAM,GAAG,eAAe,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IAC9D,MAAM,MAAM,CAAC,MAAM,CACjB,gBAAgB,OAAO,gCAAgC,kBAAkB,CAAC,MAAM,CAAC,EAAE,EACnF;QACE,SAAS,EAAE,iCAAiC;QAC5C,YAAY,EAAE,yCAAyC;QACvD,aAAa,EAAE,IAAI;KACpB,CACF,CAAC;IAEF,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC3B,MAAM,mCAAmC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACzE,OAAO;IACT,CAAC;IAED,oBAAoB,CAAC,kBAAkB,MAAM,uBAAuB,CAAC,CAAC;AACxE,CAAC","sourcesContent":["import { createApiClient } from \"../../common/api/client.js\";\nimport {\n printJsonToConsoleAndExitGracefully,\n printResultToConsole,\n} from \"../../common/output.js\";\nimport { DeleteArguments } from \"../models.js\";\n\nexport async function deleteCommand(argv: DeleteArguments) {\n const { account } = argv;\n const certId = argv[\"cert-id\"];\n\n const client = createApiClient({ authToken: argv.authToken });\n await client.delete(\n `/v1/accounts/${account}/client-mtls-ca-certificates/${encodeURIComponent(certId)}`,\n {\n operation: \"Failed to delete CA certificate\",\n errorMessage: \"Error: Failed to delete CA certificate.\",\n emptyResponse: true,\n }\n );\n\n if (argv.output === \"json\") {\n await printJsonToConsoleAndExitGracefully({ id: certId, deleted: true });\n return;\n }\n\n printResultToConsole(`CA certificate ${certId} deleted successfully`);\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/ca-certificate/describe/handler.ts"],"names":[],"mappings":"AAMA,OAAO,EAA6B,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAK5E,wBAAsB,QAAQ,CAAC,IAAI,EAAE,iBAAiB,iBAuCrD"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { createApiClient } from "../../common/api/client.js";
|
|
2
|
+
import { printDiagnosticsToConsole, printJsonToConsoleAndExitGracefully, printResultToConsole, } from "../../common/output.js";
|
|
3
|
+
export async function describe(argv) {
|
|
4
|
+
const { account } = argv;
|
|
5
|
+
const certId = argv["cert-id"];
|
|
6
|
+
const client = createApiClient({ authToken: argv.authToken });
|
|
7
|
+
const response = await client.get(`/v1/accounts/${account}/client-mtls-ca-certificates`, {
|
|
8
|
+
operation: "Failed to describe CA certificate",
|
|
9
|
+
errorMessage: "Error: Failed to describe CA certificate.",
|
|
10
|
+
});
|
|
11
|
+
const cert = response.data.find((c) => c.id === certId);
|
|
12
|
+
if (!cert) {
|
|
13
|
+
printDiagnosticsToConsole(`Error: CA certificate with ID '${certId}' not found in account '${account}'`);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (argv.output === "json") {
|
|
17
|
+
await printJsonToConsoleAndExitGracefully(cert);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const subject = cert.certificateInfo.subject.replace(/\n/g, ", ");
|
|
21
|
+
const issuer = cert.certificateInfo.issuer.replace(/\n/g, ", ");
|
|
22
|
+
printResultToConsole(` ID: ${cert.id}\n` +
|
|
23
|
+
` Name: ${cert.name}\n` +
|
|
24
|
+
` Subject: ${subject}\n` +
|
|
25
|
+
` Issuer: ${issuer}\n` +
|
|
26
|
+
` Serial: ${cert.certificateInfo.serialNumber}\n` +
|
|
27
|
+
` Valid from: ${cert.certificateInfo.validFrom}\n` +
|
|
28
|
+
` Valid to: ${cert.certificateInfo.validTo}\n` +
|
|
29
|
+
` Created: ${cert.createdOn}\n` +
|
|
30
|
+
` Updated: ${cert.updatedOn}`);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/ca-certificate/describe/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EACL,yBAAyB,EACzB,mCAAmC,EACnC,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAMhC,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAuB;IACpD,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACzB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;IAE/B,MAAM,MAAM,GAAG,eAAe,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,CAC/B,gBAAgB,OAAO,8BAA8B,EACrD;QACE,SAAS,EAAE,mCAAmC;QAC9C,YAAY,EAAE,2CAA2C;KAC1D,CACF,CAAC;IAEF,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;IACxD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,yBAAyB,CACvB,kCAAkC,MAAM,2BAA2B,OAAO,GAAG,CAC9E,CAAC;QACF,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC3B,MAAM,mCAAmC,CAAC,IAAI,CAAC,CAAC;QAChD,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAChE,oBAAoB,CAClB,SAAS,IAAI,CAAC,EAAE,IAAI;QAClB,WAAW,IAAI,CAAC,IAAI,IAAI;QACxB,cAAc,OAAO,IAAI;QACzB,aAAa,MAAM,IAAI;QACvB,aAAa,IAAI,CAAC,eAAe,CAAC,YAAY,IAAI;QAClD,iBAAiB,IAAI,CAAC,eAAe,CAAC,SAAS,IAAI;QACnD,eAAe,IAAI,CAAC,eAAe,CAAC,OAAO,IAAI;QAC/C,cAAc,IAAI,CAAC,SAAS,IAAI;QAChC,cAAc,IAAI,CAAC,SAAS,EAAE,CACjC,CAAC;AACJ,CAAC","sourcesContent":["import { createApiClient } from \"../../common/api/client.js\";\nimport {\n printDiagnosticsToConsole,\n printJsonToConsoleAndExitGracefully,\n printResultToConsole,\n} from \"../../common/output.js\";\nimport { CaCertificateListResponse, DescribeArguments } from \"../models.js\";\n\n// developer-api does not currently expose GET /client-mtls-ca-certificates/{id},\n// so we fetch the list and filter client-side. Switch to a direct GET when the\n// route is added.\nexport async function describe(argv: DescribeArguments) {\n const { account } = argv;\n const certId = argv[\"cert-id\"];\n\n const client = createApiClient({ authToken: argv.authToken });\n const response = await client.get<CaCertificateListResponse>(\n `/v1/accounts/${account}/client-mtls-ca-certificates`,\n {\n operation: \"Failed to describe CA certificate\",\n errorMessage: \"Error: Failed to describe CA certificate.\",\n }\n );\n\n const cert = response.data.find((c) => c.id === certId);\n if (!cert) {\n printDiagnosticsToConsole(\n `Error: CA certificate with ID '${certId}' not found in account '${account}'`\n );\n return;\n }\n\n if (argv.output === \"json\") {\n await printJsonToConsoleAndExitGracefully(cert);\n return;\n }\n\n const subject = cert.certificateInfo.subject.replace(/\\n/g, \", \");\n const issuer = cert.certificateInfo.issuer.replace(/\\n/g, \", \");\n printResultToConsole(\n ` ID: ${cert.id}\\n` +\n ` Name: ${cert.name}\\n` +\n ` Subject: ${subject}\\n` +\n ` Issuer: ${issuer}\\n` +\n ` Serial: ${cert.certificateInfo.serialNumber}\\n` +\n ` Valid from: ${cert.certificateInfo.validFrom}\\n` +\n ` Valid to: ${cert.certificateInfo.validTo}\\n` +\n ` Created: ${cert.createdOn}\\n` +\n ` Updated: ${cert.updatedOn}`\n );\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/ca-certificate/list/handler.ts"],"names":[],"mappings":"AAKA,OAAO,EAA6B,aAAa,EAAE,MAAM,cAAc,CAAC;AAExE,wBAAsB,IAAI,CAAC,IAAI,EAAE,aAAa,iBAkC7C"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { createApiClient } from "../../common/api/client.js";
|
|
2
|
+
import { printJsonToConsoleAndExitGracefully, printResultToConsole, } from "../../common/output.js";
|
|
3
|
+
export async function list(argv) {
|
|
4
|
+
const { account } = argv;
|
|
5
|
+
const client = createApiClient({ authToken: argv.authToken });
|
|
6
|
+
const response = await client.get(`/v1/accounts/${account}/client-mtls-ca-certificates`, {
|
|
7
|
+
operation: "Failed to list CA certificates",
|
|
8
|
+
errorMessage: "Error: Failed to list CA certificates.",
|
|
9
|
+
});
|
|
10
|
+
if (argv.output === "json") {
|
|
11
|
+
await printJsonToConsoleAndExitGracefully(response);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (response.data.length === 0) {
|
|
15
|
+
printResultToConsole("No CA certificates found");
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
printResultToConsole(`Found ${response.data.length} CA certificate(s):\n`);
|
|
19
|
+
for (const cert of response.data) {
|
|
20
|
+
const subject = cert.certificateInfo.subject.replace(/\n/g, ", ");
|
|
21
|
+
printResultToConsole(` ID: ${cert.id}\n` +
|
|
22
|
+
` Name: ${cert.name}\n` +
|
|
23
|
+
` Subject: ${subject}\n` +
|
|
24
|
+
` Valid from: ${cert.certificateInfo.validFrom}\n` +
|
|
25
|
+
` Valid to: ${cert.certificateInfo.validTo}\n`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/ca-certificate/list/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EACL,mCAAmC,EACnC,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAGhC,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,IAAmB;IAC5C,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAEzB,MAAM,MAAM,GAAG,eAAe,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,CAC/B,gBAAgB,OAAO,8BAA8B,EACrD;QACE,SAAS,EAAE,gCAAgC;QAC3C,YAAY,EAAE,wCAAwC;KACvD,CACF,CAAC;IAEF,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC3B,MAAM,mCAAmC,CAAC,QAAQ,CAAC,CAAC;QACpD,OAAO;IACT,CAAC;IAED,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,oBAAoB,CAAC,0BAA0B,CAAC,CAAC;QACjD,OAAO;IACT,CAAC;IAED,oBAAoB,CAAC,SAAS,QAAQ,CAAC,IAAI,CAAC,MAAM,uBAAuB,CAAC,CAAC;IAE3E,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClE,oBAAoB,CAClB,SAAS,IAAI,CAAC,EAAE,IAAI;YAClB,WAAW,IAAI,CAAC,IAAI,IAAI;YACxB,cAAc,OAAO,IAAI;YACzB,iBAAiB,IAAI,CAAC,eAAe,CAAC,SAAS,IAAI;YACnD,eAAe,IAAI,CAAC,eAAe,CAAC,OAAO,IAAI,CAClD,CAAC;IACJ,CAAC;AACH,CAAC","sourcesContent":["import { createApiClient } from \"../../common/api/client.js\";\nimport {\n printJsonToConsoleAndExitGracefully,\n printResultToConsole,\n} from \"../../common/output.js\";\nimport { CaCertificateListResponse, ListArguments } from \"../models.js\";\n\nexport async function list(argv: ListArguments) {\n const { account } = argv;\n\n const client = createApiClient({ authToken: argv.authToken });\n const response = await client.get<CaCertificateListResponse>(\n `/v1/accounts/${account}/client-mtls-ca-certificates`,\n {\n operation: \"Failed to list CA certificates\",\n errorMessage: \"Error: Failed to list CA certificates.\",\n }\n );\n\n if (argv.output === \"json\") {\n await printJsonToConsoleAndExitGracefully(response);\n return;\n }\n\n if (response.data.length === 0) {\n printResultToConsole(\"No CA certificates found\");\n return;\n }\n\n printResultToConsole(`Found ${response.data.length} CA certificate(s):\\n`);\n\n for (const cert of response.data) {\n const subject = cert.certificateInfo.subject.replace(/\\n/g, \", \");\n printResultToConsole(\n ` ID: ${cert.id}\\n` +\n ` Name: ${cert.name}\\n` +\n ` Subject: ${subject}\\n` +\n ` Valid from: ${cert.certificateInfo.validFrom}\\n` +\n ` Valid to: ${cert.certificateInfo.validTo}\\n`\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export interface CaCertificateInfo {
|
|
2
|
+
subject: string;
|
|
3
|
+
issuer: string;
|
|
4
|
+
validFrom: string;
|
|
5
|
+
validTo: string;
|
|
6
|
+
serialNumber: string;
|
|
7
|
+
}
|
|
8
|
+
export interface CaCertificate {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
certificateInfo: CaCertificateInfo;
|
|
12
|
+
createdOn: string;
|
|
13
|
+
updatedOn: string;
|
|
14
|
+
}
|
|
15
|
+
export interface CaCertificateListResponse {
|
|
16
|
+
data: CaCertificate[];
|
|
17
|
+
offset: number;
|
|
18
|
+
limit: number;
|
|
19
|
+
}
|
|
20
|
+
export interface CreateArguments {
|
|
21
|
+
account: string;
|
|
22
|
+
authToken: string;
|
|
23
|
+
name: string;
|
|
24
|
+
cert: string;
|
|
25
|
+
output?: "default" | "json";
|
|
26
|
+
}
|
|
27
|
+
export interface ListArguments {
|
|
28
|
+
account: string;
|
|
29
|
+
authToken: string;
|
|
30
|
+
output?: "default" | "json";
|
|
31
|
+
}
|
|
32
|
+
export interface UpdateArguments {
|
|
33
|
+
account: string;
|
|
34
|
+
authToken: string;
|
|
35
|
+
"cert-id": string;
|
|
36
|
+
name: string;
|
|
37
|
+
output?: "default" | "json";
|
|
38
|
+
}
|
|
39
|
+
export interface DeleteArguments {
|
|
40
|
+
account: string;
|
|
41
|
+
authToken: string;
|
|
42
|
+
"cert-id": string;
|
|
43
|
+
output?: "default" | "json";
|
|
44
|
+
}
|
|
45
|
+
export interface DescribeArguments {
|
|
46
|
+
account: string;
|
|
47
|
+
authToken: string;
|
|
48
|
+
"cert-id": string;
|
|
49
|
+
output?: "default" | "json";
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=models.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/ca-certificate/models.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,iBAAiB,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;CAC7B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/ca-certificate/models.ts"],"names":[],"mappings":"","sourcesContent":["export interface CaCertificateInfo {\n subject: string;\n issuer: string;\n validFrom: string;\n validTo: string;\n serialNumber: string;\n}\n\nexport interface CaCertificate {\n id: string;\n name: string;\n certificateInfo: CaCertificateInfo;\n createdOn: string;\n updatedOn: string;\n}\n\nexport interface CaCertificateListResponse {\n data: CaCertificate[];\n offset: number;\n limit: number;\n}\n\nexport interface CreateArguments {\n account: string;\n authToken: string;\n name: string;\n cert: string;\n output?: \"default\" | \"json\";\n}\n\nexport interface ListArguments {\n account: string;\n authToken: string;\n output?: \"default\" | \"json\";\n}\n\nexport interface UpdateArguments {\n account: string;\n authToken: string;\n \"cert-id\": string;\n name: string;\n output?: \"default\" | \"json\";\n}\n\nexport interface DeleteArguments {\n account: string;\n authToken: string;\n \"cert-id\": string;\n output?: \"default\" | \"json\";\n}\n\nexport interface DescribeArguments {\n account: string;\n authToken: string;\n \"cert-id\": string;\n output?: \"default\" | \"json\";\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/ca-certificate/update/handler.ts"],"names":[],"mappings":"AAMA,OAAO,EAAiB,eAAe,EAAE,MAAM,cAAc,CAAC;AAG9D,wBAAsB,MAAM,CAAC,IAAI,EAAE,eAAe,iBA8BjD"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createApiClient } from "../../common/api/client.js";
|
|
2
|
+
import { printDiagnosticsToConsole, printJsonToConsoleAndExitGracefully, printResultToConsole, } from "../../common/output.js";
|
|
3
|
+
import { validateName } from "../validation.js";
|
|
4
|
+
export async function update(argv) {
|
|
5
|
+
const { account } = argv;
|
|
6
|
+
const certId = argv["cert-id"];
|
|
7
|
+
const nameError = validateName(argv.name);
|
|
8
|
+
if (nameError) {
|
|
9
|
+
printDiagnosticsToConsole(`Error: --name is invalid. ${nameError.message}`);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const client = createApiClient({ authToken: argv.authToken });
|
|
13
|
+
const cert = await client.patch(`/v1/accounts/${account}/client-mtls-ca-certificates/${encodeURIComponent(certId)}`, {
|
|
14
|
+
operation: "Failed to update CA certificate",
|
|
15
|
+
errorMessage: "Error: Failed to update CA certificate.",
|
|
16
|
+
body: {
|
|
17
|
+
name: argv.name,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
if (argv.output === "json") {
|
|
21
|
+
await printJsonToConsoleAndExitGracefully(cert);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
printResultToConsole(`CA certificate '${cert.name}' (${cert.id}) updated successfully`);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/ca-certificate/update/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EACL,yBAAyB,EACzB,mCAAmC,EACnC,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAqB;IAChD,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACzB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;IAE/B,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,SAAS,EAAE,CAAC;QACd,yBAAyB,CAAC,6BAA6B,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5E,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,eAAe,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IAC9D,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,CAC7B,gBAAgB,OAAO,gCAAgC,kBAAkB,CAAC,MAAM,CAAC,EAAE,EACnF;QACE,SAAS,EAAE,iCAAiC;QAC5C,YAAY,EAAE,yCAAyC;QACvD,IAAI,EAAE;YACJ,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB;KACF,CACF,CAAC;IAEF,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC3B,MAAM,mCAAmC,CAAC,IAAI,CAAC,CAAC;QAChD,OAAO;IACT,CAAC;IAED,oBAAoB,CAClB,mBAAmB,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,wBAAwB,CAClE,CAAC;AACJ,CAAC","sourcesContent":["import { createApiClient } from \"../../common/api/client.js\";\nimport {\n printDiagnosticsToConsole,\n printJsonToConsoleAndExitGracefully,\n printResultToConsole,\n} from \"../../common/output.js\";\nimport { CaCertificate, UpdateArguments } from \"../models.js\";\nimport { validateName } from \"../validation.js\";\n\nexport async function update(argv: UpdateArguments) {\n const { account } = argv;\n const certId = argv[\"cert-id\"];\n\n const nameError = validateName(argv.name);\n if (nameError) {\n printDiagnosticsToConsole(`Error: --name is invalid. ${nameError.message}`);\n return;\n }\n\n const client = createApiClient({ authToken: argv.authToken });\n const cert = await client.patch<CaCertificate>(\n `/v1/accounts/${account}/client-mtls-ca-certificates/${encodeURIComponent(certId)}`,\n {\n operation: \"Failed to update CA certificate\",\n errorMessage: \"Error: Failed to update CA certificate.\",\n body: {\n name: argv.name,\n },\n }\n );\n\n if (argv.output === \"json\") {\n await printJsonToConsoleAndExitGracefully(cert);\n return;\n }\n\n printResultToConsole(\n `CA certificate '${cert.name}' (${cert.id}) updated successfully`\n );\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface ValidationError {
|
|
2
|
+
message: string;
|
|
3
|
+
hint?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function validateName(name: string): ValidationError | null;
|
|
6
|
+
export interface PemCertificateDetails {
|
|
7
|
+
subject: string;
|
|
8
|
+
issuer: string;
|
|
9
|
+
validFrom: string;
|
|
10
|
+
validTo: string;
|
|
11
|
+
serialNumber: string;
|
|
12
|
+
isCa: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare function parseAndValidateCaCertificate(
|
|
15
|
+
pem: string,
|
|
16
|
+
now?: Date
|
|
17
|
+
): PemCertificateDetails | ValidationError;
|
|
18
|
+
export declare function isValidationError(
|
|
19
|
+
result: PemCertificateDetails | ValidationError
|
|
20
|
+
): result is ValidationError;
|
|
21
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/ca-certificate/validation.ts"],"names":[],"mappings":"AAwDA,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAID,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAmBjE;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,OAAO,CAAC;CACf;AAMD,wBAAgB,6BAA6B,CAC3C,GAAG,EAAE,MAAM,EACX,GAAG,GAAE,IAAiB,GACrB,qBAAqB,GAAG,eAAe,CAsEzC;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,qBAAqB,GAAG,eAAe,GAC9C,MAAM,IAAI,eAAe,CAE3B"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
const MAX_NAME_LENGTH = 120;
|
|
3
|
+
const PEM_BEGIN = "-----BEGIN CERTIFICATE-----";
|
|
4
|
+
const PEM_END = "-----END CERTIFICATE-----";
|
|
5
|
+
const JS_VARIABLE_REGEX = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
|
|
6
|
+
const JS_RESERVED_KEYWORDS = new Set([
|
|
7
|
+
"break",
|
|
8
|
+
"case",
|
|
9
|
+
"catch",
|
|
10
|
+
"class",
|
|
11
|
+
"const",
|
|
12
|
+
"continue",
|
|
13
|
+
"debugger",
|
|
14
|
+
"default",
|
|
15
|
+
"delete",
|
|
16
|
+
"do",
|
|
17
|
+
"else",
|
|
18
|
+
"export",
|
|
19
|
+
"extends",
|
|
20
|
+
"finally",
|
|
21
|
+
"for",
|
|
22
|
+
"function",
|
|
23
|
+
"if",
|
|
24
|
+
"import",
|
|
25
|
+
"in",
|
|
26
|
+
"instanceof",
|
|
27
|
+
"let",
|
|
28
|
+
"new",
|
|
29
|
+
"return",
|
|
30
|
+
"super",
|
|
31
|
+
"switch",
|
|
32
|
+
"this",
|
|
33
|
+
"throw",
|
|
34
|
+
"try",
|
|
35
|
+
"typeof",
|
|
36
|
+
"var",
|
|
37
|
+
"void",
|
|
38
|
+
"while",
|
|
39
|
+
"with",
|
|
40
|
+
"yield",
|
|
41
|
+
"enum",
|
|
42
|
+
"implements",
|
|
43
|
+
"interface",
|
|
44
|
+
"package",
|
|
45
|
+
"private",
|
|
46
|
+
"protected",
|
|
47
|
+
"public",
|
|
48
|
+
"static",
|
|
49
|
+
"await",
|
|
50
|
+
]);
|
|
51
|
+
export function validateName(name) {
|
|
52
|
+
if (name.length === 0) {
|
|
53
|
+
return { message: "Name cannot be empty" };
|
|
54
|
+
}
|
|
55
|
+
if (name.length > MAX_NAME_LENGTH) {
|
|
56
|
+
return {
|
|
57
|
+
message: `Name must be ${MAX_NAME_LENGTH} characters or fewer (got ${name.length})`,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
if (!JS_VARIABLE_REGEX.test(name)) {
|
|
61
|
+
return {
|
|
62
|
+
message: "Name must be a valid JavaScript variable name (start with a letter, _, or $, and contain only letters, digits, _, or $)",
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
if (JS_RESERVED_KEYWORDS.has(name.toLowerCase())) {
|
|
66
|
+
return { message: "Name cannot be a JavaScript reserved keyword" };
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
export function parseAndValidateCaCertificate(pem, now = new Date()) {
|
|
71
|
+
if (!pem.includes(PEM_BEGIN) || !pem.includes(PEM_END)) {
|
|
72
|
+
if (/-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----/.test(pem)) {
|
|
73
|
+
return {
|
|
74
|
+
message: "File is a private key, not a certificate",
|
|
75
|
+
hint: "The `--cert` flag expects the public CA certificate, not a private key. " +
|
|
76
|
+
"CA certs only contain the public half; the private key stays with your PKI. " +
|
|
77
|
+
"If your CA is bundled in a single PEM file, pass it as-is — the certificate block will be picked up.",
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
if (/-----BEGIN CERTIFICATE REQUEST-----/.test(pem)) {
|
|
81
|
+
return {
|
|
82
|
+
message: "File is a certificate signing request (CSR), not a certificate",
|
|
83
|
+
hint: "A CSR is the request you send to a CA to get a certificate issued. Pass the issued CA certificate instead.",
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
if (/-----BEGIN [A-Z0-9 ]+-----/.test(pem)) {
|
|
87
|
+
return {
|
|
88
|
+
message: "File is a PEM block but not a certificate",
|
|
89
|
+
hint: `Expected a PEM block starting with "${PEM_BEGIN}".`,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
message: "File does not appear to be a PEM-encoded certificate",
|
|
94
|
+
hint: `Expected to find "${PEM_BEGIN}" and "${PEM_END}" in the file.\n` +
|
|
95
|
+
"If you have a DER-encoded certificate, convert it with:\n" +
|
|
96
|
+
" openssl x509 -in <file> -inform der -out cert.pem",
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
let cert;
|
|
100
|
+
try {
|
|
101
|
+
cert = new crypto.X509Certificate(pem);
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
return {
|
|
105
|
+
message: "Failed to parse certificate",
|
|
106
|
+
hint: err instanceof Error ? err.message : String(err),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
if (!cert.ca) {
|
|
110
|
+
return {
|
|
111
|
+
message: "The certificate is not a CA certificate",
|
|
112
|
+
hint: "Expected a certificate with the CA basic constraint set to TRUE " +
|
|
113
|
+
"(typically the root or intermediate CA that signs your client certs), " +
|
|
114
|
+
"not a leaf/client certificate.",
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
const validTo = new Date(cert.validTo);
|
|
118
|
+
if (!Number.isNaN(validTo.getTime()) && validTo < now) {
|
|
119
|
+
return {
|
|
120
|
+
message: `Certificate has already expired (validTo=${cert.validTo})`,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
subject: cert.subject,
|
|
125
|
+
issuer: cert.issuer,
|
|
126
|
+
validFrom: cert.validFrom,
|
|
127
|
+
validTo: cert.validTo,
|
|
128
|
+
serialNumber: cert.serialNumber,
|
|
129
|
+
isCa: cert.ca,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
export function isValidationError(result) {
|
|
133
|
+
return "message" in result;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/ca-certificate/validation.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from \"node:crypto\";\n\nconst MAX_NAME_LENGTH = 120;\nconst PEM_BEGIN = \"-----BEGIN CERTIFICATE-----\";\nconst PEM_END = \"-----END CERTIFICATE-----\";\nconst JS_VARIABLE_REGEX = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;\n\n// Kept in sync with tenant-api's reservedKeywords list in\n// apps/tenant-api/src/utils/certificate-validation.ts. Updating one without\n// the other lets bad names slip past the CLI and fail on the server.\nconst JS_RESERVED_KEYWORDS = new Set([\n \"break\",\n \"case\",\n \"catch\",\n \"class\",\n \"const\",\n \"continue\",\n \"debugger\",\n \"default\",\n \"delete\",\n \"do\",\n \"else\",\n \"export\",\n \"extends\",\n \"finally\",\n \"for\",\n \"function\",\n \"if\",\n \"import\",\n \"in\",\n \"instanceof\",\n \"let\",\n \"new\",\n \"return\",\n \"super\",\n \"switch\",\n \"this\",\n \"throw\",\n \"try\",\n \"typeof\",\n \"var\",\n \"void\",\n \"while\",\n \"with\",\n \"yield\",\n \"enum\",\n \"implements\",\n \"interface\",\n \"package\",\n \"private\",\n \"protected\",\n \"public\",\n \"static\",\n \"await\",\n]);\n\nexport interface ValidationError {\n message: string;\n hint?: string;\n}\n\n// Mirrors tenant-api's validateCertificateName so the CLI rejects bad names\n// before a network round trip.\nexport function validateName(name: string): ValidationError | null {\n if (name.length === 0) {\n return { message: \"Name cannot be empty\" };\n }\n if (name.length > MAX_NAME_LENGTH) {\n return {\n message: `Name must be ${MAX_NAME_LENGTH} characters or fewer (got ${name.length})`,\n };\n }\n if (!JS_VARIABLE_REGEX.test(name)) {\n return {\n message:\n \"Name must be a valid JavaScript variable name (start with a letter, _, or $, and contain only letters, digits, _, or $)\",\n };\n }\n if (JS_RESERVED_KEYWORDS.has(name.toLowerCase())) {\n return { message: \"Name cannot be a JavaScript reserved keyword\" };\n }\n return null;\n}\n\nexport interface PemCertificateDetails {\n subject: string;\n issuer: string;\n validFrom: string;\n validTo: string;\n serialNumber: string;\n isCa: boolean;\n}\n\n// Mirrors tenant-api's parseCertificateWithDetails. Returns the parsed\n// certificate details or a ValidationError that the CLI can surface directly,\n// avoiding a round trip when the input is obviously wrong.\n// `now` is injectable for testing the expiry branch portably.\nexport function parseAndValidateCaCertificate(\n pem: string,\n now: Date = new Date()\n): PemCertificateDetails | ValidationError {\n if (!pem.includes(PEM_BEGIN) || !pem.includes(PEM_END)) {\n // Detect common PEM header variants so the hint actually matches the\n // mistake the user made.\n if (/-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----/.test(pem)) {\n return {\n message: \"File is a private key, not a certificate\",\n hint:\n \"The `--cert` flag expects the public CA certificate, not a private key. \" +\n \"CA certs only contain the public half; the private key stays with your PKI. \" +\n \"If your CA is bundled in a single PEM file, pass it as-is — the certificate block will be picked up.\",\n };\n }\n if (/-----BEGIN CERTIFICATE REQUEST-----/.test(pem)) {\n return {\n message:\n \"File is a certificate signing request (CSR), not a certificate\",\n hint: \"A CSR is the request you send to a CA to get a certificate issued. Pass the issued CA certificate instead.\",\n };\n }\n if (/-----BEGIN [A-Z0-9 ]+-----/.test(pem)) {\n return {\n message: \"File is a PEM block but not a certificate\",\n hint: `Expected a PEM block starting with \"${PEM_BEGIN}\".`,\n };\n }\n return {\n message: \"File does not appear to be a PEM-encoded certificate\",\n hint:\n `Expected to find \"${PEM_BEGIN}\" and \"${PEM_END}\" in the file.\\n` +\n \"If you have a DER-encoded certificate, convert it with:\\n\" +\n \" openssl x509 -in <file> -inform der -out cert.pem\",\n };\n }\n\n let cert: crypto.X509Certificate;\n try {\n cert = new crypto.X509Certificate(pem);\n } catch (err) {\n return {\n message: \"Failed to parse certificate\",\n hint: err instanceof Error ? err.message : String(err),\n };\n }\n\n if (!cert.ca) {\n return {\n message: \"The certificate is not a CA certificate\",\n hint:\n \"Expected a certificate with the CA basic constraint set to TRUE \" +\n \"(typically the root or intermediate CA that signs your client certs), \" +\n \"not a leaf/client certificate.\",\n };\n }\n\n const validTo = new Date(cert.validTo);\n if (!Number.isNaN(validTo.getTime()) && validTo < now) {\n return {\n message: `Certificate has already expired (validTo=${cert.validTo})`,\n };\n }\n\n return {\n subject: cert.subject,\n issuer: cert.issuer,\n validFrom: cert.validFrom,\n validTo: cert.validTo,\n serialNumber: cert.serialNumber,\n isCa: cert.ca,\n };\n}\n\nexport function isValidationError(\n result: PemCertificateDetails | ValidationError\n): result is ValidationError {\n return \"message\" in result;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.test.d.ts","sourceRoot":"","sources":["../../src/ca-certificate/validation.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import assert from "node:assert";
|
|
2
|
+
import { describe, it } from "node:test";
|
|
3
|
+
import { isValidationError, parseAndValidateCaCertificate, validateName, } from "./validation.js";
|
|
4
|
+
const CA_PEM = `-----BEGIN CERTIFICATE-----
|
|
5
|
+
MIIC5jCCAc6gAwIBAgIUB4s5BPjuGshWHSZKkNIJJ7W7alkwDQYJKoZIhvcNAQEL
|
|
6
|
+
BQAwEjEQMA4GA1UEAwwHVGVzdCBjYTAgFw0yNjA1MTMwMDA1NDFaGA8yMTI2MDQx
|
|
7
|
+
OTAwMDU0MVowEjEQMA4GA1UEAwwHVGVzdCBjYTCCASIwDQYJKoZIhvcNAQEBBQAD
|
|
8
|
+
ggEPADCCAQoCggEBAK+8kcIOYXC5SKCnnEmddLKiVSon8NoLn8RABel0op+5i3J2
|
|
9
|
+
pnDBBWOy2nT5qWRI2N0tTK4tQn/jaGeiBP0BUu4z+Y/pcglveexyFWhtFstHyyUr
|
|
10
|
+
yiwhBhX3NEWHZGr/VShriKxojnTwWONpgQwq7On7k+We3JK7IEASvKLxhC1+hcch
|
|
11
|
+
CwP67zGDF6qJrfjBfdPSRoW8OomioTRyb7MyrWvRpKm/0rj9NYc7MxMYbgVffE6y
|
|
12
|
+
IVQ4UCsVw74DdebfdzBSJOwNa+2Fe8AwQ3QMVbzfE3qs6+nviQ1EJA/h0kWgIrCI
|
|
13
|
+
3JvGpJinI0kDXEYx/4BTHVNfg1UdCOqPxxdrS18CAwEAAaMyMDAwDwYDVR0TAQH/
|
|
14
|
+
BAUwAwEB/zAdBgNVHQ4EFgQUuku+yW29ASY8vCZ7fBVA6L3r28YwDQYJKoZIhvcN
|
|
15
|
+
AQELBQADggEBAFaYAde91xdpST+LlokhbWanr8xiUr7jdHemjxGvBi/Zxs2VQIj2
|
|
16
|
+
+1Bh0dpxGk670nSc/Bq8jcivoiGoaRxT5rFVhtQOpYLgo+wKqNoYfEoEPrIrT4PO
|
|
17
|
+
seBrdMa9cduhs/Nx11Vgf5N56KomRO1a4AaIcvh6uGxrf1jfaCjaAKWTNNd9luzo
|
|
18
|
+
/IsRikl4QN0pZ1lIxdOdVMFhCp8V/+oEO6aw2FhFZlZKA+XLELHQzPBpuubQocuT
|
|
19
|
+
9dLovPbpFD2UwgvpjXQYjpr5btZx+iupHfiXq7WI6EI3eG5UgTuOpK8g9rLDiX9f
|
|
20
|
+
ArcSyj6/ZV+MDtaEHyEJBdsp//aT6Kfpoek=
|
|
21
|
+
-----END CERTIFICATE-----
|
|
22
|
+
`;
|
|
23
|
+
const LEAF_PEM = `-----BEGIN CERTIFICATE-----
|
|
24
|
+
MIIC5zCCAc+gAwIBAgIUFG0P6P6J4YoBLyRH2pjt7RdV9sAwDQYJKoZIhvcNAQEL
|
|
25
|
+
BQAwFDESMBAGA1UEAwwJVGVzdCBsZWFmMCAXDTI2MDUxMzAwMDU0MVoYDzIxMjYw
|
|
26
|
+
NDE5MDAwNTQxWjAUMRIwEAYDVQQDDAlUZXN0IGxlYWYwggEiMA0GCSqGSIb3DQEB
|
|
27
|
+
AQUAA4IBDwAwggEKAoIBAQDc1H+Z9qbmSsTR1tDVEvMN94ayec1UZ/17eIDY55ho
|
|
28
|
+
N5UA3Blho2xLeXvWWpKpo6wTXONzpNak8qhccIGsuIogpparkYYPBG+86cofnGDC
|
|
29
|
+
m/T9wa8eLTvyrIyPfUjkYVU7Gfmsq08pF/GZHIHcJg/xdTOLKE8WgJi15zwi1ZOE
|
|
30
|
+
z/OtpGKlX2pnM7aq6mzUqamWo2WBPpFdtdLfCBtnUkoNtxWmn98Xj/AaoiBR0UAI
|
|
31
|
+
C8UQAEAv3yaZ8pBZoLLn68kFgkOdNAPnX2zi6B6uk7LWA90JUneL+fPb/89muxl+
|
|
32
|
+
uQ4NGgWINtG23OtELLtUIuNiZxEFEO0mxf+0pIYa/1VTAgMBAAGjLzAtMAwGA1Ud
|
|
33
|
+
EwEB/wQCMAAwHQYDVR0OBBYEFP5YdepOBrpmYPdem5awTb3ByLZ7MA0GCSqGSIb3
|
|
34
|
+
DQEBCwUAA4IBAQBZ9Bl8IcQ9VYxTQgO1U9wB+LcHJ2WXqVSQTlz+qwd+tyfnv0PM
|
|
35
|
+
O5/ouSYiCj3IBQ42N3z+QhLgZgvfGcC6qFvG67A1WV7n7ZV5D7Yb9CqE+NPUbx3V
|
|
36
|
+
3GFBkIAv7U+4TKYPSK2YPXCb/D3rtel2j31tcMtODoT0LrHbwaOCGd8G+15rxBjP
|
|
37
|
+
dfHuC/nYYeKsplDhcdfemel73WbNzuqGNliQhEqhtlpGOhciHpd1Zlm7OgUINmCr
|
|
38
|
+
rfRfSGvBGDkuNRQIEhnFZXYhD0iCM/6D56/VykaqaQz+bPr04d0e0KvusFGsmapN
|
|
39
|
+
zC0Ztm1aNp0wB0vPNoEJrpQEmkB80cR1DXVR
|
|
40
|
+
-----END CERTIFICATE-----
|
|
41
|
+
`;
|
|
42
|
+
describe("validateName", () => {
|
|
43
|
+
it("accepts valid names", () => {
|
|
44
|
+
assert.strictEqual(validateName("my_ca"), null);
|
|
45
|
+
assert.strictEqual(validateName("CA1"), null);
|
|
46
|
+
assert.strictEqual(validateName("$abc"), null);
|
|
47
|
+
assert.strictEqual(validateName("_underscore"), null);
|
|
48
|
+
});
|
|
49
|
+
it("rejects empty names", () => {
|
|
50
|
+
const result = validateName("");
|
|
51
|
+
assert.ok(result);
|
|
52
|
+
assert.match(result.message, /empty/i);
|
|
53
|
+
});
|
|
54
|
+
it("rejects names over 120 characters", () => {
|
|
55
|
+
const result = validateName("a".repeat(121));
|
|
56
|
+
assert.ok(result);
|
|
57
|
+
assert.match(result.message, /120 characters/);
|
|
58
|
+
});
|
|
59
|
+
it("rejects names starting with a digit", () => {
|
|
60
|
+
const result = validateName("1ca");
|
|
61
|
+
assert.ok(result);
|
|
62
|
+
assert.match(result.message, /JavaScript variable name/);
|
|
63
|
+
});
|
|
64
|
+
it("rejects names with hyphens or spaces", () => {
|
|
65
|
+
assert.ok(validateName("my-ca"));
|
|
66
|
+
assert.ok(validateName("my ca"));
|
|
67
|
+
assert.ok(validateName("ca.example"));
|
|
68
|
+
});
|
|
69
|
+
it("rejects JavaScript reserved keywords", () => {
|
|
70
|
+
for (const keyword of ["class", "delete", "import", "return", "await"]) {
|
|
71
|
+
const result = validateName(keyword);
|
|
72
|
+
assert.ok(result, `expected ${keyword} to be rejected`);
|
|
73
|
+
assert.match(result.message, /reserved keyword/);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
it("rejects reserved keywords case-insensitively", () => {
|
|
77
|
+
assert.ok(validateName("CLASS"));
|
|
78
|
+
assert.ok(validateName("Delete"));
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
describe("parseAndValidateCaCertificate", () => {
|
|
82
|
+
it("rejects garbage input", () => {
|
|
83
|
+
const result = parseAndValidateCaCertificate("not a certificate");
|
|
84
|
+
assert.ok(isValidationError(result));
|
|
85
|
+
assert.match(result.message, /PEM-encoded/);
|
|
86
|
+
assert.match(result.hint ?? "", /openssl x509.*-inform der/);
|
|
87
|
+
});
|
|
88
|
+
it("rejects a PKCS#8 private key with a key-specific hint", () => {
|
|
89
|
+
const pem = `-----BEGIN PRIVATE KEY-----\nfoo\n-----END PRIVATE KEY-----`;
|
|
90
|
+
const result = parseAndValidateCaCertificate(pem);
|
|
91
|
+
assert.ok(isValidationError(result));
|
|
92
|
+
assert.match(result.message, /private key/i);
|
|
93
|
+
assert.match(result.hint ?? "", /public CA certificate/);
|
|
94
|
+
});
|
|
95
|
+
it("rejects an RSA private key with a key-specific hint", () => {
|
|
96
|
+
const pem = `-----BEGIN RSA PRIVATE KEY-----\nfoo\n-----END RSA PRIVATE KEY-----`;
|
|
97
|
+
const result = parseAndValidateCaCertificate(pem);
|
|
98
|
+
assert.ok(isValidationError(result));
|
|
99
|
+
assert.match(result.message, /private key/i);
|
|
100
|
+
});
|
|
101
|
+
it("rejects a CSR with a CSR-specific hint", () => {
|
|
102
|
+
const pem = `-----BEGIN CERTIFICATE REQUEST-----\nfoo\n-----END CERTIFICATE REQUEST-----`;
|
|
103
|
+
const result = parseAndValidateCaCertificate(pem);
|
|
104
|
+
assert.ok(isValidationError(result));
|
|
105
|
+
assert.match(result.message, /CSR|signing request/i);
|
|
106
|
+
});
|
|
107
|
+
it("rejects a PEM-shaped but corrupt certificate", () => {
|
|
108
|
+
const pem = `-----BEGIN CERTIFICATE-----\nnot-real-base64\n-----END CERTIFICATE-----`;
|
|
109
|
+
const result = parseAndValidateCaCertificate(pem);
|
|
110
|
+
assert.ok(isValidationError(result));
|
|
111
|
+
assert.match(result.message, /Failed to parse/);
|
|
112
|
+
});
|
|
113
|
+
it("accepts a valid CA certificate", () => {
|
|
114
|
+
const result = parseAndValidateCaCertificate(CA_PEM);
|
|
115
|
+
assert.ok(!isValidationError(result), JSON.stringify(result));
|
|
116
|
+
assert.strictEqual(result.isCa, true);
|
|
117
|
+
assert.match(result.subject, /Test ca/i);
|
|
118
|
+
});
|
|
119
|
+
it("rejects a leaf (non-CA) certificate", () => {
|
|
120
|
+
const result = parseAndValidateCaCertificate(LEAF_PEM);
|
|
121
|
+
assert.ok(isValidationError(result));
|
|
122
|
+
assert.match(result.message, /not a CA certificate/);
|
|
123
|
+
});
|
|
124
|
+
it("rejects a CA certificate that is expired relative to `now`", () => {
|
|
125
|
+
const farFuture = new Date("2200-01-01T00:00:00Z");
|
|
126
|
+
const result = parseAndValidateCaCertificate(CA_PEM, farFuture);
|
|
127
|
+
assert.ok(isValidationError(result));
|
|
128
|
+
assert.match(result.message, /expired/);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
//# sourceMappingURL=validation.test.js.map
|