openvibers/openvibe.network Commits
Grant Design the Exchange icon-search capability (#841)
Changes
@@@ -22,7 +22,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.406.0",++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.407.0","openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.147.0","openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.206.0","otpauth": "9.6.0",@@@ -2679,9 +2679,9 @@}},"node_modules/openvibe-contracts": {-- "version": "0.406.0",-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.406.0",-- "integrity": "sha512-V/Tjss2UWvzI551bw3ACb/RqWg0lChxGITxfCVZ8qou2Docg0pBMvIjkeQoib56yq3r6UZGB6DGl+pA+qfjOiA==",++ "version": "0.407.0",++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.407.0",++ "integrity": "sha512-i+brTUApefkumQu1Ra4GFkZqwd2+mWBIEW8Ra55Eid5Bn6Q29cVNMl57EKI9uzlOauzc6s6ut5r55NWepRoMSQ==","license": "AGPL-3.0-only","dependencies": {"ajv": "^8.17.1",@@@ -26,7 +26,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.406.0",++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.407.0","openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.147.0","openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.206.0","otpauth": "9.6.0",@@@ -839,6 +839,11 @@ const DEFAULT_GRANTS = [// what passes `prefer` to the router). Without ai.chat every unpinned frame was refused ("this token may not run// ai.chat") from 10-31 to 11-02.['design', 'ai.run.create', 'openvibe.ai', ['ai.generate', 'ai.chat']],++ // The Exchange platform API's icon reference search (contracts 0.407.0, exchange.search.icons): Design asks++ // OpenVibe.AI for the references beside a glyph draft with its own service token, so no Exchange key is needed,++ // and reaches only POST /v1/search/icons. This grant was never granted or revoked before, so it needs no++ // RESTORED_GRANTS entry; the seed inserts it at boot.++ ['design', 'exchange.search.icons', 'openvibe.ai', []],// OpenVibe.Bench (contracts 0.238.0): the shared benchmark engine calls AI's generate route (namespace ai.generate)// to run its pinned rounds, and subscribes to the account events at boot; its export/deletion pair is with the// other services' above. It publishes bench.* events and answers no other service today, so no Search grant.nnew file mode 100644@@@ -0,0 +1,25 @@++/**++ * OpenVibe.Design's Exchange icon-search grant (contracts 0.407.0): Design asks OpenVibe.AI's Exchange platform API++ * for the icon references beside a glyph draft, with its own client-credentials token (audience openvibe.ai), and++ * reaches only POST /v1/search/icons. No Exchange key is needed anywhere.++ *++ * node test/design-exchange-search-grant.test.js++ */++'use strict';++const assert = require('assert');++const contracts = require('openvibe-contracts');++const principals = require('../server/identity/principals');++++const CAP = 'exchange.search.icons';++const AUDIENCE = 'openvibe.ai';++const grant = principals.DEFAULT_GRANTS.find(([client, cap, aud]) => client === 'design' && cap === CAP && aud === AUDIENCE);++assert.ok(grant, 'Design holds exchange.search.icons on openvibe.ai');++assert.deepStrictEqual(grant[3], [], 'the grant needs no namespace: the route names none');++assert.ok(!principals.DEFAULT_GRANTS.some(([client, cap]) => cap === CAP && client !== 'design'), 'Design alone holds it');++assert.ok(!principals.RESTORED_GRANTS.some(([client, cap]) => client === 'design' && cap === CAP), 'new grant: no RESTORED_GRANTS entry');++const cap = contracts.capabilities.get(CAP);++assert.ok(cap && cap.status === 'active', 'exchange.search.icons is active in the pinned contracts');++assert.strictEqual(cap.owner, 'ai', 'OpenVibe.AI serves the Exchange platform API');++assert.strictEqual(cap.visibility, 'first-party');++assert.deepStrictEqual(cap.implementedBy, ['POST /v1/search/icons'], 'it opens the icons route only');++console.log('design exchange search grant: ok');
@@ -22,7 +22,7 @@
@@ -22,7 +22,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.406.0",
+ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.407.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.147.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.147.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.206.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.206.0",
"otpauth": "9.6.0",
"otpauth": "9.6.0",
@@ -2679,9 +2679,9 @@
@@ -2679,9 +2679,9 @@
}
}
},
},
"node_modules/openvibe-contracts": {
"node_modules/openvibe-contracts": {
- "version": "0.406.0",
- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.406.0",
- "integrity": "sha512-V/Tjss2UWvzI551bw3ACb/RqWg0lChxGITxfCVZ8qou2Docg0pBMvIjkeQoib56yq3r6UZGB6DGl+pA+qfjOiA==",
+ "version": "0.407.0",
+ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.407.0",
+ "integrity": "sha512-i+brTUApefkumQu1Ra4GFkZqwd2+mWBIEW8Ra55Eid5Bn6Q29cVNMl57EKI9uzlOauzc6s6ut5r55NWepRoMSQ==",
"license": "AGPL-3.0-only",
"license": "AGPL-3.0-only",
"dependencies": {
"dependencies": {
"ajv": "^8.17.1",
"ajv": "^8.17.1",
@@ -26,7 +26,7 @@
@@ -26,7 +26,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.406.0",
+ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.407.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.147.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.147.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.206.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.206.0",
"otpauth": "9.6.0",
"otpauth": "9.6.0",
@@ -839,6 +839,11 @@ const DEFAULT_GRANTS = [
@@ -839,6 +839,11 @@ const DEFAULT_GRANTS = [
// what passes `prefer` to the router). Without ai.chat every unpinned frame was refused ("this token may not run
// what passes `prefer` to the router). Without ai.chat every unpinned frame was refused ("this token may not run
// ai.chat") from 10-31 to 11-02.
// ai.chat") from 10-31 to 11-02.
['design', 'ai.run.create', 'openvibe.ai', ['ai.generate', 'ai.chat']],
['design', 'ai.run.create', 'openvibe.ai', ['ai.generate', 'ai.chat']],
+ // The Exchange platform API's icon reference search (contracts 0.407.0, exchange.search.icons): Design asks
+ // OpenVibe.AI for the references beside a glyph draft with its own service token, so no Exchange key is needed,
+ // and reaches only POST /v1/search/icons. This grant was never granted or revoked before, so it needs no
+ // RESTORED_GRANTS entry; the seed inserts it at boot.
+ ['design', 'exchange.search.icons', 'openvibe.ai', []],
// OpenVibe.Bench (contracts 0.238.0): the shared benchmark engine calls AI's generate route (namespace ai.generate)
// OpenVibe.Bench (contracts 0.238.0): the shared benchmark engine calls AI's generate route (namespace ai.generate)
// to run its pinned rounds, and subscribes to the account events at boot; its export/deletion pair is with the
// to run its pinned rounds, and subscribes to the account events at boot; its export/deletion pair is with the
// other services' above. It publishes bench.* events and answers no other service today, so no Search grant.
// other services' above. It publishes bench.* events and answers no other service today, so no Search grant.
new file mode 100644
new file mode 100644
@@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
+/**
+ * OpenVibe.Design's Exchange icon-search grant (contracts 0.407.0): Design asks OpenVibe.AI's Exchange platform API
+ * for the icon references beside a glyph draft, with its own client-credentials token (audience openvibe.ai), and
+ * reaches only POST /v1/search/icons. No Exchange key is needed anywhere.
+ *
+ * node test/design-exchange-search-grant.test.js
+ */
+'use strict';
+const assert = require('assert');
+const contracts = require('openvibe-contracts');
+const principals = require('../server/identity/principals');
+
+const CAP = 'exchange.search.icons';
+const AUDIENCE = 'openvibe.ai';
+const grant = principals.DEFAULT_GRANTS.find(([client, cap, aud]) => client === 'design' && cap === CAP && aud === AUDIENCE);
+assert.ok(grant, 'Design holds exchange.search.icons on openvibe.ai');
+assert.deepStrictEqual(grant[3], [], 'the grant needs no namespace: the route names none');
+assert.ok(!principals.DEFAULT_GRANTS.some(([client, cap]) => cap === CAP && client !== 'design'), 'Design alone holds it');
+assert.ok(!principals.RESTORED_GRANTS.some(([client, cap]) => client === 'design' && cap === CAP), 'new grant: no RESTORED_GRANTS entry');
+const cap = contracts.capabilities.get(CAP);
+assert.ok(cap && cap.status === 'active', 'exchange.search.icons is active in the pinned contracts');
+assert.strictEqual(cap.owner, 'ai', 'OpenVibe.AI serves the Exchange platform API');
+assert.strictEqual(cap.visibility, 'first-party');
+assert.deepStrictEqual(cap.implementedBy, ['POST /v1/search/icons'], 'it opens the icons route only');
+console.log('design exchange search grant: ok');