openvibers/openvibe.rent Commits

Enable silent first-visit sign-in on OpenVibe.Rent (#243)

OP OpenVibers committed 5 days ago · 3af73c4ccf · 3 files, +23 −12

Changes

ddiff --git a/server/app.js b/server/app.js
iindex c81e6c5..354f223 100644
---- a/server/app.js
++++ b/server/app.js
@@@ -58,6 +58,10 @@ async function createApp(opts = {}) {
const keys = createKeyStore({ config, fetchImpl, log });
const sso = createSso({ config, keys, fetchImpl, now: s.now, log });
++ const homesSso = createSso({ config: { ...config, baseUrl: config.homes.url,
++ oauth: { ...config.oauth, redirectUri: `${config.homes.url}/auth/callback` } }, keys, fetchImpl, now: s.now, log });
++ const homesAuthHost = new URL(config.homes.url).hostname;
++
const principal = createPrincipal({ config, keys });
const ctx = { config, s, keys, sso, principal, log };
// Listing pages in OpenVibe.Search (./search-index.js): every store write names the listing it touched (s.search),
@@@ -168,7 +172,8 @@ async function createApp(opts = {}) {
// ── Sign-in (OAuth2 + PKCE client of OpenVibe.Network) ──
// /auth/me is the navbar's who-is-signed-in read on every page, so it is not counted with sign-ins: 60 page views in 15 minutes made a signed-in visitor look signed out.
app.use('/auth/', rateLimit({ windowMs: 15 * 60_000, limit: 60, skip: (req) => req.path === '/me', standardHeaders: true, legacyHeaders: false }));
-- app.use('/auth', sso.routes());
++ const rentAuth = sso.routes(), homesAuth = homesSso.routes();
++ app.use('/auth', (req, res, next) => (req.hostname === homesAuthHost ? homesAuth : rentAuth)(req, res, next));
{ const legal = require('openvibe-shared/legal'); app.get(legal.PATHS, legal.handler({ id: 'rent', service: 'rent', host: 'openvibe.rent', name: 'OpenVibe.Rent', profile: 'ugc' })); }
// ── OpenVibe.Events → this service (loopback only) ──────
ddiff --git a/server/render/layout.js b/server/render/layout.js
iindex e02e130..c19a3a5 100644
---- a/server/render/layout.js
++++ b/server/render/layout.js
@@@ -91,16 +91,12 @@ function renderPage(o) {
links: NAV.map((l) => ({ label: l.label, href: l.href, ...(l.icon ? { icon: l.icon } : {}), ...(l.more ? { more: true } : {}), active: pathNow === l.href || pathNow.startsWith(`${l.href}/`) })),
appBar: true, // phones: the places with icons as the bottom tab bar (Shared 4.20)
history: { type: 'page', title: o.title || SITE_NAME },
-- // On Homes the account lives on OpenVibe.Rent: its session probe answers signed out, and sign-in goes there.
-- ...(homes ? {
-- loginUrl: `${o.config.baseUrl}/auth/login?next=/board`,
-- } : {
-- silentLogin: `${o.config.baseUrl}/auth/login?silent=1&next={url}`,
-- sessionUrl: '/auth/me',
-- loginUrl: '/auth/login?next={path}', // filled from the current page (boost moves between pages)
-- logoutUrl: '/auth/logout?next={path}', // Sign out in the shared navbar ends this site's session too
-- notificationsRealtime: true, // the bell hears new notifications over OpenVibe.Events (Shared 1.22.0)
-- }),
++ silentLogin: '/auth/login?silent=1&next={url}',
++ sessionUrl: '/auth/me',
++ loginUrl: '/auth/login?next={path}',
++ logoutUrl: '/auth/logout?next={path}',
++ notificationsRealtime: true,
++
};
const footer = { service: 'rent', variant: 'full', mount: '#ov-footer', brandName: SITE_NAME, updates: homes ? `${o.config.baseUrl}/updates` : '/updates' };
const account = homes
ddiff --git a/test/homes.test.js b/test/homes.test.js
iindex 34cb323..b807b39 100644
---- a/test/homes.test.js
++++ b/test/homes.test.js
@@@ -66,10 +66,20 @@ const housingFetchImpl = async (url) => (new URL(String(url)).pathname.endsWith(
require('http').get({ hostname: u.hostname, port: u.port, path: u.pathname + u.search, headers: { Host: 'openvibe.homes' } }, (res) => {
const chunks = [];
res.on('data', (c) => chunks.push(c));
-- res.on('end', () => resolve({ status: res.statusCode, text: Buffer.concat(chunks).toString('utf8') }));
++ res.on('end', () => resolve({ status: res.statusCode, headers: res.headers, text: Buffer.concat(chunks).toString('utf8') }));
}).on('error', reject);
});
try {
++ await check('Homes owns its OAuth callback and silent session', async () => {
++ const started = await homes('/auth/login?silent=1&next=%2Fmortgage');
++ assert.strictEqual(started.status, 302);
++ const u = new URL(started.headers.location);
++ assert.strictEqual(u.searchParams.get('redirect_uri'), 'https://openvibe.homes/auth/callback');
++ assert.strictEqual(u.searchParams.get('prompt'), 'none');
++ const page = await homes('/');
++ assert.ok(page.text.includes('"silentLogin":"/auth/login?silent=1&next={url}"'));
++ assert.ok(page.text.includes('"sessionUrl":"/auth/me"'));
++ });
await check('the Homes host: its own home page and name; Rent\'s host is untouched', async () => {
const r = await homes('/');
assert.strictEqual(r.status, 200);