inbound-db.test.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import assert from 'node:assert/strict';
  2. import { mkdtempSync } from 'node:fs';
  3. import { tmpdir } from 'node:os';
  4. import path from 'node:path';
  5. import { test } from 'node:test';
  6. import {
  7. createDomain,
  8. createInboundMailbox,
  9. createInboundMessage,
  10. createUser,
  11. getInboundMailboxByAddress,
  12. getInboundMessage,
  13. initDatabase,
  14. listInboundMailboxes,
  15. listInboundMessages,
  16. markInboundMessageRead
  17. } from '../src/db.js';
  18. test('users can create inbound mailboxes and read received messages', () => {
  19. initDatabase(mkdtempSync(path.join(tmpdir(), 'mailhub-inbound-db-')), 'inbound-secret');
  20. const user = createUser({ username: 'inbound-user', email: 'inbound-user@example.com', password: 'password123' });
  21. createDomain(user.id, {
  22. domain: 'inbound.example',
  23. selector: 'mh',
  24. verificationToken: 'verify',
  25. dkimPublic: 'public',
  26. dkimPrivate: 'private',
  27. senderHost: 'mail.inbound.example',
  28. sendingIp: '192.0.2.10',
  29. spfExtra: '',
  30. dmarcPolicy: 'none',
  31. dmarcRua: ''
  32. });
  33. const mailbox = createInboundMailbox(user.id, {
  34. address: 'Support@Inbound.Example',
  35. displayName: 'Support'
  36. });
  37. assert.equal(mailbox.address, 'support@inbound.example');
  38. assert.equal(mailbox.displayName, 'Support');
  39. assert.equal(mailbox.messageCount, 0);
  40. assert.equal(mailbox.unreadCount, 0);
  41. const resolved = getInboundMailboxByAddress('SUPPORT@INBOUND.EXAMPLE');
  42. assert.equal(resolved.id, mailbox.id);
  43. assert.equal(resolved.userId, user.id);
  44. const message = createInboundMessage(resolved, {
  45. sender: 'alice@example.net',
  46. recipients: ['support@inbound.example'],
  47. subject: 'Hello inbound',
  48. messageId: '<hello@example.net>',
  49. rawMessage: 'From: alice@example.net\r\nTo: support@inbound.example\r\nSubject: Hello inbound\r\n\r\nHello MailHub',
  50. textBody: 'Hello MailHub',
  51. htmlBody: ''
  52. });
  53. assert.equal(message.mailboxId, mailbox.id);
  54. assert.equal(message.read, false);
  55. const mailboxes = listInboundMailboxes(user.id);
  56. assert.equal(mailboxes.length, 1);
  57. assert.equal(mailboxes[0].messageCount, 1);
  58. assert.equal(mailboxes[0].unreadCount, 1);
  59. const messages = listInboundMessages(user.id);
  60. assert.equal(messages.length, 1);
  61. assert.equal(messages[0].subject, 'Hello inbound');
  62. assert.equal(messages[0].preview, 'Hello MailHub');
  63. assert.equal('rawMessage' in messages[0], false);
  64. const detail = getInboundMessage(user.id, message.id);
  65. assert.equal(detail.rawMessage.includes('Hello MailHub'), true);
  66. assert.equal(detail.textBody, 'Hello MailHub');
  67. const readMessage = markInboundMessageRead(user.id, message.id, true);
  68. assert.equal(readMessage.read, true);
  69. assert.equal(listInboundMailboxes(user.id)[0].unreadCount, 0);
  70. assert.equal(markInboundMessageRead(999999, message.id, true), null);
  71. });
  72. test('inbound mailboxes must belong to a domain owned by the user', () => {
  73. initDatabase(mkdtempSync(path.join(tmpdir(), 'mailhub-inbound-db-scope-')), 'inbound-secret');
  74. const owner = createUser({ username: 'owner-user', email: 'owner@example.com', password: 'password123' });
  75. const other = createUser({ username: 'other-user', email: 'other@example.com', password: 'password123' });
  76. createDomain(owner.id, {
  77. domain: 'owned.example',
  78. selector: 'mh',
  79. verificationToken: 'verify',
  80. dkimPublic: 'public',
  81. dkimPrivate: 'private',
  82. senderHost: 'mail.owned.example',
  83. sendingIp: '192.0.2.11',
  84. spfExtra: '',
  85. dmarcPolicy: 'none',
  86. dmarcRua: ''
  87. });
  88. assert.throws(
  89. () => createInboundMailbox(other.id, { address: 'support@owned.example' }),
  90. /收信域名不存在/
  91. );
  92. });