openvibers/openvibe.design Commits

account-data: pin openvibe-sdk 0.74.0 and guard every table with a person column (#30)

OP OpenVibers committed 14 days ago · 96b95df294 · 6 files, +35 −8

* account-data: pin openvibe-sdk 0.74.0 and guard every table with a person column

* account-data: cover the tables the guard found with a person column

Changes

ddiff --git a/README.md b/README.md
iindex 2ce742c..ae4a15f 100644
---- a/README.md
++++ b/README.md
@@@ -208,6 +208,6 @@ Part of the [OpenVibe network](https://openvibe.network). Built in the open by
<!-- versions:start -->
- openvibe-contracts: v0.236.0
--- openvibe-sdk: v0.73.0
++- openvibe-sdk: v0.74.0
- openvibe-shared: v4.48.0
<!-- versions:end -->
ddiff --git a/STATUS.json b/STATUS.json
iindex 514ee06..37779b4 100644
---- a/STATUS.json
++++ b/STATUS.json
@@@ -9,11 +9,11 @@
"port": "5090",
"domain": "openvibe.design",
"contracts": "openvibe-contracts v0.236.0",
-- "sdk": "openvibe-sdk v0.73.0",
++ "sdk": "openvibe-sdk v0.74.0",
"shared": "openvibe-shared v4.48.0",
"packages": [
"openvibe-contracts v0.236.0",
-- "openvibe-sdk v0.73.0",
++ "openvibe-sdk v0.74.0",
"openvibe-shared v4.48.0"
],
"summary": "The service skeleton for openvibe.design: Network sign-in as OAuth client `design` (PKCE S256, httpOnly design_at/design_rt cookies) and a theme API proxy to OpenVibe.Network's /api/themes. The proxy serves the public catalogue (cached 5 minutes), one theme, the person's active theme and custom variables, saving a theme with source 'studio', its history and a restore by id, and a submission to the gallery. Writes need this site's own Origin; Network 4xx answers pass through and a Network failure is 502. The studio is designed: a gallery, previews on a Live channel, a Chat room and a shop's grid (with colour-vision views), a six-colour editor that derives the full token set, WCAG checks that gate Use, sharing to the gallery, and History with Restore. The Arena queues one prompt for three models through OpenVibe.AI (client credentials, ai.run.create), stores sanitized HTML with reported model/provider/cost/time/tokens, renders it only in sandboxed CSP-capped iframes, draws blind pairs, records one vote per person per round, and keeps Elo ratings per category plus median cost and time. The prompts, outputs and votes are an open JSONL dataset; rounds and votes follow ADR-033 export and deletion.",
ddiff --git a/package-lock.json b/package-lock.json
iindex 448a4ba..45a8cd8 100644
---- a/package-lock.json
++++ b/package-lock.json
@@@ -15,7 +15,7 @@
"express-rate-limit": "^7.5.0",
"helmet": "^8.1.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.236.0",
-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.73.0",
++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.74.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.48.0",
"pg": "^8.23.1"
},
@@@ -1086,9 +1086,9 @@
}
},
"node_modules/openvibe-sdk": {
-- "version": "0.73.0",
-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.73.0",
-- "integrity": "sha512-XClxoVm9M6RA8eXlGgYZ0u6q9n5h79mCXqAAEg9fX21KgcqP69RmG+cX+6wrOf7TaEj7eSBWMxHjiIeIa9N7Dg==",
++ "version": "0.74.0",
++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.74.0",
++ "integrity": "sha512-DO9KVPnUriY/I4lX6ZEJtXaUvRDbJyqnqJxvlpl+zkNGFILpmuBXVJogNOCfK071Qci1gg7C4Iw1Xrseklcajg==",
"license": "MIT",
"bin": {
"openvibe-download": "bin/openvibe-download.js"
ddiff --git a/package.json b/package.json
iindex 883b033..83b05cc 100644
---- a/package.json
++++ b/package.json
@@@ -21,7 +21,7 @@
"express-rate-limit": "^7.5.0",
"helmet": "^8.1.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.236.0",
-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.73.0",
++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.74.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.48.0",
"pg": "^8.23.1"
},
ddiff --git a/server/identity/account-data.js b/server/identity/account-data.js
iindex 67c9f4e..10bf110 100644
---- a/server/identity/account-data.js
++++ b/server/identity/account-data.js
@@@ -13,6 +13,8 @@ const { createAccountData, TOPICS } = require('openvibe-sdk/account-data');
const TABLES = [
{ table: 'arena_rounds', subject: 'created_by', file: 'arena_rounds.json', erase: 'delete' },
{ table: 'arena_votes', subject: 'voter_subject', file: 'arena_votes.json', erase: 'delete' },
++ // The designs a signed-in person asked for; a guest's design has no owner and matches nobody. Versions cascade.
++ { table: 'designs', subject: 'owner', file: 'designs.json', order: 'created_at', columns: ['id', 'kind', 'prompt', 'theme_id', 'variants', 'created_at', 'updated_at'] },
];
async function extraExport(db, subject) {
ddiff --git a/test/account-data.test.js b/test/account-data.test.js
nnew file mode 100644
iindex 0000000..16be21a
---- /dev/null
++++ b/test/account-data.test.js
@@@ -0,0 +1,25 @@
++'use strict';
++/**
++ * ADR-033: every table in this service with a person column is either in the account-data map, keyed under the
++ * row that owns it, or exempted with a reason. A new table with one fails here until it is answered for.
++ */
++const assert = require('assert');
++const { uncovered } = require('openvibe-sdk/account-data');
++const { TABLES } = require('../server/identity/account-data');
++const { testDb } = require('./helpers/db');
++
++(async () => {
++ const d = await testDb();
++ try {
++ const missing = await uncovered(d.db, {
++ tables: TABLES,
++ taskKeyed: ['design_versions'], // versions belong to the design and cascade with it
++ exempt: {
++ account_data_events: 'the ledger of requests itself: which export and deletion design applied',
++
++ },
++ });
++ assert.deepStrictEqual(missing, [], `a table with a person column is neither covered nor exempted: ${missing.join(', ')}`);
++ console.log(' ✓ every table that names a person is covered or exempted with a reason');
++ } finally { await d.close(); }
++})();