Persist configurable connectivity diagnostics
This commit is contained in:
@@ -25,6 +25,73 @@ export const CONNECTIVITY_SITES = Object.freeze([
|
||||
|
||||
export const MAX_CUSTOM_DIAGNOSTIC_SERVICES = 5;
|
||||
|
||||
export interface DiagnosticService {
|
||||
id: string;
|
||||
label: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface DiagnosticSettings {
|
||||
configured: boolean;
|
||||
customServices: DiagnosticService[];
|
||||
hiddenServiceIds: string[];
|
||||
}
|
||||
|
||||
function record(value: unknown): Record<string, unknown> {
|
||||
return value && typeof value === 'object' && !Array.isArray(value)
|
||||
? value as Record<string, unknown>
|
||||
: {};
|
||||
}
|
||||
|
||||
function diagnosticService(value: unknown): DiagnosticService | null {
|
||||
const candidate = record(value);
|
||||
const id = typeof candidate.id === 'string' ? candidate.id.trim() : '';
|
||||
const label = typeof candidate.label === 'string' ? candidate.label.trim() : '';
|
||||
if (!/^custom-[a-z0-9-]{1,80}$/i.test(id) || !label || label.length > 40) return null;
|
||||
try {
|
||||
const url = new URL(typeof candidate.url === 'string' ? candidate.url.trim() : '');
|
||||
if (
|
||||
url.protocol !== 'https:'
|
||||
|| url.username
|
||||
|| url.password
|
||||
|| (url.port && url.port !== '443')
|
||||
) return null;
|
||||
return { id, label, url: url.href };
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function normalizeDiagnosticSettings(
|
||||
value: unknown,
|
||||
{ strict = false }: { strict?: boolean } = {},
|
||||
): DiagnosticSettings {
|
||||
const candidate = record(value);
|
||||
const requestedServices = Array.isArray(candidate.customServices) ? candidate.customServices : [];
|
||||
const customServices = requestedServices
|
||||
.map(diagnosticService)
|
||||
.filter((service): service is DiagnosticService => Boolean(service))
|
||||
.filter((service, index, services) => services.findIndex(({ id }) => id === service.id) === index)
|
||||
.slice(0, MAX_CUSTOM_DIAGNOSTIC_SERVICES);
|
||||
const builtInIds = new Set(CONNECTIVITY_SITES.map(({ id }) => id));
|
||||
const requestedHiddenIds = Array.isArray(candidate.hiddenServiceIds) ? candidate.hiddenServiceIds : [];
|
||||
const hiddenServiceIds = requestedHiddenIds
|
||||
.filter((id): id is string => typeof id === 'string' && builtInIds.has(id))
|
||||
.filter((id, index, ids) => ids.indexOf(id) === index);
|
||||
if (strict && (
|
||||
typeof candidate.configured !== 'boolean'
|
||||
|| !Array.isArray(candidate.customServices)
|
||||
|| !Array.isArray(candidate.hiddenServiceIds)
|
||||
|| customServices.length !== requestedServices.length
|
||||
|| hiddenServiceIds.length !== requestedHiddenIds.length
|
||||
)) throw new TypeError('Invalid diagnostic settings');
|
||||
return {
|
||||
configured: candidate.configured === true,
|
||||
customServices,
|
||||
hiddenServiceIds,
|
||||
};
|
||||
}
|
||||
|
||||
export interface ConnectivitySiteResult {
|
||||
id: string;
|
||||
label: string;
|
||||
|
||||
Reference in New Issue
Block a user