From e31072ad6a09a6fba7118a1091ae2b31895d7d21 Mon Sep 17 00:00:00 2001 From: Aidan Date: Sun, 19 Jan 2025 18:27:23 -0500 Subject: [PATCH] update to prepare for mailu migration --- .env.example | 10 -- app.js | 235 ++++++------------------------------ bun.lockb | Bin 0 -> 61155 bytes package.json | 2 +- src/admin/dash.ejs | 58 --------- src/admin/edit.ejs | 25 ---- src/admin/login.ejs | 21 ---- src/admin/shards/footer.ejs | 4 - src/admin/shards/header.ejs | 37 ------ src/error/404.ejs | 7 -- src/error/500.ejs | 7 -- src/error/email.ejs | 25 ---- src/error/notfoundemail.ejs | 7 -- src/index.ejs | 23 +--- src/privacy.ejs | 14 +-- src/reg-success.ejs | 8 -- src/register.ejs | 46 ------- src/request.ejs | 51 -------- src/services.ejs | 3 +- src/shards/nav.ejs | 14 +-- 20 files changed, 51 insertions(+), 546 deletions(-) delete mode 100644 .env.example create mode 100755 bun.lockb delete mode 100644 src/admin/dash.ejs delete mode 100644 src/admin/edit.ejs delete mode 100644 src/admin/login.ejs delete mode 100644 src/admin/shards/footer.ejs delete mode 100644 src/admin/shards/header.ejs delete mode 100644 src/error/404.ejs delete mode 100644 src/error/500.ejs delete mode 100644 src/error/email.ejs delete mode 100644 src/error/notfoundemail.ejs delete mode 100644 src/reg-success.ejs delete mode 100644 src/register.ejs delete mode 100644 src/request.ejs diff --git a/.env.example b/.env.example deleted file mode 100644 index c5186bb..0000000 --- a/.env.example +++ /dev/null @@ -1,10 +0,0 @@ -DB_NAME=pontusmail -DB_USER=root -DB_PASSWORD=passwdhere -DB_HOST=127.0.0.1 -DB_PORT=3306 -SESSION_SECRET=secretkeyhere -ADMIN_USERNAME=admin -ADMIN_PASSWORD=admin -INTERNAL_PORT=3000 -MC_API_KEY=mailcowapikeyhere \ No newline at end of file diff --git a/app.js b/app.js index edaf39f..249a50b 100644 --- a/app.js +++ b/app.js @@ -2,8 +2,6 @@ const express = require('express'); const bodyParser = require('body-parser'); const path = require('path'); const fs = require('fs'); -const session = require('express-session'); -const { Sequelize, DataTypes } = require('sequelize'); const axios = require('axios'); const NodeCache = require('node-cache'); const cache = new NodeCache({ stdTTL: 1800 }); @@ -16,81 +14,47 @@ app.set('views', path.join(__dirname, 'src')); app.use(bodyParser.urlencoded({ extended: false })); app.use(express.static(path.join(__dirname, 'public'))); -app.use(session({ - secret: process.env.SESSION_SECRET, - resave: false, - saveUninitialized: true -})); -const sequelize = new Sequelize(process.env.DB_NAME, process.env.DB_USER, process.env.DB_PASSWORD, { - host: process.env.DB_HOST || '127.0.0.1', // pulls from .env or defaults to localhost - port: process.env.DB_PORT || 3306, // pulls from .env or defaults to 3306 - dialect: 'mysql' -}); +//async function fetchDomainData() { +// const cachedData = cache.get('domainData'); +// if (cachedData) { +// return cachedData; +// } +// +// try { +// const response = await axios.get('https://user.p0ntus.com/api/v1/get/domain/all', { +// headers: { +// 'accept': 'application/json', +// 'X-API-Key': process.env.MC_API_KEY +// } +// }); +// const domainData = response.data; +// cache.set('domainData', domainData); +// return domainData; +// } catch (error) { +// console.error('Error fetching domain data:', error); +// return []; +// } +//} -sequelize.authenticate() - .then(() => console.log('Database connected')) - .catch(err => console.log('Error: ' + err)); - -const Request = sequelize.define('Request', { - fullName: DataTypes.STRING, - email: DataTypes.STRING, - reason: DataTypes.TEXT, - telegram: DataTypes.STRING, - status: { - type: DataTypes.STRING, - defaultValue: 'Pending' - } -}); - -async function fetchDomainData() { - const cachedData = cache.get('domainData'); - if (cachedData) { - return cachedData; - } - - try { - const response = await axios.get('https://user.p0ntus.com/api/v1/get/domain/all', { - headers: { - 'accept': 'application/json', - 'X-API-Key': process.env.MC_API_KEY - } - }); - const domainData = response.data; - cache.set('domainData', domainData); - return domainData; - } catch (error) { - console.error('Error fetching domain data:', error); - return []; - } -} - -function getDomains() { - const domainsPath = path.join(__dirname, 'domains.txt'); - try { - const domains = fs.readFileSync(domainsPath, 'utf-8').split('\n').filter(Boolean); - return domains; - } catch (error) { - console.error('Error reading domains.txt:', error); - return []; - } -} - -// Sync DB models -sequelize.sync(); +//function getDomains() { +// const domainsPath = path.join(__dirname, 'domains.txt'); +// try { +// const domains = fs.readFileSync(domainsPath, 'utf-8').split('\n').filter(Boolean); +// return domains; +// } catch (error) { +// console.error('Error reading domains.txt:', error); +// return []; +// } +//} app.get('/', async (req, res) => { - const domainData = await fetchDomainData(); - const domainCount = Array.isArray(domainData) ? domainData.length : 0; - const accountCount = Array.isArray(domainData) ? domainData.reduce((acc, domain) => acc + domain.mboxes_in_domain, 0) : 0; - const totalData = Array.isArray(domainData) ? domainData.reduce((acc, domain) => acc + parseInt(domain.bytes_total), 0) / (1024 * 1024) : 0; + //const domainData = await fetchDomainData(); + //const domainCount = Array.isArray(domainData) ? domainData.length : 0; + //const accountCount = Array.isArray(domainData) ? domainData.reduce((acc, domain) => acc + domain.mboxes_in_domain, 0) : 0; + //const totalData = Array.isArray(domainData) ? domainData.reduce((acc, domain) => acc + parseInt(domain.bytes_total), 0) / (1024 * 1024) : 0; - res.render('index', { - currentPage: 'home', - domainCount, - accountCount, - totalData: totalData.toFixed(2) // Round to 2 decimal places - }); + res.render('index', { currentPage: 'home' }); }); app.get('/services', (req, res) => { @@ -142,133 +106,6 @@ app.get('/guides/vaultwarden/firefox', (req, res) => { res.render('guides/vaultwarden/firefox', { currentPage: 'guides' }); }); -app.get('/register', (req, res) => { - const domains = getDomains(); - res.render('register', { domains }); -}); - -app.post('/register', async (req, res) => { - const { fullName, email, domain, reason, telegram } = req.body; - const crit = /^[a-zA-Z0-9.-]+$/; // regex (see also: public/js/register.js) - - if (!crit.test(email) || /\s/.test(email) || email !== email.toLowerCase()) { - return res.render('error/500'); - } - - const fullEmail = `${email}@${domain}`; - - try { - await Request.create({ fullName, email: fullEmail, reason, telegram }); - res.render('reg-success', { currentPage: 'register' }); - } catch (error) { - console.error('Error creating request:', error); - res.render('error/500'); - } -}); - -app.get('/request', async (req, res) => { - console.log("Found!"); - const { email } = req.query; - const domains = getDomains(); - - if (!email) { - return res.render('error/email', { domains }); - } - - try { - const request = await Request.findOne({ where: { email } }); - if (!request) { - return res.status(404).render('error/notfoundemail', { email, domain }); - } - res.render('request', { request, domains }); - } catch (error) { - console.error(error); - res.render('error/500'); - } -}); - -app.post('/request', async (req, res) => { - console.log("Found!"); - const { email, domain } = req.body; - const fullEmail = `${email}@${domain}`; - const domains = getDomains(); - - if (!email || !domain) { - return res.render('error/email', { domains }); - } - - try { - const request = await Request.findOne({ where: { email: fullEmail } }); - const domains = getDomains(); - if (!request) { - return res.render('error/notfoundemail', { email, domain }); - } - res.render('request', { request, domains }); - } catch (error) { - console.error(error); - res.render('error/500'); - } -}); - -function checkAdminAuth(req, res, next) { - if (req.session.admin) { - next(); - } else { - res.redirect('/admin'); - } -} - -// Admin routes - -app.get('/admin', (req, res) => { - if (req.session.admin) { - return res.redirect('/admin/dashboard'); - } - res.render('admin/login', { currentPage: 'admin', error: null }); -}); - -app.post('/admin', (req, res) => { - const { username, password } = req.body; - if (username === process.env.ADMIN_USERNAME && password === process.env.ADMIN_PASSWORD) { - req.session.admin = true; - res.redirect('/admin/dashboard'); - } else { - res.render('admin/login', { error: 'An error occurred.' }); - } -}); - -app.get('/admin/dashboard', checkAdminAuth, async (req, res) => { - const requests = await Request.findAll(); - res.render('admin/dash', { requests, currentPage: 'admin', user: process.env.ADMIN_USERNAME }); -}); - -app.post('/admin/update-status', checkAdminAuth, async (req, res) => { - const { id, status } = req.body; - await Request.update({ status }, { where: { id } }); - res.redirect('/admin/dashboard'); -}); - -app.post('/admin/delete-request', checkAdminAuth, async (req, res) => { - const { id } = req.body; - await Request.destroy({ where: { id } }); - res.redirect('/admin/dashboard'); -}); - -app.get('/admin/edit/:id', checkAdminAuth, async (req, res) => { - const { id } = req.params; - const request = await Request.findByPk(id); - if (!request) { - return res.status(404).render('error/404'); - } - res.render('admin/edit', { request, currentPage: 'admin' }); -}); - -app.post('/admin/edit', checkAdminAuth, async (req, res) => { - const { id, fullName, email, reason, telegram } = req.body; - await Request.update({ fullName, email, reason, telegram }, { where: { id } }); - res.redirect('/admin/dashboard'); -}); - // Start server on internal port defined in .env app.listen(process.env.INTERNAL_PORT, () => { console.log(`Server started on port ${process.env.INTERNAL_PORT}`); diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..f82c034c514e457b4646c3488e7a7893eff7552d GIT binary patch literal 61155 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 r<_#Mhd;79gH5+}QnQjP@=@(2 -
-
-

Welcome, <%= user %>!

-

You are viewing all requests

-
-
- - - - - - - - - - - - - - - <% requests.forEach(request => { %> - - - - - - - - - - - <% }); %> - -
IDFull NameEmailReasonTelegramStatusUpdate StatusDelete
<%= request.id %><%= request.fullName %><%= request.email %><%= request.reason %><%= request.telegram %><%= request.status %> -
- - - -
-
- - - -
- - -
-
-
-
-<%- include('shards/footer') %> \ No newline at end of file diff --git a/src/admin/edit.ejs b/src/admin/edit.ejs deleted file mode 100644 index c06a30b..0000000 --- a/src/admin/edit.ejs +++ /dev/null @@ -1,25 +0,0 @@ -<%- include('shards/header', { title: 'Edit Request - p0ntus mail' }) %> -
-

Edit Request

-
- -
- - -
-
- - -
-
- - -
-
- - -
- -
-
-<%- include('shards/footer') %> \ No newline at end of file diff --git a/src/admin/login.ejs b/src/admin/login.ejs deleted file mode 100644 index d023507..0000000 --- a/src/admin/login.ejs +++ /dev/null @@ -1,21 +0,0 @@ -<%- include('../shards/header', { title: 'Admin - p0ntus mail' }) %> -
- <%- include('../shards/nav', { currentPage: 'admin' }) %> - Login to administration panel -
- <% if (error) { %> -
<%= error %>
- <% } %> -
-
- - -
-
- - -
- -
-
-<%- include('../shards/footer') %> \ No newline at end of file diff --git a/src/admin/shards/footer.ejs b/src/admin/shards/footer.ejs deleted file mode 100644 index 8db4976..0000000 --- a/src/admin/shards/footer.ejs +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/admin/shards/header.ejs b/src/admin/shards/header.ejs deleted file mode 100644 index 10d5cc8..0000000 --- a/src/admin/shards/header.ejs +++ /dev/null @@ -1,37 +0,0 @@ - - - - - <%= title %> - - - - - - \ No newline at end of file diff --git a/src/error/404.ejs b/src/error/404.ejs deleted file mode 100644 index 5f7ee56..0000000 --- a/src/error/404.ejs +++ /dev/null @@ -1,7 +0,0 @@ -<%- include('../shards/header', { title: '404 Not Found - p0ntus mail', currentPage: 'err' }) %> -
- 404 Not Found -
-

The requested resource could not be found.

-
-<%- include('../shards/footer') %> \ No newline at end of file diff --git a/src/error/500.ejs b/src/error/500.ejs deleted file mode 100644 index 3221398..0000000 --- a/src/error/500.ejs +++ /dev/null @@ -1,7 +0,0 @@ -<%- include('../shards/header', { title: '500 Internal Server Error - p0ntus mail', currentPage: 'err' }) %> -
- 500 Internal Server Error -
-

An unexpected error occurred. Please try again later.

-
-<%- include('../shards/footer') %> \ No newline at end of file diff --git a/src/error/email.ejs b/src/error/email.ejs deleted file mode 100644 index f88efc7..0000000 --- a/src/error/email.ejs +++ /dev/null @@ -1,25 +0,0 @@ -<%- include('../shards/header', { title: 'Request Status - p0ntus mail', currentPage: 'err' }) %> -
- <%- include('../shards/nav', { currentPage: 'request' }) %> - We need your email -
-

We need an email to check your request. Please enter your p0ntus mail email address below:

-
-
- -
- -
- @ -
- -
-
- -
-
-<%- include('../shards/footer') %> \ No newline at end of file diff --git a/src/error/notfoundemail.ejs b/src/error/notfoundemail.ejs deleted file mode 100644 index 4415c2a..0000000 --- a/src/error/notfoundemail.ejs +++ /dev/null @@ -1,7 +0,0 @@ -<%- include('../shards/header', { title: "Couldn't find that email - p0ntus mail", currentPage: 'err' }) %> -
- We couldn't find that email -
-

We couldn't find a request under <%= email %>@<%= domain %>. Please try again later or try and register again.

-
-<%- include('../shards/footer') %> \ No newline at end of file diff --git a/src/index.ejs b/src/index.ejs index 88fcdd1..1c82d3c 100644 --- a/src/index.ejs +++ b/src/index.ejs @@ -10,33 +10,20 @@
If you aren't a current user
- Register - Check Registration Status + Register
Statistics
-
-
-

<%= domainCount %>

-

Domains Hosted

-
-
-

<%= accountCount %>

-

Accounts

-
-
-

<%= totalData %>

-

Total Data (MB)

-
-
+

As we have migrated to a new email platform, we are currently rewriting this.

Please note all domains may not be available for registration. <%- include('shards/footer') %> \ No newline at end of file diff --git a/src/privacy.ejs b/src/privacy.ejs index bc26970..8ba6a40 100644 --- a/src/privacy.ejs +++ b/src/privacy.ejs @@ -5,17 +5,15 @@

Our system collects automatically:

    -
  • Log files which may include the currently logged-in IP address. Log files are stored in memory, and Redis lists.
  • -
  • Last login time
  • -
  • Storage used by your account
  • -
  • Message count for your account
  • -
  • Last message received time
  • -
  • Account creation date
  • +
  • Log files which may include the currently logged-in IP address, user agent, or other identifying information. We clear this data as much as possible.
  • +
  • Storage and disk quota used by your account
  • +
  • Account creation date (no time)
  • +
  • Linked external email addresses' folders, last check date, status, created date, users, and the ability to take actions (like you can on your dashboard).
  • +
  • Automatic reply settings

What I collect by choice:

    -
  • Email used at registration
  • -
  • Telegram account (if given at registration)
  • +
  • I do not collect any extra information at the moment

What the admin has access to:

    diff --git a/src/reg-success.ejs b/src/reg-success.ejs deleted file mode 100644 index 6c94f7d..0000000 --- a/src/reg-success.ejs +++ /dev/null @@ -1,8 +0,0 @@ -<%- include('shards/header', { title: 'Registration Successful - p0ntus mail' }) %> -
    - <%- include('shards/nav', { currentPage: 'register' }) %> - Registration Submitted -
    -

    Your request has been submitted successfully. You can check the status of your request here.

    -
    -<%- include('shards/footer') %> \ No newline at end of file diff --git a/src/register.ejs b/src/register.ejs deleted file mode 100644 index b52e497..0000000 --- a/src/register.ejs +++ /dev/null @@ -1,46 +0,0 @@ -<%- include('shards/header', { title: 'Register - p0ntus mail', currentPage: 'register' }) %> -
    - <%- include('shards/nav', { currentPage: 'register' }) %> -

    Register

    - If you already filled out a registration request -
    - - If you haven't filled out a registration request -
    -

    Do not use this service for spam. It is a waste of your time. I have added protections to prevent spam, including sending quotas per hour. I will catch you before you can send a good enough amount.

    -
    -
    - - -
    -
    - -
    - -
    - @ -
    - -
    - Only letters, numbers, periods, and dashes are allowed. -
    -
    - - -
    -
    - - -
    - -
    -
    -<%- include('shards/footer') %> \ No newline at end of file diff --git a/src/request.ejs b/src/request.ejs deleted file mode 100644 index 3416916..0000000 --- a/src/request.ejs +++ /dev/null @@ -1,51 +0,0 @@ -<%- include('shards/header', { title: 'Request Status - p0ntus mail', currentPage: 'request' }) %> -
    - <%- include('shards/nav', { currentPage: 'request' }) %> - Request Status -
    -
    -
    - -
    - -
    - @ -
    - -
    - Only letters, numbers, periods, and dashes are allowed. -
    - -
    - - <% if (request) { %> -
    -

    Email: <%= request.email %>

    -

    Request Status: <%= request.status %>

    - <% if (request.status === 'Approved') { %> -
    -

    Your request has been approved. You can access your p0ntus mail account here with your email as the username and abcabc for the password. FOR SECURITY, CHANGE YOUR PASSWORD ASAP.

    -

    I also suggest you check out our guides at mail.p0ntus.com/guides.

    -

    You can also access Vaultwarden at vaultwarden.p0ntus.com.

    -

    If you need any help or support, contact admin@p0ntus.com.

    -

    Your webmail can be accessed here.

    -
    - <% } %> - <% if (request.status === 'Pending') { %> -

    Your request is pending approval. This page will be updated when your request been approved or denied.

    - <% } %> - <% if (request.status === 'Denied') { %> -

    Your request has been denied.

    -

    If you believe this is an error, please contact admin@p0ntus.com.

    -

    Please ensure the username you selected only includes letters, numbers, and periods/dashes. Your request may also be declined if you do not provide a valid reason or response in your application.

    -

    You may resubmit another request if you feel you deserve an email, or have fixed issues with your application.

    - <% } %> - <% } else { %> -

    No request found for the provided email.

    - <% } %> -
    -<%- include('shards/footer') %> \ No newline at end of file diff --git a/src/services.ejs b/src/services.ejs index 4b20b33..f46f9cc 100644 --- a/src/services.ejs +++ b/src/services.ejs @@ -44,7 +44,8 @@

    Upon creating your account, you will be allocated an account with the following:

    • 4000 MB storage (may vary)
    • -
    • Webmail
    • +
    • Roundcube Webmail
    • +
    • Contacts List
    • IMAP/SMTP access
    • Spam protection
    • 5 outgoing messages per hour
    • diff --git a/src/shards/nav.ejs b/src/shards/nav.ejs index cacb07b..2c0f95d 100644 --- a/src/shards/nav.ejs +++ b/src/shards/nav.ejs @@ -12,11 +12,7 @@ Services <% } %> Status - <% if (currentPage === 'register') { %> - Register - <% } else { %> - Register - <% } %> + Register <% if (currentPage === 'donate') { %> Donate <% } else { %> @@ -32,12 +28,4 @@ <% } else { %> Guides <% } %> - <% if (currentPage === 'request') { %> - My Request - <% } else { %> - My Request - <% } %> - <% if (currentPage === 'admin') { %> - Admin - <% } %> \ No newline at end of file