| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- import assert from 'node:assert/strict';
- import { mkdtempSync } from 'node:fs';
- import { tmpdir } from 'node:os';
- import path from 'node:path';
- import { test } from 'node:test';
- import { DatabaseSync } from 'node:sqlite';
- import {
- authenticateUser,
- claimLegacyData,
- createApiToken,
- createDomain,
- createUser,
- getSmtpCredential,
- initDatabase,
- listDomains,
- listSendEvents,
- logSendEvent,
- saveSmtpCredential,
- seedAdminUser,
- verifyApiToken,
- verifySmtpCredential
- } from '../src/db.js';
- test('migrates legacy data to the seeded admin user', () => {
- const dataDir = tempDataDir();
- const dbPath = path.join(dataDir, 'mailhub.sqlite');
- const legacy = new DatabaseSync(dbPath);
- legacy.exec(`
- CREATE TABLE domains (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- domain TEXT NOT NULL UNIQUE,
- selector TEXT NOT NULL,
- verification_token TEXT NOT NULL,
- dkim_public TEXT NOT NULL,
- dkim_private TEXT NOT NULL,
- sender_host TEXT NOT NULL,
- sending_ip TEXT NOT NULL,
- spf_extra TEXT NOT NULL DEFAULT '',
- dmarc_policy TEXT NOT NULL DEFAULT 'none',
- dmarc_rua TEXT NOT NULL DEFAULT '',
- status_json TEXT NOT NULL DEFAULT '{}',
- created_at TEXT NOT NULL,
- updated_at TEXT NOT NULL
- );
- CREATE TABLE send_events (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- domain_id INTEGER,
- sender TEXT NOT NULL,
- recipients TEXT NOT NULL,
- subject TEXT NOT NULL,
- status TEXT NOT NULL,
- detail TEXT NOT NULL DEFAULT '',
- created_at TEXT NOT NULL
- );
- CREATE TABLE smtp_credentials (
- id INTEGER PRIMARY KEY CHECK (id = 1),
- username TEXT NOT NULL,
- password_hash TEXT NOT NULL,
- password_secret TEXT NOT NULL DEFAULT '',
- created_at TEXT NOT NULL,
- updated_at TEXT NOT NULL
- );
- `);
- legacy
- .prepare(`
- INSERT INTO domains (
- domain, selector, verification_token, dkim_public, dkim_private,
- sender_host, sending_ip, spf_extra, dmarc_policy, dmarc_rua, created_at, updated_at
- ) VALUES ('legacy.example', 'mh', 'tok', 'pub', 'priv', 'mail.legacy.example', '127.0.0.1', '', 'none', '', 'now', 'now')
- `)
- .run();
- legacy
- .prepare(`
- INSERT INTO send_events (domain_id, sender, recipients, subject, status, detail, created_at)
- VALUES (1, 'noreply@legacy.example', '["user@example.com"]', 'hi', 'queued', '', 'now')
- `)
- .run();
- legacy
- .prepare(`
- INSERT INTO smtp_credentials (id, username, password_hash, password_secret, created_at, updated_at)
- VALUES (1, 'legacy-smtp', 'scrypt$salt$hash', '', 'now', 'now')
- `)
- .run();
- legacy.close();
- initDatabase(dataDir, 'test-secret');
- const admin = seedAdminUser({ username: 'admin', email: 'admin@example.com', password: 'password123' });
- claimLegacyData(admin.id);
- assert.equal(listDomains(admin.id).length, 1);
- assert.equal(listSendEvents(admin.id).length, 1);
- assert.equal(getSmtpCredential(admin.id).username, 'legacy-smtp');
- });
- test('isolates domains, smtp credentials, and api tokens by user', () => {
- initDatabase(tempDataDir(), 'test-secret');
- const admin = seedAdminUser({ username: 'admin', email: 'admin@example.com', password: 'password123' });
- claimLegacyData(admin.id);
- const alice = createUser({ username: 'alice', email: 'alice@example.com', password: 'password123' });
- const bob = createUser({ username: 'bob', email: 'bob@example.com', password: 'password123' });
- assert.equal(authenticateUser('alice', 'password123').id, alice.id);
- assert.equal(authenticateUser('alice', 'wrong'), null);
- createDomain(alice.id, domainFixture('alice.example'));
- assert.equal(listDomains(alice.id).length, 1);
- assert.equal(listDomains(bob.id).length, 0);
- logSendEvent({
- userId: alice.id,
- domainId: listDomains(alice.id)[0].id,
- sender: 'noreply@alice.example',
- recipients: ['user@example.com'],
- subject: 'Hello',
- status: 'queued'
- });
- assert.equal(listSendEvents(alice.id).length, 1);
- assert.equal(listSendEvents(bob.id).length, 0);
- saveSmtpCredential(alice.id, { username: 'smtp-alice', password: 'copy-me-123' });
- assert.equal(getSmtpCredential(alice.id, { includePassword: true }).password, 'copy-me-123');
- assert.equal(verifySmtpCredential('smtp-alice', 'copy-me-123').user.id, alice.id);
- assert.equal(verifySmtpCredential('smtp-alice', 'wrong'), null);
- const token = createApiToken(alice.id, 'send');
- assert.equal(verifyApiToken(token.token).id, alice.id);
- });
- function domainFixture(domain) {
- return {
- domain,
- selector: 'mh202607',
- verificationToken: 'token',
- dkimPublic: 'public',
- dkimPrivate: 'private',
- senderHost: `mail.${domain}`,
- sendingIp: '127.0.0.1',
- spfExtra: '',
- dmarcPolicy: 'none',
- dmarcRua: ''
- };
- }
- function tempDataDir() {
- return mkdtempSync(path.join(tmpdir(), 'mailhub-test-'));
- }
|