@checkstack/healthcheck-tls-backend 0.2.8 → 0.2.10
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/CHANGELOG.md +29 -0
- package/package.json +4 -4
- package/src/certificate-collector.test.ts +2 -2
- package/src/certificate-collector.ts +12 -0
- package/src/strategy.test.ts +7 -7
- package/src/strategy.ts +17 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# @checkstack/healthcheck-tls-backend
|
|
2
2
|
|
|
3
|
+
## 0.2.10
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 8d1ef12: ## Downstream consumer bumps for the anomaly detection + cache system rollout
|
|
8
|
+
|
|
9
|
+
Packages on this branch were updated as part of the anomaly detection feature (schema annotations on result fields, plugin metadata for the modular cache system) but were not listed in the upstream changesets.
|
|
10
|
+
|
|
11
|
+
- **`@checkstack/healthcheck-common`** (minor) — new RPC contract additions and schema changes supporting per-field anomaly metadata.
|
|
12
|
+
- **`@checkstack/cache-memory-common`** (minor) — new package providing access rules + plugin metadata for the in-memory cache backend.
|
|
13
|
+
- **healthcheck plugins** (patch) — adopt the new `x-anomaly-*` schema annotations on their result fields so anomaly detection works automatically against their checks. No public API changes.
|
|
14
|
+
- **integration / notification / auth / queue / collector plugins** (patch) — minor internal updates as consumers of upstream API changes (cache plugin registry, schema additions). No public API changes.
|
|
15
|
+
|
|
16
|
+
- Updated dependencies [8d1ef12]
|
|
17
|
+
- Updated dependencies [8d1ef12]
|
|
18
|
+
- Updated dependencies [8d1ef12]
|
|
19
|
+
- @checkstack/healthcheck-common@0.12.0
|
|
20
|
+
- @checkstack/common@0.7.0
|
|
21
|
+
- @checkstack/backend-api@0.13.0
|
|
22
|
+
|
|
23
|
+
## 0.2.9
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- Updated dependencies [26d8bae]
|
|
28
|
+
- Updated dependencies [26d8bae]
|
|
29
|
+
- @checkstack/healthcheck-common@0.11.0
|
|
30
|
+
- @checkstack/backend-api@0.12.0
|
|
31
|
+
|
|
3
32
|
## 0.2.8
|
|
4
33
|
|
|
5
34
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@checkstack/healthcheck-tls-backend",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"checkstack": {
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
"lint:code": "eslint . --max-warnings 0"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@checkstack/backend-api": "0.
|
|
16
|
-
"@checkstack/common": "0.6.
|
|
17
|
-
"@checkstack/healthcheck-common": "0.
|
|
15
|
+
"@checkstack/backend-api": "0.12.0",
|
|
16
|
+
"@checkstack/common": "0.6.5",
|
|
17
|
+
"@checkstack/healthcheck-common": "0.11.0"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"@types/bun": "^1.0.0",
|
|
@@ -7,7 +7,7 @@ import type {
|
|
|
7
7
|
|
|
8
8
|
describe("CertificateCollector", () => {
|
|
9
9
|
const createMockClient = (
|
|
10
|
-
response: Partial<TlsCertificateInfo> = {}
|
|
10
|
+
response: Partial<TlsCertificateInfo> = {},
|
|
11
11
|
): TlsTransportClient => ({
|
|
12
12
|
exec: mock(() =>
|
|
13
13
|
Promise.resolve({
|
|
@@ -20,7 +20,7 @@ describe("CertificateCollector", () => {
|
|
|
20
20
|
daysUntilExpiry: response.daysUntilExpiry ?? 365,
|
|
21
21
|
daysRemaining: response.daysRemaining ?? 365,
|
|
22
22
|
error: response.error,
|
|
23
|
-
})
|
|
23
|
+
}),
|
|
24
24
|
),
|
|
25
25
|
});
|
|
26
26
|
|
|
@@ -38,27 +38,35 @@ const certificateResultSchema = healthResultSchema({
|
|
|
38
38
|
subject: healthResultString({
|
|
39
39
|
"x-chart-type": "text",
|
|
40
40
|
"x-chart-label": "Subject",
|
|
41
|
+
"x-anomaly-enabled": false,
|
|
41
42
|
}),
|
|
42
43
|
issuer: healthResultString({
|
|
43
44
|
"x-chart-type": "text",
|
|
44
45
|
"x-chart-label": "Issuer",
|
|
46
|
+
"x-anomaly-enabled": false,
|
|
45
47
|
}),
|
|
46
48
|
validFrom: healthResultString({
|
|
47
49
|
"x-chart-type": "text",
|
|
48
50
|
"x-chart-label": "Valid From",
|
|
51
|
+
"x-anomaly-enabled": false,
|
|
49
52
|
}),
|
|
50
53
|
validTo: healthResultString({
|
|
51
54
|
"x-chart-type": "text",
|
|
52
55
|
"x-chart-label": "Valid To",
|
|
56
|
+
"x-anomaly-enabled": false,
|
|
53
57
|
}),
|
|
54
58
|
daysRemaining: healthResultNumber({
|
|
55
59
|
"x-chart-type": "gauge",
|
|
56
60
|
"x-chart-label": "Days Remaining",
|
|
57
61
|
"x-chart-unit": "days",
|
|
62
|
+
"x-anomaly-enabled": true,
|
|
63
|
+
"x-anomaly-direction": "higher-is-better",
|
|
58
64
|
}),
|
|
59
65
|
valid: healthResultBoolean({
|
|
60
66
|
"x-chart-type": "boolean",
|
|
61
67
|
"x-chart-label": "Valid",
|
|
68
|
+
"x-anomaly-enabled": true,
|
|
69
|
+
"x-anomaly-direction": "dominance",
|
|
62
70
|
}),
|
|
63
71
|
});
|
|
64
72
|
|
|
@@ -70,11 +78,15 @@ const certificateAggregatedFields = {
|
|
|
70
78
|
"x-chart-type": "gauge",
|
|
71
79
|
"x-chart-label": "Avg Days Remaining",
|
|
72
80
|
"x-chart-unit": "days",
|
|
81
|
+
"x-anomaly-enabled": true,
|
|
82
|
+
"x-anomaly-direction": "higher-is-better",
|
|
73
83
|
}),
|
|
74
84
|
validRate: aggregatedRate({
|
|
75
85
|
"x-chart-type": "gauge",
|
|
76
86
|
"x-chart-label": "Valid Rate",
|
|
77
87
|
"x-chart-unit": "%",
|
|
88
|
+
"x-anomaly-enabled": true,
|
|
89
|
+
"x-anomaly-direction": "higher-is-better",
|
|
78
90
|
}),
|
|
79
91
|
};
|
|
80
92
|
|
package/src/strategy.test.ts
CHANGED
|
@@ -15,7 +15,7 @@ describe("TlsHealthCheckStrategy", () => {
|
|
|
15
15
|
issuerOrg: string | undefined;
|
|
16
16
|
validFrom: Date;
|
|
17
17
|
validTo: Date;
|
|
18
|
-
}> = {}
|
|
18
|
+
}> = {},
|
|
19
19
|
): CertificateInfo => {
|
|
20
20
|
const validFrom =
|
|
21
21
|
overrides.validFrom ?? new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);
|
|
@@ -45,7 +45,7 @@ describe("TlsHealthCheckStrategy", () => {
|
|
|
45
45
|
protocol?: string;
|
|
46
46
|
cipher?: string;
|
|
47
47
|
error?: Error;
|
|
48
|
-
} = {}
|
|
48
|
+
} = {},
|
|
49
49
|
): TlsClient => ({
|
|
50
50
|
connect: mock(() =>
|
|
51
51
|
config.error
|
|
@@ -56,7 +56,7 @@ describe("TlsHealthCheckStrategy", () => {
|
|
|
56
56
|
getProtocol: () => config.protocol ?? "TLSv1.3",
|
|
57
57
|
getCipher: () => (config.cipher ? { name: config.cipher } : null),
|
|
58
58
|
end: mock(() => {}),
|
|
59
|
-
} as TlsConnection)
|
|
59
|
+
} as TlsConnection),
|
|
60
60
|
),
|
|
61
61
|
});
|
|
62
62
|
|
|
@@ -81,7 +81,7 @@ describe("TlsHealthCheckStrategy", () => {
|
|
|
81
81
|
|
|
82
82
|
it("should throw for connection error during client creation", async () => {
|
|
83
83
|
const strategy = new TlsHealthCheckStrategy(
|
|
84
|
-
createMockClient({ error: new Error("Connection refused") })
|
|
84
|
+
createMockClient({ error: new Error("Connection refused") }),
|
|
85
85
|
);
|
|
86
86
|
|
|
87
87
|
await expect(
|
|
@@ -91,7 +91,7 @@ describe("TlsHealthCheckStrategy", () => {
|
|
|
91
91
|
timeout: 5000,
|
|
92
92
|
minDaysUntilExpiry: 7,
|
|
93
93
|
rejectUnauthorized: true,
|
|
94
|
-
})
|
|
94
|
+
}),
|
|
95
95
|
).rejects.toThrow("Connection refused");
|
|
96
96
|
});
|
|
97
97
|
});
|
|
@@ -119,7 +119,7 @@ describe("TlsHealthCheckStrategy", () => {
|
|
|
119
119
|
|
|
120
120
|
it("should return invalid for unauthorized certificate", async () => {
|
|
121
121
|
const strategy = new TlsHealthCheckStrategy(
|
|
122
|
-
createMockClient({ authorized: false })
|
|
122
|
+
createMockClient({ authorized: false }),
|
|
123
123
|
);
|
|
124
124
|
|
|
125
125
|
const connectedClient = await strategy.createClient({
|
|
@@ -145,7 +145,7 @@ describe("TlsHealthCheckStrategy", () => {
|
|
|
145
145
|
});
|
|
146
146
|
|
|
147
147
|
const strategy = new TlsHealthCheckStrategy(
|
|
148
|
-
createMockClient({ cert: selfSignedCert, authorized: false })
|
|
148
|
+
createMockClient({ cert: selfSignedCert, authorized: false }),
|
|
149
149
|
);
|
|
150
150
|
|
|
151
151
|
const connectedClient = await strategy.createClient({
|
package/src/strategy.ts
CHANGED
|
@@ -63,23 +63,32 @@ const tlsResultSchema = healthResultSchema({
|
|
|
63
63
|
connected: healthResultBoolean({
|
|
64
64
|
"x-chart-type": "boolean",
|
|
65
65
|
"x-chart-label": "Connected",
|
|
66
|
+
"x-anomaly-enabled": true,
|
|
67
|
+
"x-anomaly-direction": "dominance",
|
|
66
68
|
}),
|
|
67
69
|
isValid: healthResultBoolean({
|
|
68
70
|
"x-chart-type": "boolean",
|
|
69
71
|
"x-chart-label": "Valid",
|
|
72
|
+
"x-anomaly-enabled": true,
|
|
73
|
+
"x-anomaly-direction": "dominance",
|
|
70
74
|
}),
|
|
71
75
|
isSelfSigned: healthResultBoolean({
|
|
72
76
|
"x-chart-type": "boolean",
|
|
73
77
|
"x-chart-label": "Self-Signed",
|
|
78
|
+
"x-anomaly-enabled": true,
|
|
79
|
+
"x-anomaly-direction": "dominance",
|
|
74
80
|
}),
|
|
75
81
|
daysUntilExpiry: healthResultNumber({
|
|
76
82
|
"x-chart-type": "line",
|
|
77
83
|
"x-chart-label": "Days Until Expiry",
|
|
78
84
|
"x-chart-unit": "days",
|
|
85
|
+
"x-anomaly-enabled": true,
|
|
86
|
+
"x-anomaly-direction": "higher-is-better",
|
|
79
87
|
}),
|
|
80
88
|
error: healthResultString({
|
|
81
89
|
"x-chart-type": "status",
|
|
82
90
|
"x-chart-label": "Error",
|
|
91
|
+
"x-anomaly-enabled": false,
|
|
83
92
|
}).optional(),
|
|
84
93
|
});
|
|
85
94
|
|
|
@@ -91,19 +100,27 @@ const tlsAggregatedFields = {
|
|
|
91
100
|
"x-chart-type": "line",
|
|
92
101
|
"x-chart-label": "Avg Days Until Expiry",
|
|
93
102
|
"x-chart-unit": "days",
|
|
103
|
+
"x-anomaly-enabled": true,
|
|
104
|
+
"x-anomaly-direction": "higher-is-better",
|
|
94
105
|
}),
|
|
95
106
|
minDaysUntilExpiry: aggregatedMinMax({
|
|
96
107
|
"x-chart-type": "line",
|
|
97
108
|
"x-chart-label": "Min Days Until Expiry",
|
|
98
109
|
"x-chart-unit": "days",
|
|
110
|
+
"x-anomaly-enabled": true,
|
|
111
|
+
"x-anomaly-direction": "higher-is-better",
|
|
99
112
|
}),
|
|
100
113
|
invalidCount: aggregatedCounter({
|
|
101
114
|
"x-chart-type": "counter",
|
|
102
115
|
"x-chart-label": "Invalid Certificates",
|
|
116
|
+
"x-anomaly-enabled": true,
|
|
117
|
+
"x-anomaly-direction": "lower-is-better",
|
|
103
118
|
}),
|
|
104
119
|
errorCount: aggregatedCounter({
|
|
105
120
|
"x-chart-type": "counter",
|
|
106
121
|
"x-chart-label": "Errors",
|
|
122
|
+
"x-anomaly-enabled": true,
|
|
123
|
+
"x-anomaly-direction": "lower-is-better",
|
|
107
124
|
}),
|
|
108
125
|
};
|
|
109
126
|
|