Files
BetterDesk/web-nodejs/tests/dbAdapter.tokenHashMigration.test.js
T
UNITRONIX 1b240543bd feat(auth): implement SQLite auth consolidation and admin password validation
- Added functionality for safely consolidating legacy auth.db into the selected SQLite database, with options for dry runs and rollbacks.
- Introduced command-line flags for SQLite auth consolidation, including backup directory and rollback options.
- Enhanced admin interface security by requiring a password when the admin port is enabled, preventing unauthorized access.
- Updated related tests to ensure proper handling of admin password requirements and relay authorization logic.
2026-08-05 23:49:42 +02:00

85 lines
2.9 KiB
JavaScript

'use strict';
/**
* Legacy auth.db without access_tokens.token_hash must migrate on init (issue #158).
*/
const fs = require('fs');
const os = require('os');
const path = require('path');
const Database = require('better-sqlite3');
describe('dbAdapter token_hash SQLite migration', () => {
let tmpDir;
let dataDir;
let authPath;
beforeEach(() => {
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'bd-token-hash-'));
dataDir = path.join(tmpDir, 'data');
fs.mkdirSync(dataDir);
authPath = path.join(dataDir, 'auth.db');
const db = new Database(authPath);
db.exec(`
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
role TEXT DEFAULT 'admin',
created_at TEXT DEFAULT (datetime('now'))
);
CREATE TABLE access_tokens (
id INTEGER PRIMARY KEY AUTOINCREMENT,
token TEXT UNIQUE NOT NULL,
user_id INTEGER NOT NULL,
client_id TEXT DEFAULT '',
client_uuid TEXT DEFAULT '',
created_at TEXT DEFAULT (datetime('now')),
expires_at TEXT NOT NULL,
last_used TEXT,
ip_address TEXT DEFAULT '',
revoked INTEGER DEFAULT 0
);
INSERT INTO users (username, password_hash) VALUES ('admin', 'hash');
INSERT INTO access_tokens (token, user_id, expires_at)
VALUES ('legacytoken123456789012345678901234567890', 1, datetime('now', '+1 day'));
`);
db.close();
process.env.DATA_DIR = dataDir;
process.env.DB_TYPE = 'sqlite';
process.env.DB_PATH = path.join(dataDir, 'db_v2.sqlite3');
jest.resetModules();
});
afterEach(() => {
delete process.env.DATA_DIR;
delete process.env.DB_TYPE;
delete process.env.DB_PATH;
if (tmpDir && fs.existsSync(tmpDir)) {
fs.rmSync(tmpDir, { recursive: true, force: true });
}
});
test('adds token_hash column and backfills legacy tokens', async () => {
const { getAdapter } = require('../services/dbAdapter');
const adapter = getAdapter();
await adapter.init();
const auth = new Database(authPath);
const cols = auth.prepare('PRAGMA table_info(access_tokens)').all().map((c) => c.name);
const row = auth.prepare('SELECT token_hash FROM access_tokens WHERE id = 1').get();
const indexes = auth.prepare(`
SELECT name FROM sqlite_master
WHERE type = 'index' AND tbl_name = 'access_tokens' AND name = 'idx_access_tokens_hash'
`).all();
auth.close();
expect(cols).toContain('token_hash');
expect(row.token_hash).toHaveLength(64);
expect(indexes).toHaveLength(1);
await adapter.close();
});
});