Geliştirici Merkezi · Platformu genişletin
Gömülü Sayfalar - kendi araçlarınızı yönetici paneline yerleştirin.
Kendi https tarafından barındırılan sayfanızı kaydedin ve bu, SocialHub yöneticisinde izin verilen bir menü öğesine (tam sayfa, korumalı alanlı bir iframe) dönüşür. Flash sayfanıza kısa ömürlü, PII içermeyen bir kimlik belirteci verir, böylece operatöre tekrar giriş yapmasına gerek kalmadan yetki verebilirsiniz.
Erken erişim · açık genişletilebilirlik modülünün arkasında
Nasıl çalışır
URL'nizden menü öğesine dört adım.
Sayfanızı kaydedin
Bir çalışma alanı yöneticisi, https URL'nizi Flash → Yapılandır → Gömülü Sayfalar bölümüne bir menü etiketi, bir kaynak izin listesi ve hangi rollerin/katmanın açabileceğini belirterek ekler.
İmza sırrını kopyala
Flash bir kez imzalama sırrını gösterir (slotsec_…). Bunu uygulamanızda bir sunucu sırrı olarak saklayın; bununla Flash'in kimlik belirtecini doğrularsınız.
Flash sayfanızı çerçeveler
Sayfa, izin verilen operatörler için Uygulamalar altında bir kenar çubuğu menü öğesi olarak görünür; açıldığında URL'niz, sonuna ?flash_context=<token> eklenmiş bir korumalı iframe'de yüklenir.
Doğrulama + yetkilendirme
Tokeni okuyun, sunucu tarafında doğrulayın (HS256) ve kullanıcı arayüzünüzü çalışma alanı kimliği + taşıdığı operatör rolüne göre kilitleyin.
Kimlik belirteci
Kısa ömürlü, kişisel bilgiler içermez, gizli bilgilerinizle imzalanmıştır.
Her oluşturmada Flash, URL'nize ?flash_context=<JWT> öğesini ekler. Bu, sayfanızın sırrıyla imzalanmış bir HS256 JWT'dir (yani siz - platform değil - güven dayanağısınız), en fazla 120 saniye geçerlidir ve hiçbir üyenin kişisel verisini taşımaz - yalnızca çalışma alanı kimliği ve operatörün opak kimliği + kaba rolü, böylece yetkilendirebilirsiniz.
{
"iss": "flash",
"aud": "nav.page",
"slotKey": "nav.page",
"ctx": {
"teamId": "team_...", // the workspace (tenant) — the tenant already owns this
"userId": "usr_...", // opaque operator id (NOT an email/name/phone)
"role": "org_admin", // coarse role: org_owner | org_admin | marketer | store_manager
"pageType": "nav.page",
"locale": "en"
},
"jti": "…", "iat": 1730000000, "nbf": 1730000000,
"exp": 1730000110 // <= 120s after iat
}Doğrulayın
İstek değil, belirteç (token) güvenin.
Sunucunuzda imzayı, vereni (flash), hedef kitleyi (nav.page) ve son kullanma tarihini doğrulayın. Ardından, çalışma alanı kimliği + taşıdığı rol üzerinden yetkilendirin — asla çerezler üzerinden değil (iframe'in kullanılabilir bir kaynağı yok; aşağıya bakın).
// Node (jose). The secret is your page's signing secret, shown ONCE at registration.
import { jwtVerify } from "jose";
const SECRET = new TextEncoder().encode(process.env.FLASH_EMBED_SECRET); // slotsec_…
export async function verifyFlashContext(token) {
const { payload } = await jwtVerify(token, SECRET, {
algorithms: ["HS256"],
issuer: "flash",
audience: "nav.page",
requiredClaims: ["exp", "jti"],
maxTokenAge: "120s",
});
// payload.ctx = { teamId, userId, role, pageType, locale }
return payload.ctx; // → authorize the operator with this
}// In your page: read ?flash_context=… , verify it server-side, then authorize.
const token = new URLSearchParams(location.search).get("flash_context");
// POST it to YOUR backend, verify with the snippet above, and gate the UI on
// ctx.teamId + ctx.role. Never trust it unverified, and never rely on cookies —
// the iframe is a null origin (see "Framing" below).Çerçeveleme ve güvenlik
Sayfanızın yapması gerekenler.
Çerçeveye izin verin
Sayfanızın Flash ile çerçevelenmesine izin vermesi gerekir.socialhub.ai — X-Frame-Options: DENY göndermeyin; Content-Security-Policy: frame-ancestors olarak ayarlayın https://flash.socialhub.ai.
Boş bir köken varsayalım
Flash, iframe'i allow-scripts ve no allow-same-origin ile sanal bir alana alır, böylece sayfanız null bir kaynaktan çalışır: Flash çerez, depolama veya üst DOM yok. Çerezlerle değil, belirteçle kimlik doğrulaması yapın.
postMessage izin verilenler listesine eklendi
Ana makine yalnızca kaydettiğiniz kaynaklardan ve yalnızca iframe pencerenizden gelen postMessage'ı kabul eder. İzin verilen kaynaklar listenizi sıkı ve yalnızca https'den oluşan bir liste tutun.
İmzalama gizli anahtarı ifşa edilirse yöneticiden alın (eski token'lar hemen doğrulamayı durdurur). Gömülü Sayfalar erken erişim özelliğine sahiptir, çalışma alanı başına varsayılan olarak kapalıdır ve üretim için etkinleştirilmesi SocialHub'ın üçüncü taraf gömme güvenlik incelemesine tabidir.
Yönetici görünümüyle eşleştirme
Yerleşikmiş gibi değil, yerelmiş gibi hissettirin.
Sayfanız SocialHub yöneticisinin içinde oluşturuluyor, dolayısıyla ona aitmiş gibi görünmesi gerekiyor. Yönetici, birkaç jeton üzerine inşa edilmiş tek bir düz, hafif temadır; bunları yansıtın. Flash zaten sayfanızı "Üçüncü taraf" rozetiyle başlıklı bir pencerede sarıyor; bu nedenle kendi üst çubuğunuzu, kenar çubuğunuzu veya tam sayfa kromunuzu eklemeyin; yalnızca içeriği işleyin.
/* Starter tokens that match the SocialHub admin (flat, light, single-accent).
Drop into your embedded page so it feels native, not bolted on. */
:root {
/* type — the admin's three families */
--font-sans: "Inter", -apple-system, "Segoe UI", Roboto, sans-serif;
--font-display: "Plus Jakarta Sans", "Inter", system-ui, sans-serif;
--font-mono: "JetBrains Mono", ui-monospace, monospace;
/* surfaces — light theme only (the admin has no dark mode) */
--bg: #fafbfc; /* page background */
--surface: #ffffff; /* cards / panels */
--subtle: #f7fafc; /* muted fills */
--border: #e2e8f0; /* hairlines */
/* text */
--text: #121c3d; /* primary (brand navy) */
--text-2: #4a5568; /* secondary */
--muted: #64748b; /* muted */
/* accent — the admin's primary action colour */
--accent: #2ecc87;
--accent-dark: #25b678;
/* radius + 4px spacing scale + elevation */
--radius: 8px; --radius-lg: 12px;
--space-2: 8px; --space-3: 12px; --space-4: 16px; --space-6: 24px;
--shadow-sm: 0 1px 3px rgba(0,0,0,.06), 0 1px 2px rgba(0,0,0,.04);
}
body { margin: 0; background: var(--bg); color: var(--text);
font: 14px/1.5 var(--font-sans); }
h1, h2, h3 { font-family: var(--font-display); color: var(--text); }
.card { background: var(--surface); border: 1px solid var(--border);
border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
padding: var(--space-4); }
.btn { background: var(--accent); color: #fff; border: 0; font-weight: 600;
border-radius: var(--radius); padding: 8px 14px; cursor: pointer; }
.btn:hover { background: var(--accent-dark); }
code { font-family: var(--font-mono); color: var(--text-2); }Kendi Chrome'unuz yok
Flash pencere çerçevesini ve rozeti sağlar. Uygulamanızın genel navigasyonunu/kenar çubuğunu/başlığını atlayın — yalnızca aracı oluşturun.
Hafif, düz, tek vurgulu
Sadece açık tema (yönetici panelinde karanlık mod yok): #fafbfc sayfasında beyaz kartlar, ince #e2e8f0 kenarlıklar, bir yeşil vurgu (#2ecc87).
Genişliği doldurun, yüksekliği akıtın
Tam genişliği kullanın ve içeriğin akmasına izin verin; sunucu çerçeveyi boyutlandırır (kabaca tam görüntü alanı yüksekliği) ve kaydırır — kendi 100vh'nizi veya sabit altbilgilerinizi zorlamayın.
Zarif bir şekilde gerileme
Yazı tipleri (Inter / Plus Jakarta Sans / JetBrains Mono), bunları kendiniz barındırmıyorsanız sistem arayüzüne geri döner; honor, azaltılmış hareket ve açık renk şemasını tercih eder.
Bu değerler mevcut yönetici temasını izler; bunları bir başlangıç noktası olarak değerlendirin ve kendi markanızı önemli olduğu yerde tutun. Amaç, farklı bir ürüne açılan bir pencere değil, SocialHub ile tek bir yüzey olarak okunan bir sayfadır.
Tam bir örnek
~30 satırlık, çalışan bir gömülü sayfa.
Olduğu gibi çalıştırabileceğiniz ve kaydedebileceğiniz minimal bir Express sunucusu: Flash'ın onu çerçevelemesine, kimlik belirtecini doğrulamasına, operatörün rolünde yetkilendirmesine ve çalışma alanına özgü bir araç oluşturmasına olanak tanır. İmzalama gizli anahtarını yöneticiden FLASH_EMBED_SECRET'a kopyalayın ve çalıştırın.
// server.js — a complete, minimal SocialHub Embedded Page (Express + jose).
// Register https://<host>/embed in Flash → Settings → Embedded Pages, allow the
// origin https://<host>, pick roles/tier, then copy the signing secret into env.
import express from "express";
import { jwtVerify } from "jose";
const app = express();
const SECRET = new TextEncoder().encode(process.env.FLASH_EMBED_SECRET); // slotsec_…
const FLASH = "https://flash.socialhub.ai";
app.get("/embed", async (req, res) => {
// 1. Let ONLY Flash frame this page.
res.setHeader("Content-Security-Policy", "frame-ancestors " + FLASH);
// 2. Read + verify the identity token Flash appended (?flash_context=…).
let ctx;
try {
const { payload } = await jwtVerify(String(req.query.flash_context || ""), SECRET, {
algorithms: ["HS256"], issuer: "flash", audience: "nav.page",
requiredClaims: ["exp", "jti"], maxTokenAge: "120s",
});
ctx = payload.ctx; // { teamId, userId, role, pageType, locale }
} catch {
return res.status(401).send("<p>Unauthorized — open this from inside SocialHub.</p>");
}
// 3. Authorize on the VERIFIED role (never on the raw request).
const canEdit = ctx.role === "org_owner" || ctx.role === "org_admin";
// 4. Render your tool, scoped to ctx.teamId. (Values are verified + opaque;
// still escape anything user-supplied you add.)
res.send(
'<!doctype html><meta charset="utf-8"><body style="font:14px system-ui;padding:24px">' +
'<h1>Returns portal</h1>' +
'<p>Workspace <code>' + ctx.teamId + '</code> · operator <code>' + ctx.userId +
'</code> · role <b>' + ctx.role + '</b></p>' +
(canEdit ? '<button>Process a return</button>' : '<p>Read-only for your role.</p>') +
'</body>'
);
});
app.listen(3000, () => console.log("Embedded page on :3000/embed"));1 · Çerçeveye izin ver
çerçeve-ataları https://flash.socialhub.ai — böylece yalnızca SocialHub yöneticisi onu iframe edebilir.
2 · Tokeni doğrulayın
?flash_context'i okuyun, HS256 + yayıncı flash + hedef kitle nav.page + ≤120 saniye süre sonunu doğrulayın; aksi takdirde reddedin.
3 · Yetkilendir
Kapı özellikleri DOĞRULANMIŞ rolde (org_owner / org_admin / …) bulunur, asla ham istekte bulunmaz.
4 · Oluşturma, kapsamlı
Aracınızı ctx.teamId için oluşturun — açıldığı çalışma alanı.
Daha sonra Flash → Ayarlar → Gömülü Sayfalar'da: URL'yi ekleyin (ör. https://tools.yourapp.com/embed), aynı kaynağı listeleyin, onu açabilecek rolleri + katmanı seçin ve tek seferlik imzalama sırrını sunucunuzun ortamına yapıştırın. Artık izin verdiğiniz operatörler için Uygulamalar altında görünür.