@numa-tech/numa 1.26.14 → 1.26.16

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.
@@ -0,0 +1,283 @@
1
+ import { type AuthConfig } from "../config.js";
2
+ import { type KeycloakTokenProvider } from "../oauth.js";
3
+ import { type CertificateInput, type EndpointInput, type FindingInput, type PageInput } from "./schemas.js";
4
+ export interface CertDependencies {
5
+ config?: () => AuthConfig;
6
+ initializeProfile?: () => Promise<void>;
7
+ tokenProvider?: KeycloakTokenProvider;
8
+ fetch?: typeof fetch;
9
+ }
10
+ /** Fixed public stored reads only. Authentication uses the existing current-platform identity. */
11
+ export declare class CertClient {
12
+ private readonly dependencies;
13
+ constructor(dependencies?: CertDependencies);
14
+ private request;
15
+ listCertificates(options?: CertificateInput): Promise<{
16
+ items: {
17
+ fingerprint: string;
18
+ commonName: string | null;
19
+ sans: string[];
20
+ issuer: string | null;
21
+ serial: string | null;
22
+ notBefore: string | null;
23
+ notAfter: string | null;
24
+ publicKeyFingerprint: string | null;
25
+ publicKeyScheme: string | null;
26
+ provenance: string | null;
27
+ status: "ACTIVE" | "OBSERVED_ONLY" | "RETIRED" | "SUPERSEDED" | null;
28
+ supersededBy: string | null;
29
+ }[];
30
+ total: number;
31
+ page: number;
32
+ size: number;
33
+ }>;
34
+ readCertificate(value: string, options?: PageInput): Promise<{
35
+ certificate: {
36
+ fingerprint: string;
37
+ commonName: string | null;
38
+ sans: string[];
39
+ issuer: string | null;
40
+ serial: string | null;
41
+ notBefore: string | null;
42
+ notAfter: string | null;
43
+ publicKeyFingerprint: string | null;
44
+ publicKeyScheme: string | null;
45
+ provenance: string | null;
46
+ status: "ACTIVE" | "OBSERVED_ONLY" | "RETIRED" | "SUPERSEDED" | null;
47
+ supersededBy: string | null;
48
+ };
49
+ endpoints: {
50
+ items: {
51
+ id: string;
52
+ hostname: string;
53
+ port: number;
54
+ ownerTeamId: string | null;
55
+ ownershipStatus: "CONFIRMED" | "PENDING";
56
+ managementSource: string;
57
+ environmentId: string | null;
58
+ tier: "DEV" | "PRD" | "STG" | "UNKNOWN" | null;
59
+ expectedFingerprint: string | null;
60
+ enabled: boolean;
61
+ version: number;
62
+ }[];
63
+ total: number;
64
+ page: number;
65
+ size: number;
66
+ };
67
+ copies: {
68
+ items: {
69
+ id: string;
70
+ accountId: string;
71
+ site: "CHINA" | "INTERNATIONAL";
72
+ casId: string;
73
+ certIdentifier: string | null;
74
+ name: string | null;
75
+ status: string | null;
76
+ fingerprint: string | null;
77
+ lastSeenAt: string;
78
+ removedAt: string | null;
79
+ }[];
80
+ total: number;
81
+ page: number;
82
+ size: number;
83
+ };
84
+ bindings: {
85
+ items: {
86
+ id: string;
87
+ accountId: string;
88
+ region: string;
89
+ albId: string;
90
+ albName: string | null;
91
+ listenerId: string;
92
+ port: number;
93
+ protocol: string;
94
+ certificateId: string;
95
+ defaultCertificate: boolean;
96
+ associationStatus: string | null;
97
+ managementSource: string | null;
98
+ lastSeenAt: string;
99
+ removedAt: string | null;
100
+ }[];
101
+ total: number;
102
+ page: number;
103
+ size: number;
104
+ };
105
+ }>;
106
+ listEndpoints(options?: EndpointInput): Promise<{
107
+ items: {
108
+ id: string;
109
+ hostname: string;
110
+ port: number;
111
+ ownerTeamId: string | null;
112
+ ownershipStatus: "CONFIRMED" | "PENDING";
113
+ managementSource: string;
114
+ environmentId: string | null;
115
+ tier: "DEV" | "PRD" | "STG" | "UNKNOWN" | null;
116
+ expectedFingerprint: string | null;
117
+ enabled: boolean;
118
+ version: number;
119
+ }[];
120
+ total: number;
121
+ page: number;
122
+ size: number;
123
+ }>;
124
+ readEndpoint(value: string, options?: PageInput): Promise<{
125
+ endpoint: {
126
+ id: string;
127
+ hostname: string;
128
+ port: number;
129
+ ownerTeamId: string | null;
130
+ ownershipStatus: "CONFIRMED" | "PENDING";
131
+ managementSource: string;
132
+ environmentId: string | null;
133
+ tier: "DEV" | "PRD" | "STG" | "UNKNOWN" | null;
134
+ expectedFingerprint: string | null;
135
+ enabled: boolean;
136
+ version: number;
137
+ };
138
+ bindings: {
139
+ items: {
140
+ id: string;
141
+ accountId: string;
142
+ region: string;
143
+ albId: string;
144
+ albName: string | null;
145
+ listenerId: string;
146
+ port: number;
147
+ protocol: string;
148
+ certificateId: string;
149
+ defaultCertificate: boolean;
150
+ associationStatus: string | null;
151
+ managementSource: string | null;
152
+ lastSeenAt: string;
153
+ removedAt: string | null;
154
+ }[];
155
+ total: number;
156
+ page: number;
157
+ size: number;
158
+ };
159
+ latestProbe: {
160
+ id: string;
161
+ runId: string;
162
+ attemptedAt: string;
163
+ observedAt: string | null;
164
+ outcome: "OBSERVED" | "UNKNOWN";
165
+ errorCode: string | null;
166
+ elapsedMs: number;
167
+ chain: {
168
+ fingerprint: string;
169
+ commonName: string | null;
170
+ sans: string[];
171
+ issuer: string | null;
172
+ serial: string | null;
173
+ notBefore: string | null;
174
+ notAfter: string | null;
175
+ publicKeyFingerprint: string | null;
176
+ publicKeyScheme: string | null;
177
+ provenance: string | null;
178
+ status: "ACTIVE" | "OBSERVED_ONLY" | "RETIRED" | "SUPERSEDED" | null;
179
+ supersededBy: string | null;
180
+ }[];
181
+ validity: "EXPIRED" | "NOT_YET_VALID" | "UNKNOWN" | "VALID";
182
+ hostname: "INVALID" | "UNKNOWN" | "VALID";
183
+ trust: "INVALID" | "UNKNOWN" | "VALID";
184
+ } | null;
185
+ observationStatus: "NOT_OBSERVED" | "OBSERVED" | "UNKNOWN";
186
+ }>;
187
+ probe(host: string, port?: string | number): Promise<{
188
+ endpoint: {
189
+ id: string;
190
+ hostname: string;
191
+ port: number;
192
+ ownerTeamId: string | null;
193
+ ownershipStatus: "CONFIRMED" | "PENDING";
194
+ managementSource: string;
195
+ environmentId: string | null;
196
+ tier: "DEV" | "PRD" | "STG" | "UNKNOWN" | null;
197
+ expectedFingerprint: string | null;
198
+ enabled: boolean;
199
+ version: number;
200
+ };
201
+ bindings: {
202
+ items: {
203
+ id: string;
204
+ accountId: string;
205
+ region: string;
206
+ albId: string;
207
+ albName: string | null;
208
+ listenerId: string;
209
+ port: number;
210
+ protocol: string;
211
+ certificateId: string;
212
+ defaultCertificate: boolean;
213
+ associationStatus: string | null;
214
+ managementSource: string | null;
215
+ lastSeenAt: string;
216
+ removedAt: string | null;
217
+ }[];
218
+ total: number;
219
+ page: number;
220
+ size: number;
221
+ };
222
+ latestProbe: {
223
+ id: string;
224
+ runId: string;
225
+ attemptedAt: string;
226
+ observedAt: string | null;
227
+ outcome: "OBSERVED" | "UNKNOWN";
228
+ errorCode: string | null;
229
+ elapsedMs: number;
230
+ chain: {
231
+ fingerprint: string;
232
+ commonName: string | null;
233
+ sans: string[];
234
+ issuer: string | null;
235
+ serial: string | null;
236
+ notBefore: string | null;
237
+ notAfter: string | null;
238
+ publicKeyFingerprint: string | null;
239
+ publicKeyScheme: string | null;
240
+ provenance: string | null;
241
+ status: "ACTIVE" | "OBSERVED_ONLY" | "RETIRED" | "SUPERSEDED" | null;
242
+ supersededBy: string | null;
243
+ }[];
244
+ validity: "EXPIRED" | "NOT_YET_VALID" | "UNKNOWN" | "VALID";
245
+ hostname: "INVALID" | "UNKNOWN" | "VALID";
246
+ trust: "INVALID" | "UNKNOWN" | "VALID";
247
+ } | null;
248
+ observationStatus: "NOT_OBSERVED" | "OBSERVED" | "UNKNOWN";
249
+ }>;
250
+ listFindings(options?: FindingInput): Promise<{
251
+ items: {
252
+ id: string;
253
+ type: "CHAIN_INVALID" | "DRIFT" | "EXPIRED_IN_USE" | "EXPIRED_STILL_BOUND" | "EXPIRING" | "HOSTNAME_MISMATCH" | "KEY_REUSED" | "ORPHAN_COPY" | "PROBE_UNAVAILABLE" | "RENEWAL_NOT_DEPLOYED" | "UNEXPECTED_CERT";
254
+ severity: "P1" | "P2" | "P3";
255
+ firstSeenAt: string;
256
+ lastSeenAt: string;
257
+ closedAt: string | null;
258
+ fingerprint: string | null;
259
+ replacementFingerprint: string | null;
260
+ notAfter: string | null;
261
+ endpointIds: {
262
+ items: string[];
263
+ total: number;
264
+ page: number;
265
+ size: number;
266
+ };
267
+ bindingIds: {
268
+ items: string[];
269
+ total: number;
270
+ page: number;
271
+ size: number;
272
+ };
273
+ notification: {
274
+ status: "ACCEPTED" | "CONFIGURATION_ERROR" | "CONFLICT" | "FAILED" | "NO_EVENT" | "PARTIAL" | "PENDING_RECIPIENTS" | "READY" | "RETRY" | "SENDING" | "UNKNOWN";
275
+ errorCode: string | null;
276
+ createdAt: string | null;
277
+ };
278
+ }[];
279
+ total: number;
280
+ page: number;
281
+ size: number;
282
+ }>;
283
+ }
@@ -0,0 +1,106 @@
1
+ import { loadConfig } from "../config.js";
2
+ import { currentPlatformProfile, initializePlatformProfile } from "../platform-profile.js";
3
+ import { resolveBackendUrl } from "../backend.js";
4
+ import { ensureAccessToken, fetchWithKeycloakIdentity } from "../oauth.js";
5
+ import { CertError } from "./errors.js";
6
+ import { certificateSchema, certificateDetailSchema, endpointSchema, endpointDetailSchema, findingSchema, pageSchema, certificateInput, endpointInput, findingInput, pageInput, fingerprint, identity, probeInput } from "./schemas.js";
7
+ const httpCodes = new Set(["TLS_INVALID_REQUEST", "TLS_TEAM_UNAVAILABLE", "TLS_ENVIRONMENT_UNAVAILABLE", "TLS_CERTIFICATE_UNAVAILABLE", "TLS_AUTHENTICATION_REQUIRED", "TLS_FEATURE_REQUIRED", "TLS_ADMIN_REQUIRED", "TLS_NOT_FOUND", "TLS_AUTHORIZATION_UNAVAILABLE", "TLS_INTERNAL_ERROR"]);
8
+ function platformTarget() {
9
+ if (currentPlatformProfile()?.stale)
10
+ throw new CertError("平台 Profile 已过期。", "TLS_CONFIGURATION_REQUIRED");
11
+ const auth = loadConfig("platform");
12
+ if (!auth.discoveryUrl || !auth.clientId?.trim())
13
+ throw new CertError("缺少当前平台身份配置。", "TLS_CONFIGURATION_REQUIRED");
14
+ if (auth.authenticationMode === "client_credentials" ? auth.clientId === "mcp-client" || Boolean(auth.clientSecret) === Boolean(auth.clientSecretFile) : Boolean(auth.clientSecret || auth.clientSecretFile))
15
+ throw new CertError("进程身份配置冲突;机器身份需独立 Client 和单一 Secret 来源。", "TLS_IDENTITY_CONFIGURATION_INVALID");
16
+ return auth;
17
+ }
18
+ async function readBounded(response, limit) {
19
+ const reader = response.body?.getReader();
20
+ if (!reader)
21
+ throw new Error("empty response");
22
+ const chunks = [];
23
+ let size = 0;
24
+ try {
25
+ while (true) {
26
+ const { value, done } = await reader.read();
27
+ if (done)
28
+ break;
29
+ size += value.length;
30
+ if (size > limit)
31
+ throw new Error("response limit");
32
+ chunks.push(value);
33
+ }
34
+ return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(Buffer.concat(chunks)));
35
+ }
36
+ finally {
37
+ await reader.cancel().catch(() => undefined);
38
+ reader.releaseLock();
39
+ }
40
+ }
41
+ /** Fixed public stored reads only. Authentication uses the existing current-platform identity. */
42
+ export class CertClient {
43
+ dependencies;
44
+ constructor(dependencies = {}) {
45
+ this.dependencies = dependencies;
46
+ }
47
+ async request(path, parameters, schema) {
48
+ let auth, url;
49
+ try {
50
+ if (this.dependencies.initializeProfile)
51
+ await this.dependencies.initializeProfile();
52
+ else if (!this.dependencies.config)
53
+ await initializePlatformProfile({ warn: message => process.stderr.write(`警告: ${message}\n`) });
54
+ auth = (this.dependencies.config ?? platformTarget)();
55
+ const query = new URLSearchParams(Object.entries(parameters).map(([key, value]) => [key, String(value)]));
56
+ url = resolveBackendUrl(auth, { method: "GET", path: `${path}${query.size ? `?${query}` : ""}` });
57
+ }
58
+ catch (error) {
59
+ if (error instanceof CertError)
60
+ throw error;
61
+ throw new CertError("当前平台身份或 API 配置无效;请求尚未发送。", "TLS_CONFIGURATION_REQUIRED");
62
+ }
63
+ let sent = false, token = "", response;
64
+ try {
65
+ response = await fetchWithKeycloakIdentity(auth, url, () => ({ method: "GET", redirect: "error", signal: AbortSignal.timeout(60_000), headers: { Accept: "application/json" } }), {
66
+ tokenProvider: async (config, refresh) => { token = await (this.dependencies.tokenProvider ?? ensureAccessToken)(config, refresh); return token; },
67
+ fetch: async (target, init) => { sent = true; return (this.dependencies.fetch ?? fetch)(target, init); }, retryUnauthorized: false,
68
+ });
69
+ }
70
+ catch (error) {
71
+ if (!sent && error instanceof Error && "code" in error && error.code === "login_required")
72
+ throw new CertError("当前平台身份需要认证;请求尚未发送。", auth.authenticationMode === "client_credentials" ? "TLS_MACHINE_AUTHENTICATION_REQUIRED" : "TLS_AUTHENTICATION_REQUIRED", 401);
73
+ throw new CertError(sent ? "无法读取 TLS 存储信息;未自动重试。" : "当前平台身份无法获取凭据;请求尚未发送。", sent ? "TLS_NETWORK_ERROR" : "TLS_IDENTITY_UNAVAILABLE");
74
+ }
75
+ const secrets = [token, auth.clientSecret].filter((value) => Boolean(value));
76
+ const rawRequestId = response.headers.get("x-request-id");
77
+ const requestId = rawRequestId && /^[A-Za-z0-9._:-]{1,128}$/u.test(rawRequestId) && !secrets.some(secret => rawRequestId.includes(secret)) ? rawRequestId : undefined;
78
+ let value;
79
+ try {
80
+ value = await readBounded(response, response.ok ? 1024 * 1024 : 16 * 1024);
81
+ }
82
+ catch {
83
+ if (response.ok)
84
+ throw new CertError("TLS 响应格式无效或超过大小限制。", "TLS_INVALID_RESPONSE", 502, requestId);
85
+ }
86
+ if (!response.ok) {
87
+ const upstream = value && typeof value === "object" && "code" in value && typeof value.code === "string" && httpCodes.has(value.code) ? value.code : undefined;
88
+ const code = response.status === 401 ? auth.authenticationMode === "client_credentials" ? "TLS_MACHINE_AUTHENTICATION_REQUIRED" : "TLS_AUTHENTICATION_REQUIRED"
89
+ : response.status === 403 ? upstream === "TLS_FEATURE_REQUIRED" || upstream === "TLS_ADMIN_REQUIRED" ? upstream : "TLS_ACCESS_DENIED"
90
+ : response.status === 404 ? "TLS_NOT_FOUND" : upstream ?? "TLS_HTTP_ERROR";
91
+ throw new CertError(`TLS API 读取失败(HTTP ${response.status},${code});未自动重试。`, code, response.status, requestId);
92
+ }
93
+ const parsed = schema.safeParse(value);
94
+ if (!parsed.success)
95
+ throw new CertError("TLS 响应不符合公开数据契约。", "TLS_INVALID_RESPONSE", 502, requestId);
96
+ // Project fields first; never render private additions or schema diagnostics/input values.
97
+ return JSON.parse(JSON.stringify(parsed.data).replace(/"(?:\\[\s\S]|[^"\\])*"/gu, literal => JSON.stringify(secrets.reduce((text, secret) => text.split(secret).join("[REDACTED]"), JSON.parse(literal)))));
98
+ }
99
+ async listCertificates(options = {}) { const query = certificateInput(options); return this.request("/api/v1/tls/certificates", query, pageSchema(certificateSchema)); }
100
+ async readCertificate(value, options = {}) { const key = fingerprint(value), query = pageInput(options); return this.request(`/api/v1/tls/certificates/${encodeURIComponent(key)}`, query, certificateDetailSchema); }
101
+ async listEndpoints(options = {}) { const query = endpointInput(options); return this.request("/api/v1/tls/endpoints", query, pageSchema(endpointSchema)); }
102
+ async readEndpoint(value, options = {}) { const key = identity(value), query = pageInput(options); return this.request(`/api/v1/tls/endpoints/${encodeURIComponent(key)}`, query, endpointDetailSchema); }
103
+ async probe(host, port = 443) { const query = probeInput(host, port); return this.request("/api/v1/tls/endpoints/observed", query, endpointDetailSchema); }
104
+ async listFindings(options = {}) { const query = findingInput(options); return this.request("/api/v1/tls/findings", query, pageSchema(findingSchema)); }
105
+ }
106
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/cert/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAmB,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAC3F,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAA8B,MAAM,aAAa,CAAC;AACvG,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,cAAc,EAAE,oBAAoB,EAAE,aAAa,EAAE,UAAU,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAgF,MAAM,cAAc,CAAC;AAGtT,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,qBAAqB,EAAE,sBAAsB,EAAE,6BAA6B,EAAE,6BAA6B,EAAE,6BAA6B,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,eAAe,EAAE,+BAA+B,EAAE,oBAAoB,CAAC,CAAC,CAAC;AAC9R,SAAS,cAAc;IACrB,IAAI,sBAAsB,EAAE,EAAE,KAAK;QAAE,MAAM,IAAI,SAAS,CAAC,iBAAiB,EAAE,4BAA4B,CAAC,CAAC;IAC1G,MAAM,IAAI,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IACpC,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE;QAAE,MAAM,IAAI,SAAS,CAAC,aAAa,EAAE,4BAA4B,CAAC,CAAC;IACnH,IAAI,IAAI,CAAC,kBAAkB,KAAK,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,KAAK,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,gBAAgB,CAAC;QAC1M,MAAM,IAAI,SAAS,CAAC,wCAAwC,EAAE,oCAAoC,CAAC,CAAC;IACtG,OAAO,IAAI,CAAC;AACd,CAAC;AACD,KAAK,UAAU,WAAW,CAAC,QAAkB,EAAE,KAAa;IAC1D,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC;IAAC,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAC1F,MAAM,MAAM,GAAiB,EAAE,CAAC;IAAC,IAAI,IAAI,GAAG,CAAC,CAAC;IAC9C,IAAI,CAAC;QACH,OAAO,IAAI,EAAE,CAAC;YAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YAAC,IAAI,IAAI;gBAAE,MAAM;YAAC,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC;YAAC,IAAI,IAAI,GAAG,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAAC,CAAC;QAC7K,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC7F,CAAC;YAAS,CAAC;QAAC,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAAC,MAAM,CAAC,WAAW,EAAE,CAAC;IAAC,CAAC;AACnF,CAAC;AACD,kGAAkG;AAClG,MAAM,OAAO,UAAU;IACQ,YAAY;IAAzC,YAA6B,YAAY,GAAqB,EAAE;4BAAnC,YAAY;IAA0B,CAAC;IAC5D,KAAK,CAAC,OAAO,CAAI,IAAY,EAAE,UAAkB,EAAE,MAAoB;QAC7E,IAAI,IAAgB,EAAE,GAAW,CAAC;QAClC,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,YAAY,CAAC,iBAAiB;gBAAE,MAAM,IAAI,CAAC,YAAY,CAAC,iBAAiB,EAAE,CAAC;iBAChF,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM;gBAAE,MAAM,yBAAyB,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC;YACnI,IAAI,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,IAAI,cAAc,CAAC,EAAE,CAAC;YACtD,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1G,GAAG,GAAG,iBAAiB,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACpG,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,SAAS;gBAAE,MAAM,KAAK,CAAC;YAC5C,MAAM,IAAI,SAAS,CAAC,0BAA0B,EAAE,4BAA4B,CAAC,CAAC;QAChF,CAAC;QACD,IAAI,IAAI,GAAG,KAAK,EAAE,KAAK,GAAG,EAAE,EAAE,QAAkB,CAAC;QACjD,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,yBAAyB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,EAAE,CAAC,EAAE;gBAChL,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,GAAG,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,aAAa,IAAI,iBAAiB,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC;gBAClJ,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,KAAK;aACnI,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,IAAI,IAAI,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB;gBACvF,MAAM,IAAI,SAAS,CAAC,oBAAoB,EAAE,IAAI,CAAC,kBAAkB,KAAK,oBAAoB,CAAC,CAAC,CAAC,qCAAqC,CAAC,CAAC,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;YAC3K,MAAM,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC;QACvI,CAAC;QACD,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9F,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC1D,MAAM,SAAS,GAAG,YAAY,IAAI,2BAA2B,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC;QACtK,IAAI,KAAc,CAAC;QACnB,IAAI,CAAC;YAAC,KAAK,GAAG,MAAM,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;QAAC,CAAC;QACnF,MAAM,CAAC;YAAC,IAAI,QAAQ,CAAC,EAAE;gBAAE,MAAM,IAAI,SAAS,CAAC,oBAAoB,EAAE,sBAAsB,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;QAAC,CAAC;QAC7G,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,QAAQ,GAAG,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;YAC/J,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,KAAK,oBAAoB,CAAC,CAAC,CAAC,qCAAqC,CAAC,CAAC,CAAC,6BAA6B;gBAC7J,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,KAAK,sBAAsB,IAAI,QAAQ,KAAK,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,mBAAmB;oBACrI,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,IAAI,gBAAgB,CAAC;YAC7E,MAAM,IAAI,SAAS,CAAC,qBAAqB,QAAQ,CAAC,MAAM,IAAI,IAAI,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAChH,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,MAAM,IAAI,SAAS,CAAC,kBAAkB,EAAE,sBAAsB,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;QACrG,2FAA2F;QAC3F,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,0BAA0B,EAAE,OAAO,CAAC,EAAE,CAC1F,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAW,CAAC,CAAC,CAAC,CAAM,CAAC;IAClI,CAAC;IACD,KAAK,CAAC,gBAAgB,CAAC,OAAO,GAAqB,EAAE,IAAI,MAAM,KAAK,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,0BAA0B,EAAE,KAAK,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1L,KAAK,CAAC,eAAe,CAAC,KAAa,EAAE,OAAO,GAAc,EAAE,IAAI,MAAM,GAAG,GAAG,WAAW,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,4BAA4B,kBAAkB,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,uBAAuB,CAAC,CAAC,CAAC,CAAC;IACzO,KAAK,CAAC,aAAa,CAAC,OAAO,GAAkB,EAAE,IAAI,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,uBAAuB,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3K,KAAK,CAAC,YAAY,CAAC,KAAa,EAAE,OAAO,GAAc,EAAE,IAAI,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,yBAAyB,kBAAkB,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC;IAC7N,KAAK,CAAC,KAAK,CAAC,IAAY,EAAE,IAAI,GAAoB,GAAG,IAAI,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,gCAAgC,EAAE,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC;IACpL,KAAK,CAAC,YAAY,CAAC,OAAO,GAAiB,EAAE,IAAI,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,sBAAsB,EAAE,KAAK,EAAE,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;CACvK"}
@@ -0,0 +1,7 @@
1
+ import type { Command } from "commander";
2
+ import { CertClient } from "./client.js";
3
+ export interface CertCommandDependencies {
4
+ clientFactory?: () => Pick<CertClient, "listCertificates" | "readCertificate" | "listEndpoints" | "readEndpoint" | "probe" | "listFindings">;
5
+ write?: (text: string) => void;
6
+ }
7
+ export declare function registerCertCommands(program: Command, dependencies?: CertCommandDependencies): void;
@@ -0,0 +1,47 @@
1
+ import { CertClient } from "./client.js";
2
+ import { CertError, certExitCode, certFailure } from "./errors.js";
3
+ import { certificateInput, endpointInput, findingInput, pageInput, expiring, fingerprint, identity, probeInput } from "./schemas.js";
4
+ export function registerCertCommands(program, dependencies = {}) {
5
+ const client = () => dependencies.clientFactory?.() ?? new CertClient();
6
+ const output = (value) => (dependencies.write ?? (text => process.stdout.write(text)))(`${JSON.stringify(value, null, 2)}\n`);
7
+ async function run(action, stored = false) {
8
+ try {
9
+ const data = await action();
10
+ const status = data && typeof data === "object" && "observationStatus" in data ? data.observationStatus : undefined;
11
+ output({ ok: true, data, ...(stored ? { observation: { source: "stored", current_health_verified: false,
12
+ message: status === "NOT_OBSERVED" ? "没有已存储的尝试。" : status === "UNKNOWN" ? "最新存储尝试的结果未知;请查看错误码与检查项。" : "读取历史存储观测;时间和显式检查项不保证当前健康。" } } : {}) });
13
+ }
14
+ catch (error) {
15
+ if (!(error instanceof CertError))
16
+ throw error;
17
+ output(certFailure(error));
18
+ process.exitCode = certExitCode(error);
19
+ }
20
+ }
21
+ const pages = (command) => command.option("--page <number>", "页码 1–1000000", "1").option("--size <number>", "每页 1–100 条", "20");
22
+ const cert = program.command("cert").description("读取平台 TLS 证书、端点、存储观测和风险发现")
23
+ .addHelpText("after", "\n沿用当前平台身份与 API;服务端校验 TLS view 功能授权及稳定团队/ops 范围。\n仅 GET 读取已存储信息,不发起 DNS/TLS 握手或云操作。\ndata 保留 API camelCase 字段、十进制字符串 ID 与嵌套 Page;不会自动遍历页。\n");
24
+ pages(cert.command("list").description("分页列出授权范围内的证书")
25
+ .option("--expiring <days>", "完整十进制天数 0d–3650d;0d 包括已过期证书,由服务端时钟计算")
26
+ .option("--query <text>", "字面子串,最长 253 字符"))
27
+ .action(async (options) => run(async () => {
28
+ const { expiring: duration, ...rest } = options;
29
+ const query = certificateInput({ ...rest, ...(duration === undefined ? {} : { expiringDays: expiring(duration) }) });
30
+ return client().listCertificates(query);
31
+ }));
32
+ pages(cert.command("read <fingerprint>").description("读取叶证书 SHA256 详情;page/size 分别作用于端点、副本和绑定"))
33
+ .action(async (value, options) => run(async () => { const key = fingerprint(value), query = pageInput(options); return client().readCertificate(key, query); }));
34
+ const endpoint = cert.command("endpoint").description("读取已注册 TLS 端点");
35
+ pages(endpoint.command("list").description("分页列出授权范围内的端点").option("--query <text>", "主机名字面子串").option("--team-id <id>", "稳定团队十进制字符串 ID"))
36
+ .action(async (options) => run(async () => { const query = endpointInput(options); return client().listEndpoints(query); }));
37
+ pages(endpoint.command("read <id>").description("读取稳定十进制字符串 ID 的端点与绑定页"))
38
+ .action(async (value, options) => run(async () => { const key = identity(value), query = pageInput(options); return client().readEndpoint(key, query); }, true));
39
+ cert.command("probe <host>").description("读取最新已存储的观测;不发起新的 DNS/TLS 握手")
40
+ .option("--port <number>", "只支持 443", "443")
41
+ .addHelpText("after", "\n读取最新已存储的观测。ASCII 主机名转小写并去末尾点;Unicode 语法在本地校验后保留,由服务端注册规则确定 IDNA 身份。NOT_OBSERVED 表示没有存储尝试,UNKNOWN 表示未知;请查看 attemptedAt/observedAt 与 validity/hostname/trust,不推断当前健康。\n")
42
+ .action(async (host, options) => run(async () => { const query = probeInput(host, options.port); return client().probe(query.hostname, query.port); }, true));
43
+ pages(cert.command("findings").description("分页列出风险发现;默认 OPEN").option("--type <type>", "发现类型(如 EXPIRING、PROBE_UNAVAILABLE)").option("--severity <severity>", "P1 / P2 / P3").option("--status <status>", "OPEN / CLOSED / ALL", "OPEN")
44
+ .addHelpText("after", "\n嵌套 endpointIds/bindingIds 为第一页证据。NO_EVENT 不代表通知已送达;ACCEPTED 仅表示供应商接受请求,不代表人员收到或已读。\n"))
45
+ .action(async (options) => run(async () => { const query = findingInput(options); return client().listFindings(query); }));
46
+ }
47
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/cert/commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /** CLI-owned messages and remediation; upstream error bodies are never rendered. */
2
+ export declare class CertError extends Error {
3
+ readonly code: string;
4
+ readonly status?: number | undefined;
5
+ readonly requestId?: string | undefined;
6
+ constructor(message: string, code: string, status?: number | undefined, requestId?: string | undefined);
7
+ }
8
+ export declare function certExitCode(error: CertError): number;
9
+ export declare function certFailure(error: CertError): {
10
+ ok: boolean;
11
+ status: string;
12
+ error: {
13
+ code: string;
14
+ message: string;
15
+ status: number | null;
16
+ request_id?: string | undefined;
17
+ };
18
+ execution: {
19
+ automatic_retry: boolean;
20
+ };
21
+ next_action: {
22
+ type: string;
23
+ message: string;
24
+ command?: undefined;
25
+ } | {
26
+ type: string;
27
+ command: string;
28
+ message: string;
29
+ };
30
+ };
@@ -0,0 +1,31 @@
1
+ /** CLI-owned messages and remediation; upstream error bodies are never rendered. */
2
+ export class CertError extends Error {
3
+ code;
4
+ status;
5
+ requestId;
6
+ constructor(message, code, status, requestId) {
7
+ super(message);
8
+ this.code = code;
9
+ this.status = status;
10
+ this.requestId = requestId;
11
+ this.name = "CertError";
12
+ }
13
+ }
14
+ export function certExitCode(error) {
15
+ return error.status === 401 ? 3 : error.status === 403 ? 4 : error.code === "TLS_INPUT_INVALID" || error.status === 400 ? 2 : 1;
16
+ }
17
+ export function certFailure(error) {
18
+ const input = error.code === "TLS_INPUT_INVALID" || error.status === 400;
19
+ const login = error.status === 401 && error.code !== "TLS_MACHINE_AUTHENTICATION_REQUIRED";
20
+ return {
21
+ ok: false, status: input ? "needs_input" : "blocked",
22
+ error: { code: error.code, message: error.message, status: error.status ?? null, ...(error.requestId ? { request_id: error.requestId } : {}) },
23
+ execution: { automatic_retry: false },
24
+ next_action: input ? { type: "correct_input", message: "修正参数后重试。" }
25
+ : login ? { type: "login", command: "numa login --platform", message: "使用当前平台身份登录后重试。" }
26
+ : error.status === 403 ? { type: "request_access", message: "请管理员检查 TLS 功能 view 授权及稳定团队归属;不要切换身份。" }
27
+ : error.status === 404 ? { type: "review_target", message: "目标不存在或当前身份不可见;核对目标及授权范围。" }
28
+ : { type: "contact_platform_admin", message: "将错误码交给平台管理员检查当前身份、平台配置或服务;CLI 未自动重试。" },
29
+ };
30
+ }
31
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/cert/errors.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,MAAM,OAAO,SAAU,SAAQ,KAAK;IACW,IAAI;IAA0B,MAAM;IAA2B,SAAS;IAArH,YAAY,OAAe,EAAkB,IAAY,EAAkB,MAAe,EAAkB,SAAkB;QAC5H,KAAK,CAAC,OAAO,CAAC,CAAC;oBAD4B,IAAI;sBAA0B,MAAM;yBAA2B,SAAS;QACnG,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IAC1C,CAAC;CACF;AACD,MAAM,UAAU,YAAY,CAAC,KAAgB;IAC3C,OAAO,KAAK,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,mBAAmB,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClI,CAAC;AACD,MAAM,UAAU,WAAW,CAAC,KAAgB;IAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,KAAK,mBAAmB,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,CAAC;IACzE,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,KAAK,qCAAqC,CAAC;IAC3F,OAAO;QACL,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS;QACpD,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;QAC9I,SAAS,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE;QACrC,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,UAAU,EAAE;YACjE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,uBAAuB,EAAE,OAAO,EAAE,gBAAgB,EAAE;gBACxF,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,sCAAsC,EAAE;oBACpG,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,0BAA0B,EAAE;wBACvF,CAAC,CAAC,EAAE,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,sCAAsC,EAAE;KACxF,CAAC;AACJ,CAAC"}