Files
jobtrackingapp/job-tracker-ui/src/emailOAuth.ts
T

28 lines
1.7 KiB
TypeScript

export type EmailOAuthProvider = "gmail" | "microsoft";
export type EmailOAuthAttempt = { provider: EmailOAuthProvider; origin: string; popup: Window };
type TerminalMessage = { status: "connected" | "error"; message?: string };
export function emailOAuthCallbackOrigin(authorizationUrl: unknown, provider: EmailOAuthProvider): string | null {
if (typeof authorizationUrl !== "string") return null;
try {
const authorization = new URL(authorizationUrl);
if (!["https:", "http:"].includes(authorization.protocol) || authorization.username || authorization.password) return null;
const redirects = authorization.searchParams.getAll("redirect_uri");
if (redirects.length !== 1) return null;
const callback = new URL(redirects[0]);
const path = provider === "gmail" ? "/api/gmail/oauth/callback" : "/api/microsoft-graph/oauth/callback";
return ["https:", "http:"].includes(callback.protocol) && !callback.username && !callback.password
&& callback.pathname === path && !callback.search && !callback.hash ? callback.origin : null;
} catch { return null; }
}
export function emailOAuthMessage(event: MessageEvent, attempt: EmailOAuthAttempt): TerminalMessage | null {
if (event.origin !== attempt.origin || event.source !== attempt.popup) return null;
const data = event.data as { source?: unknown; status?: unknown; message?: unknown } | null;
if (!data || typeof data !== "object" || Array.isArray(data)
|| data.source !== (attempt.provider === "gmail" ? "jobtracker-gmail-oauth" : "jobtracker-microsoft-oauth")
|| (data.status !== "connected" && data.status !== "error")
|| (data.message !== undefined && typeof data.message !== "string")) return null;
return { status: data.status, message: data.message };
}