feat(device-plane): harden edge channel rotation
This commit is contained in:
@@ -216,6 +216,45 @@ export function normalizeCertificateFingerprint(value) {
|
||||
return compact.match(/.{2}/g).join(":");
|
||||
}
|
||||
|
||||
export function normalizeCertificateIdentities(value) {
|
||||
if (!Array.isArray(value) || value.length < 1 || value.length > 2) {
|
||||
throw new TypeError("device_edge_channel_certificate_identities_invalid");
|
||||
}
|
||||
const generations = new Set();
|
||||
const fingerprints = new Set();
|
||||
let activeCount = 0;
|
||||
const identities = value.map((identity) => {
|
||||
assertPlainObject(identity, "device_edge_channel_certificate_identity");
|
||||
rejectUnexpectedKeys(
|
||||
identity,
|
||||
new Set(["generationRef", "fingerprint", "status"]),
|
||||
);
|
||||
if (!["active", "staged"].includes(identity.status)) {
|
||||
throw new TypeError("device_edge_channel_certificate_identity_status_invalid");
|
||||
}
|
||||
if (identity.status === "active") activeCount += 1;
|
||||
const generationRef = normalizeRef(
|
||||
identity.generationRef,
|
||||
"certificate_generation_ref",
|
||||
);
|
||||
const fingerprint = normalizeCertificateFingerprint(identity.fingerprint);
|
||||
if (generations.has(generationRef) || fingerprints.has(fingerprint)) {
|
||||
throw new TypeError("device_edge_channel_certificate_identity_duplicate");
|
||||
}
|
||||
generations.add(generationRef);
|
||||
fingerprints.add(fingerprint);
|
||||
return Object.freeze({
|
||||
generationRef,
|
||||
fingerprint,
|
||||
status: identity.status,
|
||||
});
|
||||
});
|
||||
if (activeCount !== 1) {
|
||||
throw new TypeError("device_edge_channel_active_certificate_identity_invalid");
|
||||
}
|
||||
return Object.freeze(identities);
|
||||
}
|
||||
|
||||
export function nextReconnectDelay(attempt, options = {}) {
|
||||
const normalizedAttempt = Number(attempt);
|
||||
if (!Number.isSafeInteger(normalizedAttempt) || normalizedAttempt < 0) {
|
||||
|
||||
Reference in New Issue
Block a user