openvibers/openvibe.services Commits
Services: Space sites, deploys and domains can be deleted from the console (contracts 0.170) (#59)
Changes
@@@ -16,7 +16,7 @@"express-rate-limit": "^7.5.0","helmet": "^8.1.0","iovalkey": "^0.4.0",-- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.169.0",++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.170.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.1.3","pg": "^8.23.0"@@@ -890,9 +890,9 @@}},"node_modules/openvibe-contracts": {-- "version": "0.169.0",-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.169.0",-- "integrity": "sha512-Py2z8UaKGvLzG3atuIAnJKnRe74Te9cJRTaxqFq6m4fov6gaMXeS6rn7lH0tSIo0qBGD5trrT618ARXnklkp+A==",++ "version": "0.170.0",++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.170.0",++ "integrity": "sha512-EpOUiqFSYBZ1p7aQTek1IYyHcbD9QT0pdr492+teWvZf425xXSMu7+DQsnzgMP8JdTmdS2VMxoirrBwMUGxjrw==","license": "AGPL-3.0-only","dependencies": {"ajv": "^8.17.1",@@@ -27,7 +27,7 @@"express-rate-limit": "^7.5.0","helmet": "^8.1.0","iovalkey": "^0.4.0",-- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.169.0",++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.170.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.1.3","pg": "^8.23.0"@@@ -40,13 +40,17 @@ const { ServiceError } = require('../util');// What the console offers on a resource (ADR-048 control), by kind. The owning service decides; a button it does not// take would only be refused. `admins`: the service lets a project's admins act on what its apps made, not only the--// resource's own person (Actor and Media, contracts 0.169.0).++// resource's own person (Actor and Media, contracts 0.169.0; Space, 0.170.0).const OPEN_TASK = new Set(['queued', 'running', 'verifying']);const KIND_ACTIONS = {'watch.watch': { actions: (x) => [x.state === 'paused' ? ['resume', 'Resume'] : ['suspend', 'Suspend'], ['delete', 'Delete…']] },'events.subscription': { actions: (x) => [x.state === 'disabled' ? ['resume', 'Resume'] : ['suspend', 'Suspend']] },'actor.task': { admins: true, actions: (x) => (OPEN_TASK.has(x.state) ? [['stop', 'Stop']] : []) },'media.object': { admins: true, actions: (x) => (x.state === 'deleted' ? [] : [['delete', 'Delete…']]) },++ // Space decides by its own project roles (maintainer or owner), so any admin here may ask (contracts 0.170.0).++ 'space.site': { admins: true, actions: (x) => (x.state === 'deleted' ? [] : [['delete', 'Delete…']]) },++ 'space.deploy': { admins: true, actions: (x) => (x.state === 'deleted' ? [] : [['delete', 'Delete…']]) },++ 'space.domain': { admins: true, actions: () => [['delete', 'Delete…']] },default: { actions: (x) => [x.state === 'paused' ? ['resume', 'Resume'] : ['suspend', 'Suspend'], ['delete', 'Delete…']] },};@@@ -88,10 +88,10 @@ function registryOf(list) {const prj = ids.newId('project');const object = resources.format({ service: 'media', project_id: prj, type: 'object', id: ids.newId('media') });-- await check('only an authority with an active <id>.resource.control takes control requests (Watch 0.165, Events 0.168, Actor and Media 0.169)', async () => {++ await check('only an authority with an active <id>.resource.control takes control requests (Watch 0.165, Events 0.168, Actor and Media 0.169, Space 0.170)', async () => {const real = createAuthorities(t.config, { log: { warn() {} } });assert.ok(real.size() > 0);-- const TAKES = { watch: 'watch.resource.control', events: 'events.resource.control', actor: 'actor.resource.control', media: 'media.resource.control' };++ const TAKES = { watch: 'watch.resource.control', events: 'events.resource.control', actor: 'actor.resource.control', media: 'media.resource.control', space: 'space.resource.control' };for (const a of real.list()) assert.strictEqual(a.control, TAKES[a.id] || null, `${a.id}: the control capability in the pinned contracts`);});
@@ -16,7 +16,7 @@
@@ -16,7 +16,7 @@
"express-rate-limit": "^7.5.0",
"express-rate-limit": "^7.5.0",
"helmet": "^8.1.0",
"helmet": "^8.1.0",
"iovalkey": "^0.4.0",
"iovalkey": "^0.4.0",
- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.169.0",
+ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.170.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.1.3",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.1.3",
"pg": "^8.23.0"
"pg": "^8.23.0"
@@ -890,9 +890,9 @@
@@ -890,9 +890,9 @@
}
}
},
},
"node_modules/openvibe-contracts": {
"node_modules/openvibe-contracts": {
- "version": "0.169.0",
- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.169.0",
- "integrity": "sha512-Py2z8UaKGvLzG3atuIAnJKnRe74Te9cJRTaxqFq6m4fov6gaMXeS6rn7lH0tSIo0qBGD5trrT618ARXnklkp+A==",
+ "version": "0.170.0",
+ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.170.0",
+ "integrity": "sha512-EpOUiqFSYBZ1p7aQTek1IYyHcbD9QT0pdr492+teWvZf425xXSMu7+DQsnzgMP8JdTmdS2VMxoirrBwMUGxjrw==",
"license": "AGPL-3.0-only",
"license": "AGPL-3.0-only",
"dependencies": {
"dependencies": {
"ajv": "^8.17.1",
"ajv": "^8.17.1",
@@ -27,7 +27,7 @@
@@ -27,7 +27,7 @@
"express-rate-limit": "^7.5.0",
"express-rate-limit": "^7.5.0",
"helmet": "^8.1.0",
"helmet": "^8.1.0",
"iovalkey": "^0.4.0",
"iovalkey": "^0.4.0",
- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.169.0",
+ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.170.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.1.3",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.1.3",
"pg": "^8.23.0"
"pg": "^8.23.0"
@@ -40,13 +40,17 @@ const { ServiceError } = require('../util');
@@ -40,13 +40,17 @@ const { ServiceError } = require('../util');
// What the console offers on a resource (ADR-048 control), by kind. The owning service decides; a button it does not
// What the console offers on a resource (ADR-048 control), by kind. The owning service decides; a button it does not
// take would only be refused. `admins`: the service lets a project's admins act on what its apps made, not only the
// take would only be refused. `admins`: the service lets a project's admins act on what its apps made, not only the
-// resource's own person (Actor and Media, contracts 0.169.0).
+// resource's own person (Actor and Media, contracts 0.169.0; Space, 0.170.0).
const OPEN_TASK = new Set(['queued', 'running', 'verifying']);
const OPEN_TASK = new Set(['queued', 'running', 'verifying']);
const KIND_ACTIONS = {
const KIND_ACTIONS = {
'watch.watch': { actions: (x) => [x.state === 'paused' ? ['resume', 'Resume'] : ['suspend', 'Suspend'], ['delete', 'Delete…']] },
'watch.watch': { actions: (x) => [x.state === 'paused' ? ['resume', 'Resume'] : ['suspend', 'Suspend'], ['delete', 'Delete…']] },
'events.subscription': { actions: (x) => [x.state === 'disabled' ? ['resume', 'Resume'] : ['suspend', 'Suspend']] },
'events.subscription': { actions: (x) => [x.state === 'disabled' ? ['resume', 'Resume'] : ['suspend', 'Suspend']] },
'actor.task': { admins: true, actions: (x) => (OPEN_TASK.has(x.state) ? [['stop', 'Stop']] : []) },
'actor.task': { admins: true, actions: (x) => (OPEN_TASK.has(x.state) ? [['stop', 'Stop']] : []) },
'media.object': { admins: true, actions: (x) => (x.state === 'deleted' ? [] : [['delete', 'Delete…']]) },
'media.object': { admins: true, actions: (x) => (x.state === 'deleted' ? [] : [['delete', 'Delete…']]) },
+ // Space decides by its own project roles (maintainer or owner), so any admin here may ask (contracts 0.170.0).
+ 'space.site': { admins: true, actions: (x) => (x.state === 'deleted' ? [] : [['delete', 'Delete…']]) },
+ 'space.deploy': { admins: true, actions: (x) => (x.state === 'deleted' ? [] : [['delete', 'Delete…']]) },
+ 'space.domain': { admins: true, actions: () => [['delete', 'Delete…']] },
default: { actions: (x) => [x.state === 'paused' ? ['resume', 'Resume'] : ['suspend', 'Suspend'], ['delete', 'Delete…']] },
default: { actions: (x) => [x.state === 'paused' ? ['resume', 'Resume'] : ['suspend', 'Suspend'], ['delete', 'Delete…']] },
};
};
@@ -88,10 +88,10 @@ function registryOf(list) {
@@ -88,10 +88,10 @@ function registryOf(list) {
const prj = ids.newId('project');
const prj = ids.newId('project');
const object = resources.format({ service: 'media', project_id: prj, type: 'object', id: ids.newId('media') });
const object = resources.format({ service: 'media', project_id: prj, type: 'object', id: ids.newId('media') });
- await check('only an authority with an active <id>.resource.control takes control requests (Watch 0.165, Events 0.168, Actor and Media 0.169)', async () => {
+ await check('only an authority with an active <id>.resource.control takes control requests (Watch 0.165, Events 0.168, Actor and Media 0.169, Space 0.170)', async () => {
const real = createAuthorities(t.config, { log: { warn() {} } });
const real = createAuthorities(t.config, { log: { warn() {} } });
assert.ok(real.size() > 0);
assert.ok(real.size() > 0);
- const TAKES = { watch: 'watch.resource.control', events: 'events.resource.control', actor: 'actor.resource.control', media: 'media.resource.control' };
+ const TAKES = { watch: 'watch.resource.control', events: 'events.resource.control', actor: 'actor.resource.control', media: 'media.resource.control', space: 'space.resource.control' };
for (const a of real.list()) assert.strictEqual(a.control, TAKES[a.id] || null, `${a.id}: the control capability in the pinned contracts`);
for (const a of real.list()) assert.strictEqual(a.control, TAKES[a.id] || null, `${a.id}: the control capability in the pinned contracts`);
});
});