Files
SRCmail/lib/protocol-handlers/webcal.ts
T

50 lines
1.2 KiB
TypeScript

export interface ParsedWebcal {
originalUrl: string;
subscriptionUrl: string;
suggestedName: string;
}
function stripControlChars(value: string): string {
// eslint-disable-next-line no-control-regex
return value.replace(/[\u0000-\u001F\u007F]/g, "").trim();
}
function extensionlessName(value: string): string {
return value.replace(/\.(ics|ical)$/i, "");
}
function decodePathSegment(value: string): string {
try {
return decodeURIComponent(value);
} catch {
return value;
}
}
export function parseWebcal(raw: string): ParsedWebcal | null {
let url: URL;
try {
url = new URL(raw);
} catch {
return null;
}
if (url.protocol === "webcal:" || url.protocol === "webcals:") {
url = new URL(raw.replace(/^webcals?:/i, "https:"));
} else if (url.protocol !== "http:" && url.protocol !== "https:") {
return null;
}
const subscriptionUrl = url.toString();
const queryName = stripControlChars(url.searchParams.get("name") || "");
const pathSegment = stripControlChars(decodePathSegment(url.pathname.split("/").filter(Boolean).pop() || ""));
const suggestedName = queryName || extensionlessName(pathSegment) || url.hostname;
return {
originalUrl: raw,
subscriptionUrl,
suggestedName,
};
}