108 lines
4.6 KiB
HTML
108 lines
4.6 KiB
HTML
<!doctype html>
|
|
<html lang="ru">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>CRM embed test</title>
|
|
<style>
|
|
body { font: 15px/1.5 system-ui, sans-serif; margin: 16px; color: #222; }
|
|
h1 { font-size: 18px; margin: 0 0 12px; }
|
|
#status { padding: 8px 12px; border-radius: 6px; background: #fff4d6; }
|
|
#status.ok { background: #e3f6e3; } #status.err { background: #fde2e2; }
|
|
dl { display: grid; grid-template-columns: max-content 1fr; gap: 4px 12px; }
|
|
dt { color: #666; } dd { margin: 0; word-break: break-all; }
|
|
button { margin-top: 12px; padding: 6px 14px; }
|
|
#log { margin-top: 16px; font-size: 13px; color: #555; padding-left: 18px; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>Тест встраивания в CRM Tvorymo</h1>
|
|
<div id="status">жду авторизацию от CRM</div>
|
|
<dl id="info" hidden>
|
|
<dt>Имя</dt><dd id="name"></dd>
|
|
<dt>Email</dt><dd id="email"></dd>
|
|
<dt>ID</dt><dd id="uid"></dd>
|
|
<dt>Origin отправителя</dt><dd id="origin"></dd>
|
|
<dt>expires_at</dt><dd id="expires"></dd>
|
|
<dt>Получено токенов</dt><dd id="count">0</dd>
|
|
</dl>
|
|
<button id="refresh" hidden>Обновить токен</button>
|
|
<ol id="log"></ol>
|
|
<script>
|
|
(() => {
|
|
// Сессия только в памяти, токен не выводится и не логируется.
|
|
let session = null; // { token, expiresAt }
|
|
let crmSource = null, crmOrigin = null, count = 0;
|
|
const $ = (id) => document.getElementById(id);
|
|
const inIframe = window.parent !== window;
|
|
|
|
function setStatus(text, cls) { const s = $("status"); s.textContent = text; s.className = cls || ""; }
|
|
function log(text) {
|
|
const li = document.createElement("li");
|
|
li.textContent = new Date().toLocaleTimeString() + " — " + text;
|
|
$("log").prepend(li);
|
|
}
|
|
function fmtTime(v) {
|
|
if (v == null) return "—";
|
|
const n = Number(v);
|
|
const d = new Date(Number.isFinite(n) ? (n < 1e12 ? n * 1000 : n) : v);
|
|
return isNaN(d) ? String(v) : d.toLocaleString() + " (" + d.toISOString() + ")";
|
|
}
|
|
|
|
async function onAuth(data, ev) {
|
|
crmSource = ev.source; crmOrigin = ev.origin;
|
|
$("origin").textContent = ev.origin;
|
|
const token = data.access_token;
|
|
if (typeof token !== "string" || !token) { setStatus("crm:auth без access_token", "err"); return; }
|
|
const changed = session && session.token !== token;
|
|
const prevExp = session && session.expiresAt;
|
|
session = { token, expiresAt: data.expires_at };
|
|
count++;
|
|
setStatus("проверяю токен в Supabase…");
|
|
try {
|
|
const r = await fetch("/api/verify", {
|
|
method: "POST", headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ access_token: token }),
|
|
});
|
|
const res = await r.json();
|
|
if (!res.ok) { setStatus("Токен не принят: " + res.error, "err"); log("crm:auth от " + ev.origin + " — отклонён"); return; }
|
|
$("name").textContent = res.name || "имя не задано в Supabase";
|
|
$("email").textContent = res.email || "—";
|
|
$("uid").textContent = res.id;
|
|
$("expires").textContent = fmtTime(data.expires_at != null ? data.expires_at : res.exp);
|
|
$("count").textContent = String(count);
|
|
$("info").hidden = false; $("refresh").hidden = false;
|
|
setStatus(changed ? "Токен сменился, пользователь подтверждён Supabase" : "Пользователь подтверждён Supabase", "ok");
|
|
log("crm:auth от " + ev.origin + (changed
|
|
? " — новый токен, expires_at: " + fmtTime(prevExp) + " → " + fmtTime(data.expires_at)
|
|
: session && count > 1 ? " — тот же токен" : " — принят"));
|
|
} catch (e) {
|
|
setStatus("Ошибка проверки токена", "err");
|
|
}
|
|
}
|
|
|
|
window.addEventListener("message", (ev) => {
|
|
const data = ev.data;
|
|
if (!data || typeof data !== "object") return;
|
|
// Для теста принимаем от любого origin (решение владельца).
|
|
if (data.type === "crm:auth") onAuth(data, ev);
|
|
});
|
|
|
|
$("refresh").addEventListener("click", () => {
|
|
const target = crmSource || window.parent;
|
|
target.postMessage({ type: "crm:refresh" }, crmOrigin || "*");
|
|
setStatus("запросил новый токен (crm:refresh)…");
|
|
log("отправлен crm:refresh → " + (crmOrigin || "*"));
|
|
});
|
|
|
|
if (inIframe) {
|
|
window.parent.postMessage({ type: "crm:ready", version: 1 }, "*");
|
|
log("отправлен crm:ready");
|
|
} else {
|
|
log("страница открыта не в iframe");
|
|
}
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>
|