Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions sdk/demos/groups/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,8 @@ async function v3Post(action, params = {}) {
return res.json()
}

authButton.onclick = () => window.web10.openAuthPortal(AUTH_ORIGIN)
window.web10.authListen(() => initApp())

function initApp() {
authButton.innerHTML = "Log out"
authButton.onclick = () => { w.signOut(); window.location.reload() }
const t = w.readToken()
message.innerHTML = `Signed in as <strong>${t["provider"]}/${t["username"]}</strong>`
app.classList.remove('hidden')

// Request app contract via auth UI (not direct API)
authButton.onclick = () => {
window.web10.openAuthPortal(AUTH_ORIGIN)
w.contractRequest([{
kind: 'app',
app_origin: window.location.origin,
Expand All @@ -87,6 +78,15 @@ function initApp() {
loadManageGroups()
})
}
window.web10.authListen(() => initApp())

function initApp() {
authButton.innerHTML = "Log out"
authButton.onclick = () => { w.signOut(); window.location.reload() }
const t = w.readToken()
message.innerHTML = `Signed in as <strong>${t["provider"]}/${t["username"]}</strong>`
app.classList.remove('hidden')
}

// Self-register
fetch(`${API_ORIGIN}/v3/apps/register`, {
Expand Down
20 changes: 10 additions & 10 deletions sdk/demos/hello/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,8 @@ const isLocal = host === 'localhost' || host === '127.0.0.1' || host.endsWith('.
const AUTH_ORIGIN = isLocal ? 'http://auth.localhost' : isDev ? 'https://auth.dev.web10.app' : 'https://auth.web10.app'
const w = window.web10.createV3Client({ apiOrigin: isLocal ? 'http://api.localhost' : isDev ? 'https://api.dev.web10.app' : 'https://api.web10.app' })

authButton.onclick = () => window.web10.openAuthPortal(AUTH_ORIGIN)
window.web10.authListen(() => initApp())

function initApp() {
authButton.innerHTML = 'log out'
authButton.onclick = () => { w.signOut(); window.location.reload() }
const t = w.readToken()
message.innerHTML = `hello ${t.provider}/${t.username},<br>`

// Request app contract for basic read access
authButton.onclick = () => {
window.web10.openAuthPortal(AUTH_ORIGIN)
w.contractRequest([{
kind: 'app',
app_origin: window.location.origin,
Expand All @@ -32,5 +24,13 @@ function initApp() {
}
})
}
window.web10.authListen(() => initApp())

function initApp() {
authButton.innerHTML = 'log out'
authButton.onclick = () => { w.signOut(); window.location.reload() }
const t = w.readToken()
message.innerHTML = `hello ${t.provider}/${t.username},<br>`
}

if (w.isSignedIn()) initApp()
20 changes: 10 additions & 10 deletions sdk/demos/mailer/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,8 @@ const w = window.web10.createV3Client({ apiOrigin: isLocal ? 'http://api.localho

const COLLECTION = 'mail'

authButton.onclick = () => window.web10.openAuthPortal(AUTH_ORIGIN)
window.web10.authListen(() => initApp())

function initApp() {
authButton.innerHTML = 'log out'
authButton.onclick = () => { w.signOut(); window.location.reload() }
const t = w.readToken()
message.innerHTML = `hello ${t.provider}/${t.username},<br>`

// Request app contract for mail collection
authButton.onclick = () => {
window.web10.openAuthPortal(AUTH_ORIGIN)
w.contractRequest([{
kind: 'app',
app_origin: window.location.origin,
Expand All @@ -35,6 +27,14 @@ function initApp() {
}
})
}
window.web10.authListen(() => initApp())

function initApp() {
authButton.innerHTML = 'log out'
authButton.onclick = () => { w.signOut(); window.location.reload() }
const t = w.readToken()
message.innerHTML = `hello ${t.provider}/${t.username},<br>`
}

async function readMail() {
try {
Expand Down
20 changes: 10 additions & 10 deletions sdk/demos/notes/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,8 @@ const w = window.web10.createV3Client({ apiOrigin: isLocal ? 'http://api.localho
const COLLECTION = 'notes'
let NOTES_GROUP = null

authButton.onclick = () => window.web10.openAuthPortal(AUTH_ORIGIN)
window.web10.authListen(() => initApp())

function initApp() {
authButton.innerHTML = 'log out'
authButton.onclick = () => { w.signOut(); window.location.reload() }
const t = w.readToken()
message.innerHTML = `hello ${t.provider}/${t.username},<br>`

// Request app contract for notes collection
authButton.onclick = () => {
window.web10.openAuthPortal(AUTH_ORIGIN)
w.contractRequest([{
kind: 'app',
app_origin: window.location.origin,
Expand All @@ -36,6 +28,14 @@ function initApp() {
}
})
}
window.web10.authListen(() => initApp())

function initApp() {
authButton.innerHTML = 'log out'
authButton.onclick = () => { w.signOut(); window.location.reload() }
const t = w.readToken()
message.innerHTML = `hello ${t.provider}/${t.username},<br>`
}

function ensureNotesGroup(username, provider) {
const groupName = `notes-${username}`
Expand Down
19 changes: 9 additions & 10 deletions ui/src/interfaces/Interface.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,25 +186,25 @@ function useInterface() {
// v3 contract listening — direct postMessage, no wapiAuth wrapper
I.initAuthenticator = function () {
if (typeof window === 'undefined') return;
let contractReceived = false;
window.addEventListener('message', (e) => {
// Contract requests are inherently cross-origin (app → auth UI).
// Only reject obviously malicious sources (null origin from sandboxed iframe).
if (!e.origin) return;
if (e.data?.type === 'acr' || e.data?.type === 'contract') {
I.setPendingContracts(normalizeContracts(e.data, e.source));
contractReceived = true;
}
});
// Signal readiness to opener — broadcast periodically so the SDK can
// always sync before sending a contract, even when reusing an open popup
// that was opened seconds ago (user logged in, then clicked "Create Group").
if (window.opener) {
// Broadcast auth_ready until contract arrives — the app may call
// contractRequest after login, so we keep signaling readiness.
const broadcastReady = () => {
if (contractReceived) return;
try {
window.opener.postMessage({ type: 'auth_ready' }, '*');
} catch { /* cross-origin */ }
};
broadcastReady();
const interval = setInterval(broadcastReady, 1000);
const interval = setInterval(broadcastReady, 500);
window.addEventListener('beforeunload', () => clearInterval(interval));
}
}
Expand Down Expand Up @@ -722,9 +722,6 @@ function useInterface() {
I.denyACR = (c: any) => I.denyContract({ ...c, kind: c.kind || 'app' });
I.removePendingACR = (c: any) => I.removePendingContract({ ...c, kind: c.kind || 'app' });

// Return to the requesting app, logging it in. Send the current v3 token
// directly to the opener — no tiered token needed for v3.
// Do NOT close the popup — keep it alive so contractRequest can reuse it.
I.goToApp = function () {
const token = I.v3.state?.token;
if (token && window.opener) {
Expand All @@ -733,10 +730,12 @@ function useInterface() {
const target = referrer ? new URL(referrer).origin : '*';
I.setStatus("Connecting…");
window.opener.postMessage({ type: 'auth', token }, target);
// Don't close — SDK needs this popup for contractRequest
window.close();
} catch {
I.setStatus("Failed to connect to app.");
}
} else if (window.opener) {
window.close();
}
}

Expand Down