openvibers/openvibe.network Commits
Network: grants follow static hosting to Space (events publish, Services' resource fan-out); Host's engine grants revoked (#160)
Changes
@@@ -732,7 +732,7 @@ Reporting a vulnerability: [SECURITY.md](SECURITY.md). The rules the code keeps:Same as the parent [OpenVibe](../LICENSE) project.<!-- versions:start -->--- openvibe-contracts: v0.148.0++- openvibe-contracts: v0.150.0- openvibe-sdk: v0.44.0- openvibe-shared: v4.0.0<!-- versions:end -->@@@ -6,7 +6,7 @@"runtime": "node 22, express, PostgreSQL 18 (openvibe-sdk/db, async) + Valkey 9","port": 4000,"domain": "openvibe.network (with auth., api., admin., my. and themes.openvibe.network in its manifest)",-- "contracts": "openvibe-contracts v0.148.0",++ "contracts": "openvibe-contracts v0.150.0","sdk": "openvibe-sdk v0.44.0","shared": "openvibe-shared v4.0.0","capabilities": [@@@ -20,7 +20,7 @@"iovalkey": "^0.4.0","jsonwebtoken": "^9.0.0","multer": "^1.4.5-lts.1",-- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.148.0",++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.150.0","openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.44.0","openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.0.0","pg": "^8.23.0",@@@ -1320,9 +1320,9 @@}},"node_modules/openvibe-contracts": {-- "version": "0.148.0",-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.148.0",-- "integrity": "sha512-IojUJ27+/SngR6QWJysym0J+LjcWDuXQOQ/zdz+toSmw/dmLrsYpmUp+GD75Qt2Ak6LjnKLUtGcjTH2GAYO2mw==",++ "version": "0.150.0",++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.150.0",++ "integrity": "sha512-CNKm1UpEynr56yIK9ppnpSAM2JXT+YLuPbLGzw4tB9A3pX/rfSIKlo8Pj3agEkoNwwlavXDdXv9az1S0Gg2H7g==","license": "AGPL-3.0-only","dependencies": {"ajv": "^8.17.1",@@@ -24,7 +24,7 @@"iovalkey": "^0.4.0","jsonwebtoken": "^9.0.0","multer": "^1.4.5-lts.1",-- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.148.0",++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.150.0","openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.44.0","openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.0.0","pg": "^8.23.0",@@@ -77,10 +77,6 @@ const DEFAULT_GRANTS = [['games', 'media.object.upload', 'openvibe.media', ['games']],// Plan T12: Host keeps tenant deploy files in Media (Host#24, HOST_OBJECT_STORE=media), its own namespace only:// write-through on deploy, re-fetch on a cache miss, list and delete when its GC finds a blob unreferenced.-- ['host', 'media.object.upload', 'openvibe.media', ['host', 'host.*']],-- ['host', 'media.object.read', 'openvibe.media', ['host', 'host.*']],-- ['host', 'media.object.list', 'openvibe.media', ['host', 'host.*']],-- ['host', 'media.object.delete', 'openvibe.media', ['host', 'host.*']],// Plan T4 (Media cleanup): Live and OpenRestream reach Media with their own tokens instead of API keys. Live keeps// its objects under the live namespace (VOD/clip/thumbnail uploads, reads, lists, deletes); OpenRestream uploads the// recordings and thumbnails it produces there too.@@@ -191,6 +187,9 @@ const DEFAULT_GRANTS = [['coupons', 'events.subscription.manage', 'openvibe.events', []],['coupons', 'sources.item.read', 'openvibe.sources', []],['host', 'events.event.publish', 'openvibe.events', []],++ // T20 step 2 (2026-10-12, Space#36): the static hosting engine moved to Space, which publishes space.deploy.* and++ // space.domain.verified through its outbox. (Its forum-era grants stay revoked below.)++ ['space', 'events.event.publish', 'openvibe.events', []],// The hosting catalog (plan T20 step 3) reads OpenVibe.Sources items in category hosting (Host#69).['host', 'sources.item.read', 'openvibe.sources', []],// The hosting catalog's provider and plan discussion threads on OpenVibe.Community (Host#74).@@@ -239,7 +238,8 @@ const DEFAULT_GRANTS = [['services', 'network.resource.read', SELF_AUDIENCE, []],// Phase 2 (contracts 0.129.0-0.134.0): watches, Actor tasks, robots, rooms, OpenRestream's streams and Community's// pastes and spaces.-- ...['media', 'events', 'host', 'watch', 'actor', 'bot', 'chat', 'openre', 'community'].map(id => ['services', `${id}.resource.read`, `openvibe.${id}`, []]),++ // Since contracts 0.150.0 the static hosting index is Space's (space.resource.read); Host's is retired.++ ...['media', 'events', 'space', 'watch', 'actor', 'bot', 'chat', 'openre', 'community'].map(id => ['services', `${id}.resource.read`, `openvibe.${id}`, []]),// Plan T14: OpenVibe.Run publishes run.job.* and hands each job to a paired Node through Bot's internal jobs API// (POST /api/v1/jobs, /jobs/:id/cancel, GET /jobs/:id, capability bot.job.dispatch, service-to-service only).['run', 'events.event.publish', 'openvibe.events', []],@@@ -378,10 +378,16 @@ const REVOKED_GRANTS = [['space', 'vip.resource.policy.evaluate', 'openvibe.vip'],['space', 'events.subscription.manage', 'openvibe.events'],['space', 'events.event.read', 'openvibe.events'],-- ['space', 'events.event.publish', 'openvibe.events'],['space', 'network.blocks.read', SELF_AUDIENCE],['space', 'network.account.export.contribute', SELF_AUDIENCE],['space', 'network.account.deletion.confirm', SELF_AUDIENCE],++ // The static hosting engine left Host (T20, Host#84, contracts 0.150.0): its Media objects and Services' fan-out to++ // its resource index go. Space serves the engine.++ ['host', 'media.object.upload', 'openvibe.media'],++ ['host', 'media.object.read', 'openvibe.media'],++ ['host', 'media.object.list', 'openvibe.media'],++ ['host', 'media.object.delete', 'openvibe.media'],++ ['services', 'host.resource.read', 'openvibe.host'],];// Default grants whose namespaces changed: a row still exactly as the old default seeded it is moved to@@@ -170,8 +170,8 @@ const server = http.createServer(app);assert.strictEqual(com.status, 200, JSON.stringify(com.body));assert.deepStrictEqual(com.body.scope.split(' '), ['identity.subject.resolve', 'network.account.deletion.confirm', 'network.account.export.contribute', 'network.blocks.read', 'network.modules.read', 'network.modules.write'], 'resolve, account export and deletion, platform blocks, plus its community.profile module');await db.prepare("UPDATE oauth_clients SET client_secret = 'space-secret' WHERE client_id = 'space'").run();-- // The forum returned to Community (contracts 0.118.0): Space keeps only its sign-in client, so its service token-- // gets no grant on any audience.++ // The forum returned to Community (contracts 0.118.0) and its grants went; since the static hosting engine moved to++ // Space (T20 step 2, contracts 0.149.0) Space publishes its hosting events, and nothing else.const spaceNetwork = await token({ client_id: 'space', client_secret: 'space-secret', audience: 'openvibe.network' });assert.strictEqual(spaceNetwork.status, 400, 'Space holds no Network grant');r = await post('/internal/identity/resolve-batch', { system: 'network', ids: ['7'] }, { authorization: `Bearer ${com.body.access_token}` });@@@ -195,10 +195,13 @@ const server = http.createServer(app);assert.strictEqual(r.status, 403, 'Media holds no coin capability');const media = await token({ client_id: 'community', client_secret: 'community-secret', audience: 'openvibe.media' });assert.strictEqual(media.body.scope, 'media.object.upload', 'community may upload screenshot bytes to Media');-- for (const audience of ['openvibe.media', 'openvibe.vip', 'openvibe.events']) {++ for (const audience of ['openvibe.media', 'openvibe.vip']) {const response = await token({ client_id: 'space', client_secret: 'space-secret', audience });assert.strictEqual(response.status, 400, `Space holds no ${audience} grant`);}++ const spaceEvents = await token({ client_id: 'space', client_secret: 'space-secret', audience: 'openvibe.events' });++ assert.strictEqual(spaceEvents.status, 200, JSON.stringify(spaceEvents.body));++ assert.strictEqual(spaceEvents.body.scope, 'events.event.publish', 'Space publishes its hosting events and nothing more');const cm = await token({ client_id: 'live', client_secret: 'live-secret', audience: 'openvibe.community' });assert.deepStrictEqual(cm.body.scope.split(' '), ['community.comment.moderate', 'community.comment.write', 'community.paste.create', 'community.paste.moderate', 'community.paste.write', 'community.pulse.write']);const tl = await token({ client_id: 'live', client_secret: 'live-secret', audience: 'openvibe.tools' });@@@ -33,5 +33,5 @@ for (const [id] of granted) {assert.ok(cap && cap.status !== 'retired', `services holds ${id}, which the contracts do not offer`);assert.ok(!revoked.has(id), `${id} is both granted and revoked`);}--assert.ok(checked >= 4, `at least Network, Media, Events and Host are active authorities (${checked})`);++assert.ok(checked >= 4, `at least Network, Media, Events and Space are active authorities (${checked})`);console.log(`services resource grants: ${checked} active authorities granted, ${granted.size} grants in all`);
@@ -732,7 +732,7 @@ Reporting a vulnerability: [SECURITY.md](SECURITY.md). The rules the code keeps:
@@ -732,7 +732,7 @@ Reporting a vulnerability: [SECURITY.md](SECURITY.md). The rules the code keeps:
Same as the parent [OpenVibe](../LICENSE) project.
Same as the parent [OpenVibe](../LICENSE) project.
<!-- versions:start -->
<!-- versions:start -->
-- openvibe-contracts: v0.148.0
+- openvibe-contracts: v0.150.0
- openvibe-sdk: v0.44.0
- openvibe-sdk: v0.44.0
- openvibe-shared: v4.0.0
- openvibe-shared: v4.0.0
<!-- versions:end -->
<!-- versions:end -->
@@ -6,7 +6,7 @@
@@ -6,7 +6,7 @@
"runtime": "node 22, express, PostgreSQL 18 (openvibe-sdk/db, async) + Valkey 9",
"runtime": "node 22, express, PostgreSQL 18 (openvibe-sdk/db, async) + Valkey 9",
"port": 4000,
"port": 4000,
"domain": "openvibe.network (with auth., api., admin., my. and themes.openvibe.network in its manifest)",
"domain": "openvibe.network (with auth., api., admin., my. and themes.openvibe.network in its manifest)",
- "contracts": "openvibe-contracts v0.148.0",
+ "contracts": "openvibe-contracts v0.150.0",
"sdk": "openvibe-sdk v0.44.0",
"sdk": "openvibe-sdk v0.44.0",
"shared": "openvibe-shared v4.0.0",
"shared": "openvibe-shared v4.0.0",
"capabilities": [
"capabilities": [
@@ -20,7 +20,7 @@
@@ -20,7 +20,7 @@
"iovalkey": "^0.4.0",
"iovalkey": "^0.4.0",
"jsonwebtoken": "^9.0.0",
"jsonwebtoken": "^9.0.0",
"multer": "^1.4.5-lts.1",
"multer": "^1.4.5-lts.1",
- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.148.0",
+ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.150.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.44.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.44.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.0.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.0.0",
"pg": "^8.23.0",
"pg": "^8.23.0",
@@ -1320,9 +1320,9 @@
@@ -1320,9 +1320,9 @@
}
}
},
},
"node_modules/openvibe-contracts": {
"node_modules/openvibe-contracts": {
- "version": "0.148.0",
- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.148.0",
- "integrity": "sha512-IojUJ27+/SngR6QWJysym0J+LjcWDuXQOQ/zdz+toSmw/dmLrsYpmUp+GD75Qt2Ak6LjnKLUtGcjTH2GAYO2mw==",
+ "version": "0.150.0",
+ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.150.0",
+ "integrity": "sha512-CNKm1UpEynr56yIK9ppnpSAM2JXT+YLuPbLGzw4tB9A3pX/rfSIKlo8Pj3agEkoNwwlavXDdXv9az1S0Gg2H7g==",
"license": "AGPL-3.0-only",
"license": "AGPL-3.0-only",
"dependencies": {
"dependencies": {
"ajv": "^8.17.1",
"ajv": "^8.17.1",
@@ -24,7 +24,7 @@
@@ -24,7 +24,7 @@
"iovalkey": "^0.4.0",
"iovalkey": "^0.4.0",
"jsonwebtoken": "^9.0.0",
"jsonwebtoken": "^9.0.0",
"multer": "^1.4.5-lts.1",
"multer": "^1.4.5-lts.1",
- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.148.0",
+ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.150.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.44.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.44.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.0.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.0.0",
"pg": "^8.23.0",
"pg": "^8.23.0",
@@ -77,10 +77,6 @@ const DEFAULT_GRANTS = [
@@ -77,10 +77,6 @@ const DEFAULT_GRANTS = [
['games', 'media.object.upload', 'openvibe.media', ['games']],
['games', 'media.object.upload', 'openvibe.media', ['games']],
// Plan T12: Host keeps tenant deploy files in Media (Host#24, HOST_OBJECT_STORE=media), its own namespace only:
// Plan T12: Host keeps tenant deploy files in Media (Host#24, HOST_OBJECT_STORE=media), its own namespace only:
// write-through on deploy, re-fetch on a cache miss, list and delete when its GC finds a blob unreferenced.
// write-through on deploy, re-fetch on a cache miss, list and delete when its GC finds a blob unreferenced.
- ['host', 'media.object.upload', 'openvibe.media', ['host', 'host.*']],
- ['host', 'media.object.read', 'openvibe.media', ['host', 'host.*']],
- ['host', 'media.object.list', 'openvibe.media', ['host', 'host.*']],
- ['host', 'media.object.delete', 'openvibe.media', ['host', 'host.*']],
// Plan T4 (Media cleanup): Live and OpenRestream reach Media with their own tokens instead of API keys. Live keeps
// Plan T4 (Media cleanup): Live and OpenRestream reach Media with their own tokens instead of API keys. Live keeps
// its objects under the live namespace (VOD/clip/thumbnail uploads, reads, lists, deletes); OpenRestream uploads the
// its objects under the live namespace (VOD/clip/thumbnail uploads, reads, lists, deletes); OpenRestream uploads the
// recordings and thumbnails it produces there too.
// recordings and thumbnails it produces there too.
@@ -191,6 +187,9 @@ const DEFAULT_GRANTS = [
@@ -191,6 +187,9 @@ const DEFAULT_GRANTS = [
['coupons', 'events.subscription.manage', 'openvibe.events', []],
['coupons', 'events.subscription.manage', 'openvibe.events', []],
['coupons', 'sources.item.read', 'openvibe.sources', []],
['coupons', 'sources.item.read', 'openvibe.sources', []],
['host', 'events.event.publish', 'openvibe.events', []],
['host', 'events.event.publish', 'openvibe.events', []],
+ // T20 step 2 (2026-10-12, Space#36): the static hosting engine moved to Space, which publishes space.deploy.* and
+ // space.domain.verified through its outbox. (Its forum-era grants stay revoked below.)
+ ['space', 'events.event.publish', 'openvibe.events', []],
// The hosting catalog (plan T20 step 3) reads OpenVibe.Sources items in category hosting (Host#69).
// The hosting catalog (plan T20 step 3) reads OpenVibe.Sources items in category hosting (Host#69).
['host', 'sources.item.read', 'openvibe.sources', []],
['host', 'sources.item.read', 'openvibe.sources', []],
// The hosting catalog's provider and plan discussion threads on OpenVibe.Community (Host#74).
// The hosting catalog's provider and plan discussion threads on OpenVibe.Community (Host#74).
@@ -239,7 +238,8 @@ const DEFAULT_GRANTS = [
@@ -239,7 +238,8 @@ const DEFAULT_GRANTS = [
['services', 'network.resource.read', SELF_AUDIENCE, []],
['services', 'network.resource.read', SELF_AUDIENCE, []],
// Phase 2 (contracts 0.129.0-0.134.0): watches, Actor tasks, robots, rooms, OpenRestream's streams and Community's
// Phase 2 (contracts 0.129.0-0.134.0): watches, Actor tasks, robots, rooms, OpenRestream's streams and Community's
// pastes and spaces.
// pastes and spaces.
- ...['media', 'events', 'host', 'watch', 'actor', 'bot', 'chat', 'openre', 'community'].map(id => ['services', `${id}.resource.read`, `openvibe.${id}`, []]),
+ // Since contracts 0.150.0 the static hosting index is Space's (space.resource.read); Host's is retired.
+ ...['media', 'events', 'space', 'watch', 'actor', 'bot', 'chat', 'openre', 'community'].map(id => ['services', `${id}.resource.read`, `openvibe.${id}`, []]),
// Plan T14: OpenVibe.Run publishes run.job.* and hands each job to a paired Node through Bot's internal jobs API
// Plan T14: OpenVibe.Run publishes run.job.* and hands each job to a paired Node through Bot's internal jobs API
// (POST /api/v1/jobs, /jobs/:id/cancel, GET /jobs/:id, capability bot.job.dispatch, service-to-service only).
// (POST /api/v1/jobs, /jobs/:id/cancel, GET /jobs/:id, capability bot.job.dispatch, service-to-service only).
['run', 'events.event.publish', 'openvibe.events', []],
['run', 'events.event.publish', 'openvibe.events', []],
@@ -378,10 +378,16 @@ const REVOKED_GRANTS = [
@@ -378,10 +378,16 @@ const REVOKED_GRANTS = [
['space', 'vip.resource.policy.evaluate', 'openvibe.vip'],
['space', 'vip.resource.policy.evaluate', 'openvibe.vip'],
['space', 'events.subscription.manage', 'openvibe.events'],
['space', 'events.subscription.manage', 'openvibe.events'],
['space', 'events.event.read', 'openvibe.events'],
['space', 'events.event.read', 'openvibe.events'],
- ['space', 'events.event.publish', 'openvibe.events'],
['space', 'network.blocks.read', SELF_AUDIENCE],
['space', 'network.blocks.read', SELF_AUDIENCE],
['space', 'network.account.export.contribute', SELF_AUDIENCE],
['space', 'network.account.export.contribute', SELF_AUDIENCE],
['space', 'network.account.deletion.confirm', SELF_AUDIENCE],
['space', 'network.account.deletion.confirm', SELF_AUDIENCE],
+ // The static hosting engine left Host (T20, Host#84, contracts 0.150.0): its Media objects and Services' fan-out to
+ // its resource index go. Space serves the engine.
+ ['host', 'media.object.upload', 'openvibe.media'],
+ ['host', 'media.object.read', 'openvibe.media'],
+ ['host', 'media.object.list', 'openvibe.media'],
+ ['host', 'media.object.delete', 'openvibe.media'],
+ ['services', 'host.resource.read', 'openvibe.host'],
];
];
// Default grants whose namespaces changed: a row still exactly as the old default seeded it is moved to
// Default grants whose namespaces changed: a row still exactly as the old default seeded it is moved to
@@ -170,8 +170,8 @@ const server = http.createServer(app);
@@ -170,8 +170,8 @@ const server = http.createServer(app);
assert.strictEqual(com.status, 200, JSON.stringify(com.body));
assert.strictEqual(com.status, 200, JSON.stringify(com.body));
assert.deepStrictEqual(com.body.scope.split(' '), ['identity.subject.resolve', 'network.account.deletion.confirm', 'network.account.export.contribute', 'network.blocks.read', 'network.modules.read', 'network.modules.write'], 'resolve, account export and deletion, platform blocks, plus its community.profile module');
assert.deepStrictEqual(com.body.scope.split(' '), ['identity.subject.resolve', 'network.account.deletion.confirm', 'network.account.export.contribute', 'network.blocks.read', 'network.modules.read', 'network.modules.write'], 'resolve, account export and deletion, platform blocks, plus its community.profile module');
await db.prepare("UPDATE oauth_clients SET client_secret = 'space-secret' WHERE client_id = 'space'").run();
await db.prepare("UPDATE oauth_clients SET client_secret = 'space-secret' WHERE client_id = 'space'").run();
- // The forum returned to Community (contracts 0.118.0): Space keeps only its sign-in client, so its service token
- // gets no grant on any audience.
+ // The forum returned to Community (contracts 0.118.0) and its grants went; since the static hosting engine moved to
+ // Space (T20 step 2, contracts 0.149.0) Space publishes its hosting events, and nothing else.
const spaceNetwork = await token({ client_id: 'space', client_secret: 'space-secret', audience: 'openvibe.network' });
const spaceNetwork = await token({ client_id: 'space', client_secret: 'space-secret', audience: 'openvibe.network' });
assert.strictEqual(spaceNetwork.status, 400, 'Space holds no Network grant');
assert.strictEqual(spaceNetwork.status, 400, 'Space holds no Network grant');
r = await post('/internal/identity/resolve-batch', { system: 'network', ids: ['7'] }, { authorization: `Bearer ${com.body.access_token}` });
r = await post('/internal/identity/resolve-batch', { system: 'network', ids: ['7'] }, { authorization: `Bearer ${com.body.access_token}` });
@@ -195,10 +195,13 @@ const server = http.createServer(app);
@@ -195,10 +195,13 @@ const server = http.createServer(app);
assert.strictEqual(r.status, 403, 'Media holds no coin capability');
assert.strictEqual(r.status, 403, 'Media holds no coin capability');
const media = await token({ client_id: 'community', client_secret: 'community-secret', audience: 'openvibe.media' });
const media = await token({ client_id: 'community', client_secret: 'community-secret', audience: 'openvibe.media' });
assert.strictEqual(media.body.scope, 'media.object.upload', 'community may upload screenshot bytes to Media');
assert.strictEqual(media.body.scope, 'media.object.upload', 'community may upload screenshot bytes to Media');
- for (const audience of ['openvibe.media', 'openvibe.vip', 'openvibe.events']) {
+ for (const audience of ['openvibe.media', 'openvibe.vip']) {
const response = await token({ client_id: 'space', client_secret: 'space-secret', audience });
const response = await token({ client_id: 'space', client_secret: 'space-secret', audience });
assert.strictEqual(response.status, 400, `Space holds no ${audience} grant`);
assert.strictEqual(response.status, 400, `Space holds no ${audience} grant`);
}
}
+ const spaceEvents = await token({ client_id: 'space', client_secret: 'space-secret', audience: 'openvibe.events' });
+ assert.strictEqual(spaceEvents.status, 200, JSON.stringify(spaceEvents.body));
+ assert.strictEqual(spaceEvents.body.scope, 'events.event.publish', 'Space publishes its hosting events and nothing more');
const cm = await token({ client_id: 'live', client_secret: 'live-secret', audience: 'openvibe.community' });
const cm = await token({ client_id: 'live', client_secret: 'live-secret', audience: 'openvibe.community' });
assert.deepStrictEqual(cm.body.scope.split(' '), ['community.comment.moderate', 'community.comment.write', 'community.paste.create', 'community.paste.moderate', 'community.paste.write', 'community.pulse.write']);
assert.deepStrictEqual(cm.body.scope.split(' '), ['community.comment.moderate', 'community.comment.write', 'community.paste.create', 'community.paste.moderate', 'community.paste.write', 'community.pulse.write']);
const tl = await token({ client_id: 'live', client_secret: 'live-secret', audience: 'openvibe.tools' });
const tl = await token({ client_id: 'live', client_secret: 'live-secret', audience: 'openvibe.tools' });
@@ -33,5 +33,5 @@ for (const [id] of granted) {
@@ -33,5 +33,5 @@ for (const [id] of granted) {
assert.ok(cap && cap.status !== 'retired', `services holds ${id}, which the contracts do not offer`);
assert.ok(cap && cap.status !== 'retired', `services holds ${id}, which the contracts do not offer`);
assert.ok(!revoked.has(id), `${id} is both granted and revoked`);
assert.ok(!revoked.has(id), `${id} is both granted and revoked`);
}
}
-assert.ok(checked >= 4, `at least Network, Media, Events and Host are active authorities (${checked})`);
+assert.ok(checked >= 4, `at least Network, Media, Events and Space are active authorities (${checked})`);
console.log(`services resource grants: ${checked} active authorities granted, ${granted.size} grants in all`);
console.log(`services resource grants: ${checked} active authorities granted, ${granted.size} grants in all`);