Introduce a new logger (modules/logger.js) that prints colorized console output, writes timestamped logs to a file in a logs/ directory, strips ANSI colors for file output, and handles process exit/SIGINT cleanup. Add service stubs (services/security.js, services/storage.js, services/smtp/actions.js, services/smtp/authenticate.js) and a test.js. Add package.json and package-lock.json with runtime deps (colors, dotenv, zod) and dev tooling (eslint, nodemon) to support the new code.
65 lines
1.8 KiB
JavaScript
65 lines
1.8 KiB
JavaScript
const fs = require("node:fs");
|
|
const fsPromises = require("node:fs/promises");
|
|
const path = require("node:path");
|
|
const logger = require("../modules/logger");
|
|
|
|
const BASE_PATH = path.resolve(process.env.MAIL_STORAGE || process.cwd(), "storage")
|
|
|
|
function initialize() {
|
|
const directories = ["", "new", "cur", "tmp"]
|
|
for (const dir of directories) {
|
|
const fullPath = path.join(BASE_PATH, dir)
|
|
if (!fs.existsSync(fullPath)) {
|
|
fs.mkdirSync(fullPath, { recursive: true })
|
|
}
|
|
}
|
|
logger.log("Directories initialized", ["StorageService", "cyan"])
|
|
}
|
|
|
|
function createMailWriteStream() {
|
|
const fileName = `${Date.now()}.${process.pid}.jawab`
|
|
const tempPath = path.join(BASE_PATH, "tmp", fileName)
|
|
const finalPath = path.join(BASE_PATH, "new", fileName)
|
|
|
|
const writeStream = fs.createWriteStream(tempPath)
|
|
|
|
writeStream.on("finish", async () => {
|
|
try {
|
|
await fsPromises.rename(tempPath, finalPath)
|
|
} catch (err) {
|
|
logger.log(`Rename failed: ${err.message}`, ["StorageService", "cyan"]);
|
|
}
|
|
})
|
|
|
|
return { writeStream, fileName }
|
|
}
|
|
|
|
async function listNewMails() {
|
|
try {
|
|
const files = await fsPromises.readdir(path.join(BASE_PATH, "new"))
|
|
return files.map(file => ({
|
|
id: file,
|
|
path: path.join(BASE_PATH, "new", file),
|
|
status: "new"
|
|
}))
|
|
} catch (err) {
|
|
return []
|
|
}
|
|
}
|
|
|
|
async function getMailContent(fileName, folder = "new") {
|
|
const fullPath = path.join(BASE_PATH, folder, fileName);
|
|
try {
|
|
await fsPromises.access(fullPath, fs.constants.R_OK)
|
|
return fs.createReadStream(fullPath)
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
initialize,
|
|
listNewMails,
|
|
getMailContent,
|
|
createMailWriteStream
|
|
} |