openvibers/openvibe.network Commits

Signed out, openvibe.my says what it is and what is inside (#745)

OP OpenVibers committed 3 days ago · 67ef3b99c5 · 3 files, +54 −16

It was a small card on an empty screen with two buttons, one of them Sign out everywhere. Now: what the page is, one
Sign in button, the five things that are here once signed in, and Sign out everywhere as a quiet line.

Changes

ddiff --git a/public/css/my.css b/public/css/my.css
iindex 6e4bd35b..f9998132 100644
---- a/public/css/my.css
++++ b/public/css/my.css
@@@ -674,3 +674,19 @@ button.td-stat:hover span { color: var(--accent-light); }
.pp-places-row .data-check{align-items:center}
.pp-places-row .data-check input{margin-top:0}
#public-page-card > p.muted{margin-bottom:16px}
++
++/* Signed out on openvibe.my (public/js/my/profile.js showSignedOutHub): what the page is, one way in, what is inside. */
++.my-out{max-width:560px;margin:clamp(12px,4vw,40px) auto 0;padding:0 4px}
++.my-out-h{margin:0 0 8px;font-size:clamp(1.6rem,5.4vw,2.3rem);line-height:1.12;letter-spacing:-.02em}
++.my-out-lede{margin:0 0 18px;color:var(--text-secondary,#96a7c2);font-size:1.02rem;line-height:1.5}
++.my-out-go{display:inline-flex;align-items:center;justify-content:center;min-height:48px;padding:0 28px;font-size:1rem;font-weight:700}
++.my-out-list{list-style:none;margin:22px 0 0;padding:0;display:grid;gap:8px}
++.my-out-list li{display:grid;grid-template-columns:40px minmax(0,1fr);align-items:center;gap:12px;padding:12px 14px;border:1px solid var(--border,#1f2d47);border-radius:14px;background:var(--bg-card,#131c2e)}
++.my-out-ic{display:grid;place-items:center;width:40px;height:40px;border-radius:12px;color:var(--accent-light,#60a5fa);background:color-mix(in srgb,var(--accent,#3b82f6) 14%,transparent)}
++.my-out-ic i{display:block;width:20px;height:20px;font-size:20px;line-height:1}
++.my-out-t{display:grid;gap:1px;min-width:0}
++.my-out-list b{font-weight:650}
++.my-out-list small{color:var(--text-muted,#7386a3);font-size:.86rem;line-height:1.4}
++.my-out-still{margin:18px 0 0;color:var(--text-muted,#7386a3);font-size:.88rem}
++.my-out-all{color:var(--text-secondary,#96a7c2)}
++@media (max-width:520px){.my-out-go{display:flex;width:100%}}
ddiff --git a/public/js/my/profile.js b/public/js/my/profile.js
iindex 32546a03..b1fea5d2 100644
---- a/public/js/my/profile.js
++++ b/public/js/my/profile.js
@@@ -47,26 +47,42 @@ function showSignedOutHub() {
here.searchParams.delete('sso');
here.searchParams.delete('signed_out');
const next = `${here.pathname}${here.search}${here.hash}`;
-- const card = document.createElement('section');
-- card.className = 'card';
-- const heading = document.createElement('h2');
-- heading.textContent = 'Sign in to OpenVibe.My';
-- const text = document.createElement('p');
-- text.textContent = 'Your account hub lives on its own address. Sign in with OpenVibe; your account and its API stay on openvibe.network.';
-- const row = document.createElement('div');
-- row.className = 'btn-row';
-- const signIn = document.createElement('a');
-- signIn.className = 'btn btn-primary';
++ // What the page is and what is inside it, then one way in. It was a small card on an empty screen that named an
++ // "account hub" and offered "Sign out everywhere" to someone who is signed out; that link is still here for the
++ // browser that kept a Network session, as a quiet line under the list.
++ const el = (tag, cls, text) => { const n = document.createElement(tag); if (cls) n.className = cls; if (text) n.textContent = text; return n; };
++ const card = el('section', 'my-out');
++ const heading = el('h1', 'my-out-h', 'Everything that is yours on OpenVibe');
++ const text = el('p', 'my-out-lede', 'Your profile, your look, your sites and your numbers, in one place. Sign in to see yours.');
++ const signIn = el('a', 'btn btn-primary my-out-go', 'Sign in');
signIn.href = `/auth/login?next=${encodeURIComponent(next)}`;
signIn.setAttribute('href', signIn.href);
-- signIn.textContent = 'Sign in with OpenVibe';
-- const everywhere = document.createElement('a');
-- everywhere.className = 'btn btn-outline'; // the second way, drawn as one (it read as a stray underlined link)
++ const list = el('ul', 'my-out-list');
++ list.setAttribute('aria-label', 'What is here when you sign in');
++ [
++ ['fa-clock-rotate-left', 'Pick up where you left off', 'The pages and sites you used last.'],
++ ['fa-table-cells', 'Your sites', 'Every OpenVibe site you use, and what is new on each.'],
++ ['fa-chart-simple', 'Your numbers', 'What you made, watched and earned, counted.'],
++ ['fa-gear', 'Settings', 'Your profile, your look, your sign-ins, your privacy and your data.'],
++ ['fa-mobile-screen', 'Sign in on another device', 'A code to scan: no password to type on a phone or a TV.'],
++ ].forEach(([icon, title, says]) => {
++ const li = el('li');
++ // The tile is a wrapper: the glyph kit draws an svg as big as its <i>, so the <i> stays icon-sized.
++ const tile = el('span', 'my-out-ic');
++ const i = el('i', `fa-solid ${icon}`);
++ i.setAttribute('aria-hidden', 'true');
++ tile.append(i);
++ const words = el('span', 'my-out-t');
++ words.append(el('b', '', title), el('small', '', says));
++ li.append(tile, words);
++ list.append(li);
++ });
++ const everywhere = el('a', 'my-out-all', 'Sign out everywhere');
everywhere.href = 'https://openvibe.network/sso/fanout?action=logout&next=' + encodeURIComponent('https://openvibe.my/?sso=none');
everywhere.setAttribute('href', everywhere.href);
-- everywhere.textContent = 'Sign out everywhere';
-- row.append(signIn, everywhere);
-- card.append(heading, text, row);
++ const still = el('p', 'my-out-still', 'Still signed in on another OpenVibe site? ');
++ still.append(everywhere);
++ card.append(heading, text, signIn, list, still);
page.replaceChildren(card);
try {
if (window.OpenVibeNavbar) OpenVibeNavbar.init({ service: 'network', token: null, user: null, menu: OV_WALLET_MENU, ...OV_NAV_AUTH });
ddiff --git a/test/my-home.test.js b/test/my-home.test.js
iindex 41ca97d6..45692811 100644
---- a/test/my-home.test.js
++++ b/test/my-home.test.js
@@@ -237,6 +237,12 @@ const MY = 'openvibe.my';
const profile = fs.readFileSync(path.join(ROOT, 'public', 'js', 'my', 'profile.js'), 'utf8');
assert.ok(profile.includes("sessionUrl: '/auth/me'") && profile.includes("logoutUrl: '/auth/logout?next={path}'"), 'the shared navbar uses the hub\'s session');
assert.ok(profile.includes('function showSignedOutHub') && profile.includes("'Sign out everywhere'"), 'a signed-out hub stays put and offers everywhere');
++ // Signed out, the page says what it is and what is inside, with one way in (it was a small card on an empty
++ // screen that offered "Sign out everywhere" as a second button to someone who is signed out).
++ assert.ok(profile.includes("'Everything that is yours on OpenVibe'") && profile.includes("el('a', 'btn btn-primary my-out-go', 'Sign in')"), 'what it is, and one button');
++ ['Pick up where you left off', 'Your sites', 'Your numbers', 'Settings', 'Sign in on another device'].forEach((name) => assert.ok(profile.includes(`'${name}'`), `the signed-out page lists ${name}`));
++ assert.ok(profile.includes("el('a', 'my-out-all', 'Sign out everywhere')"), 'signing out everywhere is a quiet line, not a second button');
++ assert.ok(fs.readFileSync(path.join(ROOT, 'public', 'css', 'my.css'), 'utf8').includes('.my-out-list li{'), 'and it is styled');
const security = fs.readFileSync(path.join(ROOT, 'public', 'js', 'my', 'security.js'), 'utf8');
assert.ok(security.includes("'https://openvibe.network/sso/fanout?action=logout&next='"), 'signing out everywhere still offers Network\'s fanout');
} finally {