openvibers/openvibe.network Commits

Seed Directory OAuth callback for opt-in listings (#820)

OP OpenVibers committed 2 days ago · d56a927095 · 4 files, +7 −4

* Seed Directory OAuth callback for opt-in listings

* Place Directory in the Network site menu

* Update site group count for Directory

Changes

ddiff --git a/server/db/database.js b/server/db/database.js
iindex 20cf91b6..348b383d 100644
---- a/server/db/database.js
++++ b/server/db/database.js
@@@ -150,6 +150,7 @@ async function seedDb(db, { log = console } = {}) {
{ client_id: 'vision', name: 'OpenVibe.Vision', redirect_uris: ['https://openvibe.vision/auth/callback'] },
// Free and swap listings with a permission passport, a sandbox and one-tap revoke (the Exchange room).
{ client_id: 'exchange', name: 'OpenVibe.Exchange', redirect_uris: ['https://openvibe.exchange/auth/callback'] },
++ { client_id: 'directory', name: 'OpenVibe.Directory', redirect_uris: ['https://openvibe.directory/auth/callback'] },
// IRL quest boards on a public Live channel, a local guide and group plans (the Fun room).
{ client_id: 'fun', name: 'OpenVibe.Fun', redirect_uris: ['https://openvibe.fun/auth/callback'] },
// The camera app, a private wall for cameras people own, and the still Live's cam button takes.
ddiff --git a/server/frame/sites.js b/server/frame/sites.js
iindex 35f42660..36742b13 100644
---- a/server/frame/sites.js
++++ b/server/frame/sites.js
@@@ -68,7 +68,7 @@ const GROUPS = [
{ id: 'tools', name: 'Free tools', sites: ['tools', 'design', 'domains', 'host', 'image', 'lock', 'food'] },
// Actor is the engine behind every agent (Codes' Auto, Vibe, the Dock call it): a developer service, not a second
// place to chat with an agent (plan L39, 2026-10-31). It makes things with AI, beside the places that do.
-- { id: 'make', name: 'Make with AI', sites: ['space', 'codes', 'bot', 'actor', 'computer', 'connect'] },
++ { id: 'make', name: 'Make with AI', sites: ['space', 'codes', 'bot', 'actor', 'computer', 'connect', 'directory'] },
{ id: 'build', name: 'For developers', sites: ['services', 'exchange', 'run', 'zone', 'events', 'watch', 'git'] },
];
// What each site is, in a few words, for the menus (the launcher's rows are two to a line on a phone: about 22
@@@ -82,7 +82,7 @@ const MENU_LINE = {
news: 'Sourced, not spun', today: 'Your schedule', report: 'Your numbers, honest', search: 'Search everything', wiki: 'Facts with sources', blog: 'Write long-form', vision: 'Ask a picture',
deals: 'Deals people share', coupons: 'Codes that work', shoes: 'Every shoe, every price', reviews: 'Honest reviews', trade: 'Watch the markets', rent: 'Places to rent', work: 'Find a job',
tools: 'Every online tool', design: 'Try themes live', domains: 'Names and prices', host: 'Compare hosting', image: 'Edit photos in your browser', lock: 'Files only you can open', food: 'Food near you',
-- space: 'Host a site or app', codes: 'Code with any agent', bot: 'Drive a robot', actor: 'The agent engine', computer: 'Your computer, your way', connect: 'Share a port with Link',
++ space: 'Host a site or app', codes: 'Code with any agent', bot: 'Drive a robot', actor: 'The agent engine', computer: 'Your computer, your way', connect: 'Share a port with Link', directory: 'Listings with sources',
services: 'APIs, SDK and keys', exchange: 'AI models, one account', run: 'Run jobs anywhere', zone: 'S3 storage', events: 'Event streams', watch: 'Know when it changes', git: 'Host and browse code',
};
ddiff --git a/test/site-groups.test.js b/test/site-groups.test.js
iindex d470a09a..5985d904 100644
---- a/test/site-groups.test.js
++++ b/test/site-groups.test.js
@@@ -16,8 +16,8 @@ assert.deepStrictEqual(GROUPS.map((g) => g.id), ['watch', 'talk', 'play', 'read'
// At most seven tiles a group, and every listed place in exactly one group.
for (const g of GROUPS) assert.ok(g.sites.length <= 7, `${g.name}: ${g.sites.length} tiles`);
for (const s of LISTED) assert.strictEqual(GROUPS.filter((g) => g.sites.includes(s.id)).length, 1, `${s.id}: exactly one group`);
--assert.deepStrictEqual(GROUPS.map((g) => g.sites.length), [7, 7, 7, 7, 7, 7, 6, 7]);
--assert.strictEqual(LISTED.filter((s) => s.status === 'open').length, 55, 'the one number: 53 open sites plus Pics and Download');
++assert.deepStrictEqual(GROUPS.map((g) => g.sites.length), [7, 7, 7, 7, 7, 7, 7, 7]);
++assert.strictEqual(LISTED.filter((s) => s.status === 'open').length, 55 + Number(Boolean(contracts.services.get('directory'))), 'the open sites plus Pics and Download; Directory joins after its Contracts release');
assert.deepStrictEqual(PRODUCTS.map((p) => LISTED.find((s) => s.id === p.id).status), ['open', 'open'], 'Pics and Download are open entries');
// Every manifest site is in one group, or is one of the named merges: Media into Video, Bench into Report,
ddiff --git a/test/web-client-callbacks.test.js b/test/web-client-callbacks.test.js
iindex 05e4f5bf..b15e9ec9 100644
---- a/test/web-client-callbacks.test.js
++++ b/test/web-client-callbacks.test.js
@@@ -27,5 +27,7 @@ const { getDb, seedDb } = require('../server/db/database');
const computer = await db.prepare("SELECT redirect_uris FROM oauth_clients WHERE client_id = 'computer'").get();
assert.ok(computer, 'Computer has a first-party confidential OAuth client');
assert.deepEqual(JSON.parse(computer.redirect_uris), ['https://openvibe.computer/auth/callback']);
++ const directory = await db.prepare("SELECT redirect_uris FROM oauth_clients WHERE client_id = 'directory'").get();
++ assert.deepEqual(JSON.parse(directory.redirect_uris), ['https://openvibe.directory/auth/callback']);
console.log('web client callbacks: exact URIs, idempotence and credential preservation passed');
})().catch(err => { console.error(err); process.exitCode = 1; });