mirror of
https://github.com/Crazyco-xyz/48hr.email.git
synced 2026-01-09 11:19:36 +01:00
141 lines
4.4 KiB
JavaScript
141 lines
4.4 KiB
JavaScript
const express = require('express')
|
|
const createAuthenticator = require('../middleware/authenticator')
|
|
|
|
/**
|
|
* Inbox & Mail Retrieval API Routes
|
|
* GET /:address - List emails in inbox
|
|
* GET /:address/:uid - Get full email by UID
|
|
* GET /:address/:uid/raw - Get raw email source
|
|
* GET /:address/:uid/attachment/:checksum - Download attachment
|
|
*/
|
|
function createInboxRouter(dependencies) {
|
|
const router = express.Router()
|
|
const { mailProcessingService, apiTokenRepository } = dependencies
|
|
|
|
const { optionalAuth } = createAuthenticator(apiTokenRepository)
|
|
|
|
/**
|
|
* GET /:address - List mail summaries for an inbox
|
|
*/
|
|
router.get('/:address', optionalAuth, async(req, res, next) => {
|
|
try {
|
|
const address = req.params.address.toLowerCase()
|
|
|
|
// Get mail summaries
|
|
const mails = mailProcessingService.getMailSummaries(address)
|
|
|
|
res.apiList(mails)
|
|
} catch (error) {
|
|
next(error)
|
|
}
|
|
})
|
|
|
|
/**
|
|
* GET /:address/:uid - Get full email by UID
|
|
*/
|
|
router.get('/:address/:uid', optionalAuth, async(req, res, next) => {
|
|
try {
|
|
const address = req.params.address.toLowerCase()
|
|
const uid = parseInt(req.params.uid)
|
|
|
|
if (isNaN(uid)) {
|
|
return res.apiError('Invalid UID', 'VALIDATION_ERROR', 400)
|
|
}
|
|
|
|
// Get full email
|
|
const mail = await mailProcessingService.getOneFullMail(address, uid, false)
|
|
|
|
if (!mail) {
|
|
return res.apiError('Email not found', 'NOT_FOUND', 404)
|
|
}
|
|
|
|
// Format response
|
|
const response = {
|
|
uid: uid,
|
|
to: mail.to,
|
|
from: mail.from,
|
|
date: mail.date,
|
|
subject: mail.subject,
|
|
text: mail.text,
|
|
html: mail.html,
|
|
attachments: mail.attachments ? mail.attachments.map(att => ({
|
|
filename: att.filename,
|
|
contentType: att.contentType,
|
|
size: att.content ? att.content.length : 0,
|
|
checksum: att.checksum
|
|
})) : []
|
|
}
|
|
|
|
res.apiSuccess(response)
|
|
} catch (error) {
|
|
next(error)
|
|
}
|
|
})
|
|
|
|
/**
|
|
* GET /:address/:uid/raw - Get raw email source
|
|
*/
|
|
router.get('/:address/:uid/raw', optionalAuth, async(req, res, next) => {
|
|
try {
|
|
const address = req.params.address.toLowerCase()
|
|
const uid = parseInt(req.params.uid)
|
|
|
|
if (isNaN(uid)) {
|
|
return res.apiError('Invalid UID', 'VALIDATION_ERROR', 400)
|
|
}
|
|
|
|
// Get raw email
|
|
const rawMail = await mailProcessingService.getOneFullMail(address, uid, true)
|
|
|
|
if (!rawMail) {
|
|
return res.apiError('Email not found', 'NOT_FOUND', 404)
|
|
}
|
|
|
|
// Return as plain text
|
|
res.setHeader('Content-Type', 'text/plain')
|
|
res.send(rawMail)
|
|
} catch (error) {
|
|
next(error)
|
|
}
|
|
})
|
|
|
|
/**
|
|
* GET /:address/:uid/attachment/:checksum - Download attachment
|
|
*/
|
|
router.get('/:address/:uid/attachment/:checksum', optionalAuth, async(req, res, next) => {
|
|
try {
|
|
const address = req.params.address.toLowerCase()
|
|
const uid = parseInt(req.params.uid)
|
|
const checksum = req.params.checksum
|
|
|
|
if (isNaN(uid)) {
|
|
return res.apiError('Invalid UID', 'VALIDATION_ERROR', 400)
|
|
}
|
|
|
|
// Get full email to access attachments
|
|
const mail = await mailProcessingService.getOneFullMail(address, uid, false)
|
|
|
|
if (!mail || !mail.attachments) {
|
|
return res.apiError('Email or attachment not found', 'NOT_FOUND', 404)
|
|
}
|
|
|
|
// Find attachment by checksum
|
|
const attachment = mail.attachments.find(att => att.checksum === checksum)
|
|
|
|
if (!attachment) {
|
|
return res.apiError('Attachment not found', 'NOT_FOUND', 404)
|
|
}
|
|
|
|
// Send attachment
|
|
res.setHeader('Content-Type', attachment.contentType || 'application/octet-stream')
|
|
res.setHeader('Content-Disposition', `attachment; filename="${attachment.filename}"`)
|
|
res.send(attachment.content)
|
|
} catch (error) {
|
|
next(error)
|
|
}
|
|
})
|
|
|
|
return router
|
|
}
|
|
|
|
module.exports = createInboxRouter
|