update to prepare for mailu migration
This commit is contained in:
parent
e926d6d3b3
commit
e31072ad6a
10
.env.example
10
.env.example
@ -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
|
235
app.js
235
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}`);
|
||||
|
@ -17,7 +17,7 @@
|
||||
"express": "^4.21.1",
|
||||
"express-session": "^1.18.1",
|
||||
"mariadb": "^3.4.0",
|
||||
"mysql2": "^3.11.5",
|
||||
"mysql2": "^3.12.0",
|
||||
"node-cache": "^5.1.2",
|
||||
"sequelize": "^6.37.5",
|
||||
"winston": "^3.17.0"
|
||||
|
@ -1,58 +0,0 @@
|
||||
<%- include('shards/header', { title: 'Admin Dashboard - p0ntus mail' }) %>
|
||||
<div class="container my-5">
|
||||
<div class="text-center mb-4">
|
||||
<h1 class="fw-bold">Welcome, <%= user %>!</h1>
|
||||
<p>You are viewing <b>all requests</b></p>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle table-hover">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Full Name</th>
|
||||
<th>Email</th>
|
||||
<th>Reason</th>
|
||||
<th>Telegram</th>
|
||||
<th>Status</th>
|
||||
<th>Update Status</th>
|
||||
<th>Delete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% requests.forEach(request => { %>
|
||||
<tr>
|
||||
<td><%= request.id %></td>
|
||||
<td><%= request.fullName %></td>
|
||||
<td><%= request.email %></td>
|
||||
<td><%= request.reason %></td>
|
||||
<td><%= request.telegram %></td>
|
||||
<td><%= request.status %></td>
|
||||
<td>
|
||||
<form action="/admin/update-status" method="POST" class="d-inline">
|
||||
<input type="hidden" name="id" value="<%= request.id %>">
|
||||
<select name="status" class="form-select form-select-sm">
|
||||
<option value="Pending" <% if (request.status === 'Pending') { %>selected<% } %>>Pending</option>
|
||||
<option value="Approved" <% if (request.status === 'Approved') { %>selected<% } %>>Approved</option>
|
||||
<option value="Denied" <% if (request.status === 'Denied') { %>selected<% } %>>Denied</option>
|
||||
</select>
|
||||
<button type="submit" class="btn btn-primary btn-sm mt-2">Update</button>
|
||||
</form>
|
||||
</td>
|
||||
<td>
|
||||
<a href="/admin/edit/<%= request.id %>" class="btn btn-warning btn-sm">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</a>
|
||||
<form action="/admin/delete-request" method="POST" class="d-inline">
|
||||
<input type="hidden" name="id" value="<%= request.id %>">
|
||||
<button type="submit" class="btn btn-danger btn-sm">
|
||||
<i class="bi bi-trash3"></i>
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<% }); %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<%- include('shards/footer') %>
|
@ -1,25 +0,0 @@
|
||||
<%- include('shards/header', { title: 'Edit Request - p0ntus mail' }) %>
|
||||
<div class="container my-5">
|
||||
<h2 class="mb-4">Edit Request</h2>
|
||||
<form action="/admin/edit" method="POST">
|
||||
<input type="hidden" name="id" value="<%= request.id %>">
|
||||
<div class="mb-3">
|
||||
<label for="fullName" class="form-label">Full Name</label>
|
||||
<input type="text" class="form-control" id="fullName" name="fullName" value="<%= request.fullName %>" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="email" class="form-label">Email</label>
|
||||
<input type="text" class="form-control" id="email" name="email" value="<%= request.email %>" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="reason" class="form-label">Reason</label>
|
||||
<textarea class="form-control" id="reason" name="reason" rows="3"><%= request.reason %></textarea>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="telegram" class="form-label">Telegram</label>
|
||||
<input type="text" class="form-control" id="telegram" name="telegram" value="<%= request.telegram %>">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Update</button>
|
||||
</form>
|
||||
</div>
|
||||
<%- include('shards/footer') %>
|
@ -1,21 +0,0 @@
|
||||
<%- include('../shards/header', { title: 'Admin - p0ntus mail' }) %>
|
||||
<div class="container">
|
||||
<%- include('../shards/nav', { currentPage: 'admin' }) %>
|
||||
<i class="il mt-5">Login to administration panel</i>
|
||||
<hr>
|
||||
<% if (error) { %>
|
||||
<div class="alert alert-danger"><%= error %></div>
|
||||
<% } %>
|
||||
<form action="/admin" method="POST">
|
||||
<div class="form-group mt-2">
|
||||
<label for="username">Username</label>
|
||||
<input type="text" class="form-control mt-1" id="username" name="username" required>
|
||||
</div>
|
||||
<div class="form-group mt-2">
|
||||
<label for="password">Password</label>
|
||||
<input type="password" class="form-control mt-1" id="password" name="password" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-dark mt-3">Login</button>
|
||||
</form>
|
||||
</div>
|
||||
<%- include('../shards/footer') %>
|
@ -1,4 +0,0 @@
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
|
||||
<script src="/js/admin.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -1,37 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title><%= title %></title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-icons/1.11.3/font/bootstrap-icons.min.css" integrity="sha512-dPXYcDub/aeb08c63jRq/k6GaKccl256JQy/AnOq7CAnEZ9FzSL9wSbcZkMp4R26vBsMLFYH4kQ67/bbV8XaCQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
<style>
|
||||
:root {
|
||||
--bg-color-light: #f9f9f9;
|
||||
--text-color-light: #333;
|
||||
--bg-color-dark: #1c1c1c;
|
||||
--text-color-dark: #fff;
|
||||
}
|
||||
body.light-mode {
|
||||
background-color: var(--bg-color-light);
|
||||
color: var(--text-color-light);
|
||||
}
|
||||
body.dark-mode {
|
||||
background-color: var(--bg-color-dark);
|
||||
color: var(--text-color-dark);
|
||||
}
|
||||
.mode-switch {
|
||||
cursor: pointer;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="light-mode">
|
||||
<nav id="nav" class="navbar navbar-expand-lg navbar-light bg-light px-4">
|
||||
<a class="navbar-brand" href="#">p0ntus Mail Admin</a>
|
||||
<div class="ms-auto">
|
||||
<span class="mode-switch" id="modeSwitch">
|
||||
<i id="iconSwitch" class="bi-moon text-black"></i>
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
@ -1,7 +0,0 @@
|
||||
<%- include('../shards/header', { title: '404 Not Found - p0ntus mail', currentPage: 'err' }) %>
|
||||
<div class="container">
|
||||
<i class="il mt-2">404 Not Found</i>
|
||||
<hr>
|
||||
<p>The requested resource could not be found.</p>
|
||||
</div>
|
||||
<%- include('../shards/footer') %>
|
@ -1,7 +0,0 @@
|
||||
<%- include('../shards/header', { title: '500 Internal Server Error - p0ntus mail', currentPage: 'err' }) %>
|
||||
<div class="container">
|
||||
<i class="il mt-2">500 Internal Server Error</i>
|
||||
<hr>
|
||||
<p>An unexpected error occurred. Please try again later.</p>
|
||||
</div>
|
||||
<%- include('../shards/footer') %>
|
@ -1,25 +0,0 @@
|
||||
<%- include('../shards/header', { title: 'Request Status - p0ntus mail', currentPage: 'err' }) %>
|
||||
<div class="container">
|
||||
<%- include('../shards/nav', { currentPage: 'request' }) %>
|
||||
<i class="il mt-5">We need your email</i>
|
||||
<hr>
|
||||
<p class="mt-4 mb-4">We need an email to check your request. Please enter your p0ntus mail email address below:</p>
|
||||
<form action="/request" method="post" onsubmit="return validateEmail()">
|
||||
<div class="form-group">
|
||||
<label class="mb-2" for="email">p0ntus mail email address:</label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" id="email" name="email" pattern="^[a-zA-Z0-9.\-]+$" required oninput="this.value = this.value.toLowerCase().replace(/\s/g, '')">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">@</span>
|
||||
</div>
|
||||
<select class="form-select" id="domain" name="domain" required>
|
||||
<% domains.forEach(domain => { %>
|
||||
<option value="<%= domain %>"><%= domain %></option>
|
||||
<% }); %>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-dark mt-3">Submit</button>
|
||||
</form>
|
||||
</div>
|
||||
<%- include('../shards/footer') %>
|
@ -1,7 +0,0 @@
|
||||
<%- include('../shards/header', { title: "Couldn't find that email - p0ntus mail", currentPage: 'err' }) %>
|
||||
<div class="container">
|
||||
<i class="il mt-2">We couldn't find that email</i>
|
||||
<hr>
|
||||
<p>We couldn't find a request under <b><%= email %>@<%= domain %></b>. Please try again later or try and register again.</p>
|
||||
</div>
|
||||
<%- include('../shards/footer') %>
|
@ -10,33 +10,20 @@
|
||||
<div class="row">
|
||||
<div class="col-md-6 text-start">
|
||||
<h5><i>If you aren't a current user</i></h5>
|
||||
<a href="/register" class="btn bg-dark text-white mt-2"><i class="fa-solid fa-user-plus ico-sm"></i> Register</a>
|
||||
<a href="/request" class="btn bg-dark text-white mt-2"><i class="fa-solid fa-person-circle-question ico-sm"></i> Check Registration Status</a>
|
||||
<a href="https://user.pontusmail.org/admin/user/signup" class="btn bg-dark text-white mt-2"><i class="fa-solid fa-user-plus ico-sm"></i> Register</a>
|
||||
</div>
|
||||
<div class="col-md-6 text-start">
|
||||
<h5><i>If you are a current user</i></h5>
|
||||
<a href="/SOGo" class="btn bg-dark text-white mt-2"><i class="fa-solid fa-envelope ico-sm"></i> Webmail</a>
|
||||
<a href="https://user.p0ntus.com" class="btn bg-dark text-white mt-2"><i class="fa-solid fa-user ico-sm"></i> Account</a>
|
||||
<a href="https://user.pontusmail.org/webmail/" class="btn bg-dark text-white mt-2"><i class="fa-solid fa-envelope ico-sm"></i> Webmail</a>
|
||||
<a href="https://user.pontusmail.org" class="btn bg-dark text-white mt-2"><i class="fa-solid fa-user ico-sm"></i> Account</a>
|
||||
<a href="https://vaultwarden.p0ntus.com" class="btn bg-dark text-white mt-2"><i class="fa-solid fa-key ico-sm"></i> Vaultwarden</a>
|
||||
<a href="/guides" class="btn bg-dark text-white mt-2"><i class="fa-solid fa-book ico-sm"></i> Guides</a>
|
||||
<a href="https://user.pontusmail.org/admin/client" class="btn bg-dark text-white mt-2"><i class="fa-solid fa-question-mark ico-sm"></i> Client Setup</a>
|
||||
</div>
|
||||
</div>
|
||||
<i class="il mt-5">Statistics</i>
|
||||
<hr>
|
||||
<div class="row mt-5">
|
||||
<div class="col-md-4 text-center">
|
||||
<h3><%= domainCount %></h3>
|
||||
<p>Domains Hosted</p>
|
||||
</div>
|
||||
<div class="col-md-4 text-center">
|
||||
<h3><%= accountCount %></h3>
|
||||
<p>Accounts</p>
|
||||
</div>
|
||||
<div class="col-md-4 text-center">
|
||||
<h3><%= totalData %></h3>
|
||||
<p>Total Data (MB)</p>
|
||||
</div>
|
||||
</div>
|
||||
<p>As we have migrated to a new email platform, we are currently rewriting this.</p>
|
||||
<small class="form-text text-muted mt-2">Please note all domains may not be available for registration.</small>
|
||||
</div>
|
||||
<%- include('shards/footer') %>
|
@ -5,17 +5,15 @@
|
||||
<hr>
|
||||
<p class="text-start"><b>Our system collects automatically:</b></p>
|
||||
<ul class="list-group text-start">
|
||||
<li class="list-group-item">Log files which may include the currently logged-in IP address. Log files are stored in memory, and Redis lists.</li>
|
||||
<li class="list-group-item">Last login time</li>
|
||||
<li class="list-group-item">Storage used by your account</li>
|
||||
<li class="list-group-item">Message count for your account</li>
|
||||
<li class="list-group-item">Last message received time</li>
|
||||
<li class="list-group-item">Account creation date</li>
|
||||
<li class="list-group-item">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.</li>
|
||||
<li class="list-group-item">Storage and disk quota used by your account</li>
|
||||
<li class="list-group-item">Account creation date (no time)</li>
|
||||
<li class="list-group-item">Linked external email addresses' folders, last check date, status, created date, users, and the ability to take actions (like you can on your dashboard).</li>
|
||||
<li class="list-group-item">Automatic reply settings</li>
|
||||
</ul>
|
||||
<p class="text-start mt-3"><b>What I collect by choice:</b></p>
|
||||
<ul class="list-group text-start">
|
||||
<li class="list-group-item">Email used at registration</li>
|
||||
<li class="list-group-item">Telegram account (if given at registration)</li>
|
||||
<li class="list-group-item">I do not collect any extra information at the moment</li>
|
||||
</ul>
|
||||
<p class="text-start mt-3"><b>What the admin has access to:</b></p>
|
||||
<ul class="list-group text-start">
|
||||
|
@ -1,8 +0,0 @@
|
||||
<%- include('shards/header', { title: 'Registration Successful - p0ntus mail' }) %>
|
||||
<div class="container">
|
||||
<%- include('shards/nav', { currentPage: 'register' }) %>
|
||||
<i class="il mt-5">Registration Submitted</i>
|
||||
<hr>
|
||||
<p>Your request has been submitted successfully. You can check the status of your request <a href="/request">here</a>.</p>
|
||||
</div>
|
||||
<%- include('shards/footer') %>
|
@ -1,46 +0,0 @@
|
||||
<%- include('shards/header', { title: 'Register - p0ntus mail', currentPage: 'register' }) %>
|
||||
<div class="container">
|
||||
<%- include('shards/nav', { currentPage: 'register' }) %>
|
||||
<h1 class="mt-5">Register</h1>
|
||||
<i class="il mt-5">If you already filled out a registration request</i>
|
||||
<hr>
|
||||
<div class="text-center">
|
||||
<a href="/request" class="btn bg-dark text-white mt-2">
|
||||
<i class="fa-solid fa-person-circle-question ico-sm"></i> Check Registration Status
|
||||
</a>
|
||||
</div>
|
||||
<i class="il mt-5">If you haven't filled out a registration request</i>
|
||||
<hr>
|
||||
<p class="mt-3"><b>Do not use this service for spam. It is a waste of your time.</b> I have added protections to prevent spam, including sending quotas per hour. I will catch you before you can send a good enough amount.</p>
|
||||
<form action="/register" method="POST">
|
||||
<div class="form-group mb-3">
|
||||
<label for="fullName" class="mb-2">Name that goes in email header (full name/username/alias)</label>
|
||||
<input type="text" class="form-control" id="fullName" name="fullName" required>
|
||||
</div>
|
||||
<div class="form-group mb-3">
|
||||
<label for="email" class="mb-2">Desired email address (e.g., yourname@p0ntus.com) - <b>Do not enter your current email in this box</b></label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" id="email" name="email" pattern="^[a-zA-Z0-9.-]+$" required oninput="this.value = this.value.toLowerCase().replace(/\s/g, '')">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">@</span>
|
||||
</div>
|
||||
<select class="form-select" id="domain" name="domain" required>
|
||||
<% domains.forEach(domain => { %>
|
||||
<option value="<%= domain %>"><%= domain %></option>
|
||||
<% }); %>
|
||||
</select>
|
||||
</div>
|
||||
<small class="form-text text-muted">Only letters, numbers, periods, and dashes are allowed.</small>
|
||||
</div>
|
||||
<div class="form-group mb-3">
|
||||
<label for="reason" class="mb-2">Reason for wanting an email (at least one full sentence)</label>
|
||||
<textarea class="form-control" id="reason" name="reason" rows="3" required></textarea>
|
||||
</div>
|
||||
<div class="form-group mb-3">
|
||||
<label for="telegram" class="mb-2">Telegram username</label>
|
||||
<input type="text" class="form-control" id="telegram" name="telegram" value="@" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-dark mt-3"><i class="fa-solid fa-user-plus ico-sm"></i> Register</button>
|
||||
</form>
|
||||
</div>
|
||||
<%- include('shards/footer') %>
|
@ -1,51 +0,0 @@
|
||||
<%- include('shards/header', { title: 'Request Status - p0ntus mail', currentPage: 'request' }) %>
|
||||
<div class="container">
|
||||
<%- include('shards/nav', { currentPage: 'request' }) %>
|
||||
<i class="il mt-5">Request Status</i>
|
||||
<hr>
|
||||
<form action="/request" method="POST">
|
||||
<div class="form-group mb-3">
|
||||
<label for="email" class="mb-2">Email</label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" id="email" name="email" pattern="^[a-zA-Z0-9.-]+$" required oninput="this.value = this.value.toLowerCase().replace(/\s/g, '')">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">@</span>
|
||||
</div>
|
||||
<select class="form-select" id="domain" name="domain" required>
|
||||
<% domains.forEach(domain => { %>
|
||||
<option value="<%= domain %>"><%= domain %></option>
|
||||
<% }); %>
|
||||
</select>
|
||||
</div>
|
||||
<small class="form-text text-muted">Only letters, numbers, periods, and dashes are allowed.</small>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-dark mt-3"><i class="fa-solid fa-search ico-sm"></i> Check Status</button>
|
||||
</form>
|
||||
|
||||
<% if (request) { %>
|
||||
<hr class="mt-4" />
|
||||
<p>Email: <strong><%= request.email %></strong></p>
|
||||
<p>Request Status: <strong><%= request.status %></strong></p>
|
||||
<% if (request.status === 'Approved') { %>
|
||||
<div class="text-start">
|
||||
<p>Your request has been approved. You can access your p0ntus mail account <a href="https://user.p0ntus.com/">here</a> with your email as the username and abcabc for the password. <b>FOR SECURITY, CHANGE YOUR PASSWORD ASAP.</b></p>
|
||||
<p>I also suggest you check out our guides at <a href="https://mail.p0ntus.com/guides">mail.p0ntus.com/guides</a>.</p>
|
||||
<p>You can also access Vaultwarden at <a href="https://vaultwarden.p0ntus.com/">vaultwarden.p0ntus.com</a>.</p>
|
||||
<p>If you need any help or support, contact <a href="mailto:admin@p0ntus.com">admin@p0ntus.com</a>.</p>
|
||||
<p>Your webmail can be accessed <a href="https://mail.p0ntus.com/SOGo">here</a>.</p>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if (request.status === 'Pending') { %>
|
||||
<p>Your request is pending approval. This page will be updated when your request been approved or denied.</p>
|
||||
<% } %>
|
||||
<% if (request.status === 'Denied') { %>
|
||||
<p>Your request has been denied.</p>
|
||||
<p>If you believe this is an error, please contact <a href="mailto:admin@p0ntus.com">admin@p0ntus.com</a>.</p>
|
||||
<p>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.</p>
|
||||
<p>You may resubmit another request if you feel you deserve an email, or have fixed issues with your application.</p>
|
||||
<% } %>
|
||||
<% } else { %>
|
||||
<p>No request found for the provided email.</p>
|
||||
<% } %>
|
||||
</div>
|
||||
<%- include('shards/footer') %>
|
@ -44,7 +44,8 @@
|
||||
<p>Upon creating your account, you will be allocated an account with the following:</p>
|
||||
<ul class="list-group text-start">
|
||||
<li class="list-group-item">4000 MB storage (may vary)</li>
|
||||
<li class="list-group-item">Webmail</li>
|
||||
<li class="list-group-item">Roundcube Webmail</li>
|
||||
<li class="list-group-item">Contacts List</li>
|
||||
<li class="list-group-item">IMAP/SMTP access</li>
|
||||
<li class="list-group-item">Spam protection</li>
|
||||
<li class="list-group-item">5 outgoing messages per hour</li>
|
||||
|
@ -12,11 +12,7 @@
|
||||
<a href="/services" class="nav-link text-dark">Services</a>
|
||||
<% } %>
|
||||
<a href="https://status.p0ntus.com/" class="nav-link text-dark">Status</a>
|
||||
<% if (currentPage === 'register') { %>
|
||||
<span class="nav-link text-dark"><b>Register</b></span>
|
||||
<% } else { %>
|
||||
<a href="/register" class="nav-link text-dark">Register</a>
|
||||
<% } %>
|
||||
<a href="https://user.pontusmail.org/admin/user/signup" class="nav-link text-dark">Register</a>
|
||||
<% if (currentPage === 'donate') { %>
|
||||
<span class="nav-link text-dark"><b>Donate</b></span>
|
||||
<% } else { %>
|
||||
@ -32,12 +28,4 @@
|
||||
<% } else { %>
|
||||
<a href="/guides" class="nav-link text-dark">Guides</a>
|
||||
<% } %>
|
||||
<% if (currentPage === 'request') { %>
|
||||
<span class="nav-link text-dark"><b>My Request</b></span>
|
||||
<% } else { %>
|
||||
<a href="/request" class="nav-link text-dark">My Request</a>
|
||||
<% } %>
|
||||
<% if (currentPage === 'admin') { %>
|
||||
<span class="nav-link text-dark"><b>Admin</b></span>
|
||||
<% } %>
|
||||
</nav>
|
Reference in New Issue
Block a user