feat(proj): init

This commit is contained in:
vl.arkhangelskii
2026-09-21 03:53:15 +03:00
commit 3e34f391b3
258 changed files with 20968 additions and 0 deletions
+51
View File
@@ -0,0 +1,51 @@
const YANDEX_AUTHORIZE = "https://oauth.yandex.ru/authorize";
export function yandexCodeFromQuery(search: string): string | null {
const params = new URLSearchParams(search.startsWith("?") ? search : `?${search}`);
const code = params.get("code")?.trim();
if (!code) return null;
// Telegram login also lands on /login with id/hash — never treat that as Yandex.
if (params.has("hash") && params.has("id")) return null;
return code;
}
export function yandexErrorFromQuery(search: string): string | null {
const params = new URLSearchParams(search.startsWith("?") ? search : `?${search}`);
if (params.has("hash") && params.has("id")) return null;
return params.get("error_description")?.trim() || params.get("error")?.trim() || null;
}
export function yandexAuthorizeUrl(
clientId: string,
redirectUri: string,
state?: string | null,
): string {
const params = new URLSearchParams({
response_type: "code",
client_id: clientId,
redirect_uri: redirectUri,
force_confirm: "yes",
});
if (state) params.set("state", state);
return `${YANDEX_AUTHORIZE}?${params.toString()}`;
}
/** Must match the Callback URL registered in the Yandex app (trailing slash). */
export function yandexRedirectUri(
configured?: string | null,
origin = window.location.origin,
): string {
const local = `${origin.replace(/\/$/, "")}/`;
if (!configured) return local;
try {
if (new URL(configured).origin === new URL(local).origin) return configured;
} catch {
// Fall through to the current origin.
}
return local;
}
/** @deprecated use yandexRedirectUri */
export function cabinetLoginRedirectUri(origin = window.location.origin): string {
return yandexRedirectUri(null, origin);
}