openvibers/openvibe.network Commits
Network: Actor, Food, Help, Work, Quest and Rent take part in account export and deletion (ADR-033, openvibe-sdk/account-data); five of them may subscribe to Events (#91)
Changes
@@@ -26,6 +26,8 @@ const DEFAULT_GRANTS = [['quest', 'network.coins.credit', SELF_AUDIENCE, ['quest']],['quest', 'identity.subject.resolve', SELF_AUDIENCE, []],['quest', 'events.subscription.manage', 'openvibe.events', []],++ // They subscribe to network.account.export_requested and network.account.deleted at boot (ADR-033).++ ...['actor', 'food', 'help', 'work', 'rent'].map((svc) => [svc, 'events.subscription.manage', 'openvibe.events', []]),['live', 'network.coins.debit', SELF_AUDIENCE, ['live']],['live', 'network.notifications.push', SELF_AUDIENCE, ['live']],// User modules: each service reads and writes the namespaces it owns (openvibe-contracts manifests/namespaces).@@@ -81,7 +83,8 @@ const DEFAULT_GRANTS = [['games', 'mods.grant.manage', SELF_AUDIENCE, []],// Account export and deletion (ADR-033): the services that keep data about people push their export part and// confirm a deletion; the holders of each grant are the services Network waits for.-- ...['live', 'chat', 'community', 'media', 'games'].flatMap((svc) => [++ // Since 2026-10-08 the services built from the skeleton answer too, through openvibe-sdk/account-data (SDK 0.36.0).++ ...['live', 'chat', 'community', 'media', 'games', 'actor', 'food', 'help', 'work', 'quest', 'rent'].flatMap((svc) => [[svc, 'network.account.export.contribute', SELF_AUDIENCE, []],[svc, 'network.account.deletion.confirm', SELF_AUDIENCE, []],]),@@@ -92,8 +92,18 @@ const server = http.createServer(app);await db.prepare("INSERT INTO user_preferences (user_id, language) VALUES (?, 'en')").run(dana.id);// ── Export ──++ const seeded = await accountData.expectedServices(db, 'network.account.export.contribute');++ assert.deepStrictEqual(seeded, ['actor', 'chat', 'community', 'food', 'games', 'help', 'live', 'media', 'quest', 'rent', 'work'],++ 'the holders of the contribute grant: the skeleton services answer too since 2026-10-08 (openvibe-sdk/account-data); Space left with the forum');++ // The scenarios below follow five services; the six newer ones are set aside here, exactly as an operator would++ // revoke a service's grant (the same rows, the same revoked_at).++ for (const svc of ['actor', 'food', 'help', 'quest', 'rent', 'work']) {++ for (const cap of ['network.account.export.contribute', 'network.account.deletion.confirm']) {++ await db.prepare('UPDATE principal_grants SET revoked_at = ov_now() WHERE client_id = ? AND capability = ? AND revoked_at IS NULL').run(svc, cap);++ }++ }const expected = await accountData.expectedServices(db, 'network.account.export.contribute');-- assert.deepStrictEqual(expected, ['chat', 'community', 'games', 'live', 'media'], 'the holders of the contribute grant (Space left with the forum, contracts 0.118.0)');++ assert.deepStrictEqual(expected, ['chat', 'community', 'games', 'live', 'media'], 'the five this scenario follows');let r = await call('POST', '/api/v1/account/export', tok(dana));assert.strictEqual(r.status, 201, JSON.stringify(r.body));assert.ok(validate('network.account-export@1', r.body).valid, JSON.stringify(validate('network.account-export@1', r.body).errors));
@@ -26,6 +26,8 @@ const DEFAULT_GRANTS = [
@@ -26,6 +26,8 @@ const DEFAULT_GRANTS = [
['quest', 'network.coins.credit', SELF_AUDIENCE, ['quest']],
['quest', 'network.coins.credit', SELF_AUDIENCE, ['quest']],
['quest', 'identity.subject.resolve', SELF_AUDIENCE, []],
['quest', 'identity.subject.resolve', SELF_AUDIENCE, []],
['quest', 'events.subscription.manage', 'openvibe.events', []],
['quest', 'events.subscription.manage', 'openvibe.events', []],
+ // They subscribe to network.account.export_requested and network.account.deleted at boot (ADR-033).
+ ...['actor', 'food', 'help', 'work', 'rent'].map((svc) => [svc, 'events.subscription.manage', 'openvibe.events', []]),
['live', 'network.coins.debit', SELF_AUDIENCE, ['live']],
['live', 'network.coins.debit', SELF_AUDIENCE, ['live']],
['live', 'network.notifications.push', SELF_AUDIENCE, ['live']],
['live', 'network.notifications.push', SELF_AUDIENCE, ['live']],
// User modules: each service reads and writes the namespaces it owns (openvibe-contracts manifests/namespaces).
// User modules: each service reads and writes the namespaces it owns (openvibe-contracts manifests/namespaces).
@@ -81,7 +83,8 @@ const DEFAULT_GRANTS = [
@@ -81,7 +83,8 @@ const DEFAULT_GRANTS = [
['games', 'mods.grant.manage', SELF_AUDIENCE, []],
['games', 'mods.grant.manage', SELF_AUDIENCE, []],
// Account export and deletion (ADR-033): the services that keep data about people push their export part and
// Account export and deletion (ADR-033): the services that keep data about people push their export part and
// confirm a deletion; the holders of each grant are the services Network waits for.
// confirm a deletion; the holders of each grant are the services Network waits for.
- ...['live', 'chat', 'community', 'media', 'games'].flatMap((svc) => [
+ // Since 2026-10-08 the services built from the skeleton answer too, through openvibe-sdk/account-data (SDK 0.36.0).
+ ...['live', 'chat', 'community', 'media', 'games', 'actor', 'food', 'help', 'work', 'quest', 'rent'].flatMap((svc) => [
[svc, 'network.account.export.contribute', SELF_AUDIENCE, []],
[svc, 'network.account.export.contribute', SELF_AUDIENCE, []],
[svc, 'network.account.deletion.confirm', SELF_AUDIENCE, []],
[svc, 'network.account.deletion.confirm', SELF_AUDIENCE, []],
]),
]),
@@ -92,8 +92,18 @@ const server = http.createServer(app);
@@ -92,8 +92,18 @@ const server = http.createServer(app);
await db.prepare("INSERT INTO user_preferences (user_id, language) VALUES (?, 'en')").run(dana.id);
await db.prepare("INSERT INTO user_preferences (user_id, language) VALUES (?, 'en')").run(dana.id);
// ── Export ──
// ── Export ──
+ const seeded = await accountData.expectedServices(db, 'network.account.export.contribute');
+ assert.deepStrictEqual(seeded, ['actor', 'chat', 'community', 'food', 'games', 'help', 'live', 'media', 'quest', 'rent', 'work'],
+ 'the holders of the contribute grant: the skeleton services answer too since 2026-10-08 (openvibe-sdk/account-data); Space left with the forum');
+ // The scenarios below follow five services; the six newer ones are set aside here, exactly as an operator would
+ // revoke a service's grant (the same rows, the same revoked_at).
+ for (const svc of ['actor', 'food', 'help', 'quest', 'rent', 'work']) {
+ for (const cap of ['network.account.export.contribute', 'network.account.deletion.confirm']) {
+ await db.prepare('UPDATE principal_grants SET revoked_at = ov_now() WHERE client_id = ? AND capability = ? AND revoked_at IS NULL').run(svc, cap);
+ }
+ }
const expected = await accountData.expectedServices(db, 'network.account.export.contribute');
const expected = await accountData.expectedServices(db, 'network.account.export.contribute');
- assert.deepStrictEqual(expected, ['chat', 'community', 'games', 'live', 'media'], 'the holders of the contribute grant (Space left with the forum, contracts 0.118.0)');
+ assert.deepStrictEqual(expected, ['chat', 'community', 'games', 'live', 'media'], 'the five this scenario follows');
let r = await call('POST', '/api/v1/account/export', tok(dana));
let r = await call('POST', '/api/v1/account/export', tok(dana));
assert.strictEqual(r.status, 201, JSON.stringify(r.body));
assert.strictEqual(r.status, 201, JSON.stringify(r.body));
assert.ok(validate('network.account-export@1', r.body).valid, JSON.stringify(validate('network.account-export@1', r.body).errors));
assert.ok(validate('network.account-export@1', r.body).valid, JSON.stringify(validate('network.account-export@1', r.body).errors));