openvibers/openvibe.tools Commits
Sign-out everywhere cutoffs live in apps/gateway/data (the gateway unit's ReadWritePaths; /opt/openvibe.tools/data was unwritable and every delivery answered 500), in a rollback journal so the read-only apps under ProtectSystem=strict can open it
Changes
@@@ -8,7 +8,8 @@const fs = require('fs');const path = require('path');--const DEFAULT_FILE = path.resolve(__dirname, '..', '..', '..', 'data', 'token-revocations.db');++// In the gateway's data directory: the one place its unit may write (ReadWritePaths); the other apps only read it.++const DEFAULT_FILE = path.resolve(__dirname, '..', '..', 'gateway', 'data', 'token-revocations.db');function revocationsFile(env = process.env) { return env.TOOLS_REVOCATIONS_DB || DEFAULT_FILE; }@@@ -20,7 +20,9 @@ function cutoffs() {const file = revocationsFile();fs.mkdirSync(path.dirname(file), { recursive: true });const db = new Database(file);-- db.pragma('journal_mode = WAL');++ // A rollback journal, not WAL: the other apps open the file read-only under ProtectSystem=strict and could not++ // create a WAL's -shm file. Writes are one row per sign-out-everywhere.++ db.pragma('journal_mode = DELETE');db.pragma('busy_timeout = 2000');store = require('openvibe-sdk/auth').createRevocationStore(db, { table: 'token_revocations' });return store;@@@ -15,7 +15,10 @@ const express = require('express');const Database = require('better-sqlite3');const { signDeliveryHeaders } = require('openvibe-sdk/events');const events = require('../server/revocation-events');--const { createCutoffReader } = require('../../_shared/guard/revocations');++const { createCutoffReader, DEFAULT_FILE } = require('../../_shared/guard/revocations');++++// The default lives where the gateway's unit may write (ReadWritePaths=apps/gateway/data).++assert.strictEqual(DEFAULT_FILE, path.resolve(__dirname, '..', 'data', 'token-revocations.db'));const SUBJECT = 'usr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A3';const at = Date.parse('2026-09-25T12:00:00Z');
@@ -8,7 +8,8 @@
@@ -8,7 +8,8 @@
const fs = require('fs');
const fs = require('fs');
const path = require('path');
const path = require('path');
-const DEFAULT_FILE = path.resolve(__dirname, '..', '..', '..', 'data', 'token-revocations.db');
+// In the gateway's data directory: the one place its unit may write (ReadWritePaths); the other apps only read it.
+const DEFAULT_FILE = path.resolve(__dirname, '..', '..', 'gateway', 'data', 'token-revocations.db');
function revocationsFile(env = process.env) { return env.TOOLS_REVOCATIONS_DB || DEFAULT_FILE; }
function revocationsFile(env = process.env) { return env.TOOLS_REVOCATIONS_DB || DEFAULT_FILE; }
@@ -20,7 +20,9 @@ function cutoffs() {
@@ -20,7 +20,9 @@ function cutoffs() {
const file = revocationsFile();
const file = revocationsFile();
fs.mkdirSync(path.dirname(file), { recursive: true });
fs.mkdirSync(path.dirname(file), { recursive: true });
const db = new Database(file);
const db = new Database(file);
- db.pragma('journal_mode = WAL');
+ // A rollback journal, not WAL: the other apps open the file read-only under ProtectSystem=strict and could not
+ // create a WAL's -shm file. Writes are one row per sign-out-everywhere.
+ db.pragma('journal_mode = DELETE');
db.pragma('busy_timeout = 2000');
db.pragma('busy_timeout = 2000');
store = require('openvibe-sdk/auth').createRevocationStore(db, { table: 'token_revocations' });
store = require('openvibe-sdk/auth').createRevocationStore(db, { table: 'token_revocations' });
return store;
return store;
@@ -15,7 +15,10 @@ const express = require('express');
@@ -15,7 +15,10 @@ const express = require('express');
const Database = require('better-sqlite3');
const Database = require('better-sqlite3');
const { signDeliveryHeaders } = require('openvibe-sdk/events');
const { signDeliveryHeaders } = require('openvibe-sdk/events');
const events = require('../server/revocation-events');
const events = require('../server/revocation-events');
-const { createCutoffReader } = require('../../_shared/guard/revocations');
+const { createCutoffReader, DEFAULT_FILE } = require('../../_shared/guard/revocations');
+
+// The default lives where the gateway's unit may write (ReadWritePaths=apps/gateway/data).
+assert.strictEqual(DEFAULT_FILE, path.resolve(__dirname, '..', 'data', 'token-revocations.db'));
const SUBJECT = 'usr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A3';
const SUBJECT = 'usr_01J8Z3Q4R5S6T7V8W9X0Y1Z2A3';
const at = Date.parse('2026-09-25T12:00:00Z');
const at = Date.parse('2026-09-25T12:00:00Z');