This commit is contained in:
Ryahn 2025-01-31 08:42:47 -05:00
parent d67c39251a
commit e7532e5e67
9 changed files with 111 additions and 63 deletions

View File

@ -1,13 +1,13 @@
{ {
"files": { "files": {
"main.css": "/static/css/main.06c3544e.css", "main.css": "/static/css/main.06c3544e.css",
"main.js": "/static/js/main.47736d7c.js", "main.js": "/static/js/main.51967182.js",
"index.html": "/index.html", "index.html": "/index.html",
"main.06c3544e.css.map": "/static/css/main.06c3544e.css.map", "main.06c3544e.css.map": "/static/css/main.06c3544e.css.map",
"main.47736d7c.js.map": "/static/js/main.47736d7c.js.map" "main.51967182.js.map": "/static/js/main.51967182.js.map"
}, },
"entrypoints": [ "entrypoints": [
"static/css/main.06c3544e.css", "static/css/main.06c3544e.css",
"static/js/main.47736d7c.js" "static/js/main.51967182.js"
] ]
} }

View File

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="2 Week Mail - Temporary Email Service"/><title>2 Week Mail</title><script defer="defer" src="/static/js/main.47736d7c.js"></script><link href="/static/css/main.06c3544e.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html> <!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="2 Week Mail - Temporary Email Service"/><title>2 Week Mail</title><script defer="defer" src="/static/js/main.51967182.js"></script><link href="/static/css/main.06c3544e.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -162,40 +162,74 @@ const App = () => {
</Card> </Card>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6"> <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<Card <Card
className="hover:shadow-lg transition-shadow cursor-pointer" className="hover:shadow-lg transition-shadow cursor-pointer"
onClick={() => window.location.href = '/docs'} onClick={() => window.location.href = '/docs'}
> >
<CardHeader> <CardHeader>
<CardTitle className="flex items-center space-x-2"> <CardTitle className="flex items-center space-x-2">
<span>API Documentation</span> <span>API Documentation</span>
<ArrowRight className="h-4 w-4" /> <ArrowRight className="h-4 w-4" />
</CardTitle> </CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<p className="text-gray-600"> <p className="text-gray-600">
Comprehensive API documentation with examples and integration guides. Comprehensive API documentation with examples and integration guides.
</p> </p>
</CardContent> </CardContent>
</Card> </Card>
<Card <Card
className="hover:shadow-lg transition-shadow cursor-pointer" className="hover:shadow-lg transition-shadow cursor-pointer"
onClick={() => setCurrentPage('stats')} onClick={() => setCurrentPage('stats')}
> >
<CardHeader> <CardHeader>
<CardTitle className="flex items-center space-x-2"> <CardTitle className="flex items-center space-x-2">
<span>Usage Statistics</span> <span>Usage Statistics</span>
<BarChart2 className="h-4 w-4" /> <BarChart2 className="h-4 w-4" />
</CardTitle> </CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<p className="text-gray-600"> <p className="text-gray-600">
View real-time statistics about email creation and message reception. View real-time statistics about email creation and message reception.
</p> </p>
</CardContent> </CardContent>
</Card> </Card>
</div>
<Card
className="hover:shadow-lg transition-shadow cursor-pointer"
onClick={() => window.location.href = 'https://status.2weekmail.fyi/status/main'}
>
<CardHeader>
<CardTitle className="flex items-center space-x-2">
<span>API Status</span>
<ArrowRight className="h-4 w-4" />
</CardTitle>
</CardHeader>
<CardContent>
<p className="text-gray-600">
Check the current status and uptime of our API services.
</p>
</CardContent>
</Card>
<Card
className="hover:shadow-lg transition-shadow cursor-pointer"
onClick={() => window.location.href = 'https://ploi.app/status-pages/2weekmail-status'}
>
<CardHeader>
<CardTitle className="flex items-center space-x-2">
<span>Infrastructure Status</span>
<ArrowRight className="h-4 w-4" />
</CardTitle>
</CardHeader>
<CardContent>
<p className="text-gray-600">
Monitor our infrastructure and server status.
</p>
</CardContent>
</Card>
</div>
</div> </div>
</div> </div>
<Footer /> <Footer />

View File

@ -2,26 +2,22 @@ const Message = require("../../db/models/Message");
const Domain = require("../../db/models/Domain"); const Domain = require("../../db/models/Domain");
const TempEmail = require("../../db/models/TempEmail"); const TempEmail = require("../../db/models/TempEmail");
const config = require("../../config/haraka"); const config = require("../../config/haraka");
const { Model } = require('objection'); const { Model } = require("objection");
const Knex = require('knex'); const Knex = require("knex");
const knexConfig = require('../../config/database'); const knexConfig = require("../../config/database");
const knex = Knex(knexConfig.development); const knex = Knex(knexConfig.development);
Model.knex(knex); Model.knex(knex);
class MessageService { class MessageService {
static async isValidDomain(email) { static async isValidDomain(email) {
const domain = email.split("@")[1]; const domain = email.split("@")[1];
const tempDomain = await Domain.query() const tempDomain = await Domain.query().where("name", domain).first();
.where("name", domain)
.first();
return !tempDomain; return !tempDomain;
} }
static async isValidEmail(email) { static async isValidEmail(email) {
const tempEmail = await TempEmail.query() const tempEmail = await TempEmail.query().where("email", email).first();
.where("email", email)
.first();
return !tempEmail; return !tempEmail;
} }
@ -47,12 +43,37 @@ class MessageService {
} }
static async cleanup() { static async cleanup() {
const now = new Date().toISOString();
const cutoffDate = new Date(); const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - config.storage.retention); cutoffDate.setDate(cutoffDate.getDate() - config.storage.retention);
const deletedMessages = await Message.query().where("created_at", "<", cutoffDate).delete(); const expiredEmails = await TempEmail.query()
const deletedTempEmails = await TempEmail.query().where("created_at", "<", cutoffDate).delete(); .where("expires_at", "<", now)
return { deletedMessages, deletedTempEmails }; .select("id");
const expiredEmailIds = expiredEmails.map((email) => email.id);
if (expiredEmailIds.length > 0) {
console.log("Deleting messages for expired emails");
const deletedMessages = await Message.query()
.whereIn("temp_email_id", expiredEmailIds)
.delete();
console.log("Deleting expired temp emails");
const deletedTempEmails = await TempEmail.query()
.whereIn("id", expiredEmailIds)
.delete();
const expiredMessages = await Message.query()
.where("created_at", "<", cutoffDate)
.delete();
console.log("Deleted messages:", deletedMessages + expiredMessages);
console.log("Deleted emails:", deletedTempEmails);
return { deletedMessages, deletedTempEmails };
}
return { deletedMessages: 0, deletedTempEmails: 0 };
} }
static async search(params) { static async search(params) {
@ -75,7 +96,7 @@ class MessageService {
if (params.to) { if (params.to) {
query = query.where("to", "like", `%${params.to}%`); query = query.where("to", "like", `%${params.to}%`);
} }
if (params.subject) { if (params.subject) {
query = query.where("subject", "like", `%${params.subject}%`); query = query.where("subject", "like", `%${params.subject}%`);
} }

11
test.js
View File

@ -4,16 +4,9 @@ const Knex = require('knex');
const knexConfig = require('./src/config/database'); const knexConfig = require('./src/config/database');
const knex = Knex(knexConfig.development); const knex = Knex(knexConfig.development);
Model.knex(knex); Model.knex(knex);
const { getRandomDomain, mysqlSafeTimestamp } = require('./src/utils/functions'); const MessageService = require('./src/email_server/services/MessageService');
const DailyStats = require('./src/db/models/DailyStats');
async function main() { async function main() {
// const domain = await getRandomDomain(true); await MessageService.cleanup();
// console.log(domain);
// console.log(mysqlSafeTimestamp(true, 14));
const stats = await DailyStats.getTotalStats();
console.log(stats);
process.exit(0);
} }
main(); main();