From d78fbf730e873a2ea799a9b92f8e3b68d45a745a Mon Sep 17 00:00:00 2001 From: fullgream Date: Tue, 27 May 2025 04:09:38 +0300 Subject: [PATCH] Add IMAP server func --- imap/index.js | 24 ++++++++++++++++++++++ imap/logic.js | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ server.js | 15 ++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 imap/index.js create mode 100644 imap/logic.js diff --git a/imap/index.js b/imap/index.js new file mode 100644 index 0000000..e41fce5 --- /dev/null +++ b/imap/index.js @@ -0,0 +1,24 @@ +const net = require("net"); +const imap = require("./logic"); +//const EventEmitter = require("events"); + +const server = net.createServer((socket) => { + const client = new imap.Client(socket); + socket.write("* OK IMAP4rev1 NodeIMAP Ready\r\n"); + + let state = "not_authenticated"; + let currentMailbox = null; + //let tag = ""; + + socket.on("data", (data) => { + const line = data.toString().trim(); + console.debug("IMAP data:", line); + const splitted = line.split(/\s{1,}/g); + if (splitted.length < 2) return socket.write(". BAD unknown command\r\n"); + const [tag, command, ...args] = splitted; + + client.command(tag, command, args); + }); +}); + +module.exports = server; diff --git a/imap/logic.js b/imap/logic.js new file mode 100644 index 0000000..19bc80f --- /dev/null +++ b/imap/logic.js @@ -0,0 +1,56 @@ +class IMAPController { + constructor (socket, tag) { + this.socket = socket; + this.tag = tag; + } + + out (answer) { + this.socket.write(`${this.tag} ${answer}`); + } + + untaggedOut (answer) { + this.socket.write(answer); + } + + close () { + this.socket.end(); + } +} + +class Commands { + constructor (client) { + this.client = client; + } + + async capability (args, controller) { + /*if (args.length > 0) + return out();*/ + controller.untaggedOut("* CAPABILITY IMAP4rev1 STARTTLS LOGINDISABLED\r\n"); + controller.out("OK CAPABILITY completed\r\n"); + } + + async logout(args, controller) { + controller.untaggedOut("* BYE Logging out\r\n"); + controller.out("OK LOGOUT completed\r\n"); + + controller.close(); + } +} + +class Client { + constructor (socket) { + this.socket = socket; + this.commands = new Commands(this); + } + + command (tag, command, args) { + //console.debug("this >>", this, this.socket, this.commands); + const cmd = this.commands[command.toLowerCase()]; + if (cmd === undefined) { + return this.socket.write(`${tag} BAD unknown command\r\n`); + } + cmd.call(this.commands, args, new IMAPController(this.socket, tag)); + } +} + +module.exports = { Client }; diff --git a/server.js b/server.js index e930a9d..2f072d9 100644 --- a/server.js +++ b/server.js @@ -3,6 +3,8 @@ const fs = require("fs"); const net = require('net'); const { EventEmitter } = require("events"); +const imap = require("./imap"); + const initalConfig = `{ "pop3-config": { "user": "example", @@ -55,3 +57,16 @@ pop3.init().then(() => { //console.log(str); }, 1); }); + +imap.listen( + global.config["imap-config"].port, + global.config["imap-config"].host, + (err) => { + if (err) throw err; + console.log(`IMAP server running on ${ + global.config["imap-config"].host + }:${ + global.config["imap-config"].port + }`); + } +);