Skip to content

Commit

Permalink
Merge branch 'master' into isybank-itbbitmm
Browse files Browse the repository at this point in the history
  • Loading branch information
matt-fidd authored Dec 12, 2024
2 parents ba59678 + 645958b commit 4aa37a0
Show file tree
Hide file tree
Showing 37 changed files with 2,440 additions and 178 deletions.
92 changes: 91 additions & 1 deletion jest.global-setup.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,100 @@
import getAccountDb from './src/account-db.js';
import runMigrations from './src/migrations.js';

const GENERIC_ADMIN_ID = 'genericAdmin';
const GENERIC_USER_ID = 'genericUser';
const ADMIN_ROLE_ID = 'ADMIN';
const BASIC_ROLE_ID = 'BASIC';

const createUser = (userId, userName, role, owner = 0, enabled = 1) => {
const missingParams = [];
if (!userId) missingParams.push('userId');
if (!userName) missingParams.push('userName');
if (!role) missingParams.push('role');
if (missingParams.length > 0) {
throw new Error(`Missing required parameters: ${missingParams.join(', ')}`);
}

if (
typeof userId !== 'string' ||
typeof userName !== 'string' ||
typeof role !== 'string'
) {
throw new Error(
'Invalid parameter types. userId, userName, and role must be strings',
);
}

try {
getAccountDb().mutate(
'INSERT INTO users (id, user_name, display_name, enabled, owner, role) VALUES (?, ?, ?, ?, ?, ?)',
[userId, userName, userName, enabled, owner, role],
);
} catch (error) {
console.error(`Error creating user ${userName}:`, error);
throw error;
}
};

const setSessionUser = (userId, token = 'valid-token') => {
if (!userId) {
throw new Error('userId is required');
}

try {
const db = getAccountDb();
const session = db.first('SELECT token FROM sessions WHERE token = ?', [
token,
]);
if (!session) {
throw new Error(`Session not found for token: ${token}`);
}

db.mutate('UPDATE sessions SET user_id = ? WHERE token = ?', [
userId,
token,
]);
} catch (error) {
console.error(`Error updating session for user ${userId}:`, error);
throw error;
}
};

export default async function setup() {
const NEVER_EXPIRES = -1; // or consider using a far future timestamp

await runMigrations();

createUser(GENERIC_ADMIN_ID, 'admin', ADMIN_ROLE_ID, 1);

// Insert a fake "valid-token" fixture that can be reused
const db = getAccountDb();
await db.mutate('INSERT INTO sessions (token) VALUES (?)', ['valid-token']);
try {
await db.mutate('BEGIN TRANSACTION');

await db.mutate('DELETE FROM sessions');
await db.mutate(
'INSERT INTO sessions (token, expires_at, user_id) VALUES (?, ?, ?)',
['valid-token', NEVER_EXPIRES, 'genericAdmin'],
);
await db.mutate(
'INSERT INTO sessions (token, expires_at, user_id) VALUES (?, ?, ?)',
['valid-token-admin', NEVER_EXPIRES, 'genericAdmin'],
);

await db.mutate(
'INSERT INTO sessions (token, expires_at, user_id) VALUES (?, ?, ?)',
['valid-token-user', NEVER_EXPIRES, 'genericUser'],
);

await db.mutate('COMMIT');
} catch (error) {
await db.mutate('ROLLBACK');
throw new Error(`Failed to setup test sessions: ${error.message}`);
}

setSessionUser('genericAdmin');
setSessionUser('genericAdmin', 'valid-token-admin');

createUser(GENERIC_USER_ID, 'user', BASIC_ROLE_ID, 1);
}
41 changes: 41 additions & 0 deletions migrations/1718889148000-openid.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import getAccountDb from '../src/account-db.js';

export const up = async function () {
await getAccountDb().exec(
`
BEGIN TRANSACTION;
CREATE TABLE auth_new
(method TEXT PRIMARY KEY,
display_name TEXT,
extra_data TEXT, active INTEGER);
INSERT INTO auth_new (method, display_name, extra_data, active)
SELECT 'password', 'Password', password, 1 FROM auth;
DROP TABLE auth;
ALTER TABLE auth_new RENAME TO auth;
CREATE TABLE pending_openid_requests
(state TEXT PRIMARY KEY,
code_verifier TEXT,
return_url TEXT,
expiry_time INTEGER);
COMMIT;`,
);
};

export const down = async function () {
await getAccountDb().exec(
`
BEGIN TRANSACTION;
ALTER TABLE auth RENAME TO auth_temp;
CREATE TABLE auth
(password TEXT);
INSERT INTO auth (password)
SELECT extra_data FROM auth_temp WHERE method = 'password';
DROP TABLE auth_temp;
DROP TABLE pending_openid_requests;
COMMIT;
`,
);
};
115 changes: 115 additions & 0 deletions migrations/1719409568000-multiuser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import getAccountDb from '../src/account-db.js';
import * as uuid from 'uuid';

export const up = async function () {
const accountDb = getAccountDb();

accountDb.transaction(() => {
accountDb.exec(
`
CREATE TABLE users
(id TEXT PRIMARY KEY,
user_name TEXT,
display_name TEXT,
role TEXT,
enabled INTEGER NOT NULL DEFAULT 1,
owner INTEGER NOT NULL DEFAULT 0);
CREATE TABLE user_access
(user_id TEXT,
file_id TEXT,
PRIMARY KEY (user_id, file_id),
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (file_id) REFERENCES files(id)
);
ALTER TABLE files
ADD COLUMN owner TEXT;
ALTER TABLE sessions
ADD COLUMN expires_at INTEGER;
ALTER TABLE sessions
ADD COLUMN user_id TEXT;
ALTER TABLE sessions
ADD COLUMN auth_method TEXT;
`,
);

const userId = uuid.v4();
accountDb.mutate(
'INSERT INTO users (id, user_name, display_name, enabled, owner, role) VALUES (?, ?, ?, 1, 1, ?)',
[userId, '', '', 'ADMIN'],
);

accountDb.mutate(
'UPDATE sessions SET user_id = ?, expires_at = ?, auth_method = ? WHERE auth_method IS NULL',
[userId, -1, 'password'],
);
});
};

export const down = async function () {
await getAccountDb().exec(
`
BEGIN TRANSACTION;
DROP TABLE IF EXISTS user_access;
CREATE TABLE sessions_backup (
token TEXT PRIMARY KEY
);
INSERT INTO sessions_backup (token)
SELECT token FROM sessions;
DROP TABLE sessions;
ALTER TABLE sessions_backup RENAME TO sessions;
CREATE TABLE files_backup (
id TEXT PRIMARY KEY,
group_id TEXT,
sync_version SMALLINT,
encrypt_meta TEXT,
encrypt_keyid TEXT,
encrypt_salt TEXT,
encrypt_test TEXT,
deleted BOOLEAN DEFAULT FALSE,
name TEXT
);
INSERT INTO files_backup (
id,
group_id,
sync_version,
encrypt_meta,
encrypt_keyid,
encrypt_salt,
encrypt_test,
deleted,
name
)
SELECT
id,
group_id,
sync_version,
encrypt_meta,
encrypt_keyid,
encrypt_salt,
encrypt_test,
deleted,
name
FROM files;
DROP TABLE files;
ALTER TABLE files_backup RENAME TO files;
DROP TABLE IF EXISTS users;
COMMIT;
`,
);
};
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "actual-sync",
"version": "24.11.0",
"version": "24.12.0",
"license": "MIT",
"description": "actual syncing server",
"type": "module",
Expand All @@ -21,7 +21,7 @@
},
"dependencies": {
"@actual-app/crdt": "2.1.0",
"@actual-app/web": "24.11.0",
"@actual-app/web": "24.12.0",
"bcrypt": "^5.1.1",
"better-sqlite3": "^9.6.0",
"body-parser": "^1.20.3",
Expand All @@ -36,6 +36,7 @@
"jws": "^4.0.0",
"migrate": "^2.0.1",
"nordigen-node": "^1.4.0",
"openid-client": "^5.4.2",
"uuid": "^9.0.0",
"winston": "^3.14.2"
},
Expand Down
Loading

0 comments on commit 4aa37a0

Please sign in to comment.