openvibers/openvibe.network Commits
Agent Streams S5: the digest and poll grants for Codes and Actor (#605)
Changes
@@@ -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.301.0",++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.303.0","openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.91.0","openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.122.0","pg": "^8.23.0",@@@ -2303,9 +2303,9 @@}},"node_modules/openvibe-contracts": {-- "version": "0.301.0",-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.301.0",-- "integrity": "sha512-f/T1fk9WfVte/kPR0Hqe2k5TJ1Bd3CC2UHA1USzssj4pGfPMMY3fCs6cr02TKolmwiDJKL94oGkCk4nfkL+FGg==",++ "version": "0.303.0",++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.303.0",++ "integrity": "sha512-8LKa7nslS2LWyOSjASTteJdzYoK++ipX4yygMnVkF+lZ/Ev3Fxvhcjv6g39hQSv/c07nSnqYBZ74X90nzH3oJA==","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.301.0",++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.303.0","openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.91.0","openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.122.0","pg": "^8.23.0",@@@ -815,6 +815,15 @@ const DEFAULT_GRANTS = [// else, so the grant is unscoped and the audience is Live's alone.['codes', 'live.agent_stream.publish', 'openvibe.live', []],['actor', 'live.agent_stream.publish', 'openvibe.live', []],++ // The Agent Streams plan (S5, Contracts 0.303.0): Codes and Actor read the digest of the owner's Co-pilot++ // room on OpenVibe.Chat (chat.agent_digest.read) and run a poll in it (chat.agent_poll.write), the audience++ // openvibe.chat. They act for the person and for nobody else, so the grant is unscoped and the audience is++ // Chat's alone. A node token names its owner in on_behalf_of, so a digest is the owner's room and never++ // another person's: the grant gives the task's service the way in, not the room.++ ['codes', 'chat.agent_digest.read', 'openvibe.chat', []],++ ['actor', 'chat.agent_digest.read', 'openvibe.chat', []],++ ['codes', 'chat.agent_poll.write', 'openvibe.chat', []],++ ['actor', 'chat.agent_poll.write', 'openvibe.chat', []],// The Agent Streams plan (S3, Contracts 0.300.0): Codes, Actor and Live write the report of an agent session on// OpenVibe.Report (report.session.write, the audience openvibe.report). They act for the person and for nobody// else, so the grant is unscoped and the audience is Report's alone. A desk session on a person's own machine@@@ -99,7 +99,7 @@ const valid = (e) => { const v = contracts.validate('events.event-envelope@1', eassert.deepStrictEqual(ev[0].actor, { type: 'service', id: 'chat' });assert.strictEqual(ev[0].visibility, 'internal'); assert.strictEqual(ev[0].source, 'network');assert.deepStrictEqual(ev[0].subject, { type: 'user_module', id: `${ANN}:chat.preferences`, revision: 1 });-- assert.deepStrictEqual(ev[0].payload, { owner: { type: 'user', id: ANN }, namespace: 'chat.preferences', namespace_owner: 'chat', schema_version: 1, revision: 1, change: 'created', reason: 'write', keys: ['compact', 'timestamps'] });++ assert.deepStrictEqual(ev[0].payload, { owner: { type: 'user', id: ANN }, namespace: 'chat.preferences', namespace_owner: 'chat', schema_version: 2, revision: 1, change: 'created', reason: 'write', keys: ['compact', 'timestamps'] });mark = await lastId();r = await call('PUT', '/api/modules/chat.preferences', { headers: { ...await tokenOf(1), 'if-match': '1' }, body: { data: { timestamps: true, font_scale: 1.2 } } });assert.strictEqual(r.status, 200); assert.strictEqual(r.body.revision, 2);
@@ -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.301.0",
+ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.303.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.91.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.91.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.122.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.122.0",
"pg": "^8.23.0",
"pg": "^8.23.0",
@@ -2303,9 +2303,9 @@
@@ -2303,9 +2303,9 @@
}
}
},
},
"node_modules/openvibe-contracts": {
"node_modules/openvibe-contracts": {
- "version": "0.301.0",
- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.301.0",
- "integrity": "sha512-f/T1fk9WfVte/kPR0Hqe2k5TJ1Bd3CC2UHA1USzssj4pGfPMMY3fCs6cr02TKolmwiDJKL94oGkCk4nfkL+FGg==",
+ "version": "0.303.0",
+ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.303.0",
+ "integrity": "sha512-8LKa7nslS2LWyOSjASTteJdzYoK++ipX4yygMnVkF+lZ/Ev3Fxvhcjv6g39hQSv/c07nSnqYBZ74X90nzH3oJA==",
"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.301.0",
+ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.303.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.91.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.91.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.122.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.122.0",
"pg": "^8.23.0",
"pg": "^8.23.0",
@@ -815,6 +815,15 @@ const DEFAULT_GRANTS = [
@@ -815,6 +815,15 @@ const DEFAULT_GRANTS = [
// else, so the grant is unscoped and the audience is Live's alone.
// else, so the grant is unscoped and the audience is Live's alone.
['codes', 'live.agent_stream.publish', 'openvibe.live', []],
['codes', 'live.agent_stream.publish', 'openvibe.live', []],
['actor', 'live.agent_stream.publish', 'openvibe.live', []],
['actor', 'live.agent_stream.publish', 'openvibe.live', []],
+ // The Agent Streams plan (S5, Contracts 0.303.0): Codes and Actor read the digest of the owner's Co-pilot
+ // room on OpenVibe.Chat (chat.agent_digest.read) and run a poll in it (chat.agent_poll.write), the audience
+ // openvibe.chat. They act for the person and for nobody else, so the grant is unscoped and the audience is
+ // Chat's alone. A node token names its owner in on_behalf_of, so a digest is the owner's room and never
+ // another person's: the grant gives the task's service the way in, not the room.
+ ['codes', 'chat.agent_digest.read', 'openvibe.chat', []],
+ ['actor', 'chat.agent_digest.read', 'openvibe.chat', []],
+ ['codes', 'chat.agent_poll.write', 'openvibe.chat', []],
+ ['actor', 'chat.agent_poll.write', 'openvibe.chat', []],
// The Agent Streams plan (S3, Contracts 0.300.0): Codes, Actor and Live write the report of an agent session on
// The Agent Streams plan (S3, Contracts 0.300.0): Codes, Actor and Live write the report of an agent session on
// OpenVibe.Report (report.session.write, the audience openvibe.report). They act for the person and for nobody
// OpenVibe.Report (report.session.write, the audience openvibe.report). They act for the person and for nobody
// else, so the grant is unscoped and the audience is Report's alone. A desk session on a person's own machine
// else, so the grant is unscoped and the audience is Report's alone. A desk session on a person's own machine
@@ -99,7 +99,7 @@ const valid = (e) => { const v = contracts.validate('events.event-envelope@1', e
@@ -99,7 +99,7 @@ const valid = (e) => { const v = contracts.validate('events.event-envelope@1', e
assert.deepStrictEqual(ev[0].actor, { type: 'service', id: 'chat' });
assert.deepStrictEqual(ev[0].actor, { type: 'service', id: 'chat' });
assert.strictEqual(ev[0].visibility, 'internal'); assert.strictEqual(ev[0].source, 'network');
assert.strictEqual(ev[0].visibility, 'internal'); assert.strictEqual(ev[0].source, 'network');
assert.deepStrictEqual(ev[0].subject, { type: 'user_module', id: `${ANN}:chat.preferences`, revision: 1 });
assert.deepStrictEqual(ev[0].subject, { type: 'user_module', id: `${ANN}:chat.preferences`, revision: 1 });
- assert.deepStrictEqual(ev[0].payload, { owner: { type: 'user', id: ANN }, namespace: 'chat.preferences', namespace_owner: 'chat', schema_version: 1, revision: 1, change: 'created', reason: 'write', keys: ['compact', 'timestamps'] });
+ assert.deepStrictEqual(ev[0].payload, { owner: { type: 'user', id: ANN }, namespace: 'chat.preferences', namespace_owner: 'chat', schema_version: 2, revision: 1, change: 'created', reason: 'write', keys: ['compact', 'timestamps'] });
mark = await lastId();
mark = await lastId();
r = await call('PUT', '/api/modules/chat.preferences', { headers: { ...await tokenOf(1), 'if-match': '1' }, body: { data: { timestamps: true, font_scale: 1.2 } } });
r = await call('PUT', '/api/modules/chat.preferences', { headers: { ...await tokenOf(1), 'if-match': '1' }, body: { data: { timestamps: true, font_scale: 1.2 } } });
assert.strictEqual(r.status, 200); assert.strictEqual(r.body.revision, 2);
assert.strictEqual(r.status, 200); assert.strictEqual(r.body.revision, 2);