summaryrefslogtreecommitdiff
path: root/app/imap.js
blob: 181d9cf4cfd2469c8e5a269de81b7c3969e1671a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
const { ipcMain } = require('electron');
const { ImapFlow } = require('imapflow');

ipcMain.on('imap:listTree:from', listTreeFrom);
ipcMain.on('imap:listTree:to', listTreeTo);
ipcMain.on('imap:migrate', migrate);

async function connect (options) {
  const client = new ImapFlow({
    host: options.server,
    port: options.port,
    auth: {
      user: options.username,
      pass: options.password,
    },
  });

  await client.connect();

  return client;
}

ImapFlow.prototype.fetchArray = async function (range, query, options = {}) {
  const msgsGenerator = await this.fetch(range, query, options);
  const msgs = [];
  for await (const msg of msgsGenerator) {
    msgs.push(msg);
  }

  return msgs;
};

async function listTreeFrom (event, options) {
  const client = await connect(options);

  event.reply('imap:listTree:from:reply', await client.listTree());
  await client.logout();
}

async function listTreeTo (event, options) {
  const client = await connect(options);

  event.reply('imap:listTree:to:reply', await client.listTree());
  await client.logout();
}

async function migrate (event, { from, to }) {
  const fromClient = await connect(from);
  const toClient = await connect(to);

  const fromFolders = (await fromClient.list()).filter((folder) => folder.subscribed);
  for (const fromFolder of fromFolders) {
    try {
      await toClient.mailboxCreate(fromFolder.path);
    } catch (e) {}

    const fromMailbox = await fromClient.getMailboxLock(fromFolder.path);
    const toMailbox = await toClient.getMailboxLock(fromFolder.path);
    try {
      const toMsgs = await toClient.fetchArray('1:*', { flags: true, envelope: true, source: true });
      const fromMsgs = await fromClient.fetchArray('1:*', { flags: true, envelope: true, source: true });

      const msgs = fromMsgs.filter((fromMsg) => !toMsgs.some((toMsg) => Buffer.compare(toMsg.source, fromMsg.source) === 0));

      await toClient.noop();
      for (const msg of msgs) {
        toClient.append(fromFolder.path, msg.source, Array.from(msg.flags), msg.envelope.date);
      }
    } finally {
      fromMailbox.release();
      toMailbox.release();
    }
  }
}