mirror of
https://github.com/abort-retry-ignore/joplock.git
synced 2026-05-22 19:57:34 +00:00
Some checks are pending
Build and push Joplock image / build-and-push (push) Waiting to run
154 lines
5.5 KiB
JavaScript
154 lines
5.5 KiB
JavaScript
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const { createSessionService, isSessionExpired, defaultSessionTtlMs } = require('../app/auth/sessionService');
|
|
|
|
// --- isSessionExpired ---
|
|
|
|
test('isSessionExpired returns true for zero/null created time', () => {
|
|
assert.ok(isSessionExpired(0));
|
|
assert.ok(isSessionExpired(null));
|
|
assert.ok(isSessionExpired(undefined));
|
|
});
|
|
|
|
test('isSessionExpired returns false for recent session', () => {
|
|
assert.ok(!isSessionExpired(Date.now() - 1000));
|
|
});
|
|
|
|
test('isSessionExpired returns true for old session', () => {
|
|
assert.ok(isSessionExpired(Date.now() - defaultSessionTtlMs - 1));
|
|
});
|
|
|
|
test('isSessionExpired returns false at exact boundary', () => {
|
|
const now = Date.now();
|
|
assert.ok(!isSessionExpired(now - defaultSessionTtlMs + 1, now));
|
|
});
|
|
|
|
test('defaultSessionTtlMs is 12 hours', () => {
|
|
assert.equal(defaultSessionTtlMs, 12 * 60 * 60 * 1000);
|
|
});
|
|
|
|
// --- createSessionService ---
|
|
|
|
test('userBySessionId returns null for empty sessionId', async () => {
|
|
const service = createSessionService({ query: async () => { throw new Error('should not query'); } });
|
|
assert.equal(await service.userBySessionId(''), null);
|
|
assert.equal(await service.userBySessionId(null), null);
|
|
});
|
|
|
|
test('userBySessionId returns null when no row found', async () => {
|
|
const db = { query: async () => ({ rows: [] }) };
|
|
const service = createSessionService(db);
|
|
assert.equal(await service.userBySessionId('nonexistent'), null);
|
|
});
|
|
|
|
test('userBySessionId returns null for expired session', async () => {
|
|
const db = {
|
|
query: async () => ({
|
|
rows: [{
|
|
session_id: 's1', id: 'u1', email: 'a@b.com', full_name: 'A',
|
|
is_admin: 0, can_upload: 1, email_confirmed: 1, account_type: 0,
|
|
created_time: Date.now(), updated_time: Date.now(), enabled: 1,
|
|
session_created_time: Date.now() - defaultSessionTtlMs - 1000,
|
|
}],
|
|
}),
|
|
};
|
|
const service = createSessionService(db);
|
|
assert.equal(await service.userBySessionId('s1'), null);
|
|
});
|
|
|
|
test('userBySessionId returns null for disabled user', async () => {
|
|
const db = {
|
|
query: async () => ({
|
|
rows: [{
|
|
session_id: 's1', id: 'u1', email: 'a@b.com', full_name: 'A',
|
|
is_admin: 0, can_upload: 1, email_confirmed: 1, account_type: 0,
|
|
created_time: Date.now(), updated_time: Date.now(), enabled: 0,
|
|
session_created_time: Date.now(),
|
|
}],
|
|
}),
|
|
};
|
|
const service = createSessionService(db);
|
|
assert.equal(await service.userBySessionId('s1'), null);
|
|
});
|
|
|
|
test('userBySessionId returns mapped user for valid session', async () => {
|
|
const now = Date.now();
|
|
const db = {
|
|
query: async () => ({
|
|
rows: [{
|
|
session_id: 's1', id: 'u1', email: 'a@b.com', full_name: 'A B',
|
|
is_admin: 1, can_upload: 1, email_confirmed: 1, account_type: 2,
|
|
created_time: now - 5000, updated_time: now - 1000, enabled: 1,
|
|
session_created_time: now - 100,
|
|
}],
|
|
}),
|
|
};
|
|
const service = createSessionService(db);
|
|
const user = await service.userBySessionId('s1');
|
|
assert.equal(user.id, 'u1');
|
|
assert.equal(user.email, 'a@b.com');
|
|
assert.equal(user.fullName, 'A B');
|
|
assert.equal(user.isAdmin, true);
|
|
assert.equal(user.sessionId, 's1');
|
|
assert.equal(user.accountType, 2);
|
|
});
|
|
|
|
test('userBySessionId passes sessionId to query', async () => {
|
|
let captured = null;
|
|
const db = { query: async (_sql, params) => { captured = params; return { rows: [] }; } };
|
|
const service = createSessionService(db);
|
|
await service.userBySessionId('my-session-id');
|
|
assert.deepEqual(captured, ['my-session-id']);
|
|
});
|
|
|
|
// --- touchSession / getLastSeen / deleteSession ---
|
|
|
|
test('touchSession upserts last_seen into joplock_sessions', async () => {
|
|
const queries = [];
|
|
const db = { query: async (sql, params) => { queries.push({ sql, params }); return { rows: [] }; } };
|
|
const service = createSessionService(db);
|
|
const now = Date.now();
|
|
await service.touchSession('sess-abc', now);
|
|
const upsert = queries.find(q => q.sql.includes('joplock_sessions') && q.sql.includes('INSERT'));
|
|
assert.ok(upsert, 'should have upserted into joplock_sessions');
|
|
assert.equal(upsert.params[0], 'sess-abc');
|
|
assert.equal(upsert.params[1], now);
|
|
});
|
|
|
|
test('getLastSeen returns null when no row exists', async () => {
|
|
const db = { query: async () => ({ rows: [] }) };
|
|
const service = createSessionService(db);
|
|
// ensureTable creates the table first (two queries), then select
|
|
const result = await service.getLastSeen('sess-xyz');
|
|
assert.equal(result, null);
|
|
});
|
|
|
|
test('getLastSeen returns numeric last_seen when row exists', async () => {
|
|
const lastSeen = Date.now() - 30000;
|
|
let callCount = 0;
|
|
const db = {
|
|
query: async (sql) => {
|
|
callCount++;
|
|
if (sql.includes('SELECT last_seen')) return { rows: [{ last_seen: lastSeen }] };
|
|
return { rows: [] };
|
|
},
|
|
};
|
|
const service = createSessionService(db);
|
|
const result = await service.getLastSeen('sess-xyz');
|
|
assert.equal(result, lastSeen);
|
|
});
|
|
|
|
test('deleteSession removes row from joplock_sessions', async () => {
|
|
const queries = [];
|
|
const db = { query: async (sql, params) => { queries.push({ sql, params }); return { rows: [] }; } };
|
|
const service = createSessionService(db);
|
|
await service.deleteSession('sess-del');
|
|
const del = queries.find(q => q.sql.includes('DELETE') && q.params && q.params[0] === 'sess-del');
|
|
assert.ok(del, 'should have deleted from joplock_sessions');
|
|
});
|
|
|
|
test('touchSession is non-fatal on db error', async () => {
|
|
const db = { query: async () => { throw new Error('db down'); } };
|
|
const service = createSessionService(db);
|
|
await assert.doesNotReject(() => service.touchSession('s1'));
|
|
});
|