fix error page errors (ironic), improve registration process and secure on backend, remove forgotten testing output, add todo, bump nodejs to 22

This commit is contained in:
Aidan 2024-12-27 03:37:32 -06:00
parent 03f439590a
commit 0e4774844a
No known key found for this signature in database
GPG Key ID: 1773A01F0EFE4FC1
9 changed files with 48 additions and 25 deletions

View File

@ -1,4 +1,4 @@
FROM node:20
FROM node:22
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --only=production

View File

@ -60,3 +60,7 @@ You can also use Docker to self-host pontus-mail's frontend. Make sure you have
```
You will now have a fully functioning Node.js Express server, which will be running on the port specified in `docker-compose.yml`, and internally on port `3000`.
# To-Do
- [ ] Port to NextJS?
- [ ] Hovering effects for buttons

7
app.js
View File

@ -4,7 +4,6 @@ const path = require('path');
const fs = require('fs');
const session = require('express-session');
const { Sequelize, DataTypes } = require('sequelize');
const { error } = require('console');
require('dotenv').config();
const app = express();
@ -101,12 +100,15 @@ app.get('/register', (req, res) => {
app.post('/register', async (req, res) => {
const { fullName, email, 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');
}
await Request.create({ fullName, email, reason, telegram });
res.render('reg-success', { currentPage: 'register' });
});
app.get('/request', async (req, res) => {
console.log("Got /request");
const { email } = req.query;
if (!email) {
@ -167,6 +169,7 @@ app.post('/admin/delete-request', checkAdminAuth, async (req, res) => {
res.redirect('/admin/dashboard');
});
// Start server on 3000
app.listen(3000, () => {
console.log('Server started on port 3000');
});

View File

@ -1,8 +1,8 @@
function copyToClipboard(elementId) {
const text = document.getElementById(elementId).innerText;
navigator.clipboard.writeText(text).then(() => {
alert('Copied to clipboard');
}).catch(err => {
console.error('Failed to copy: ', err);
});
const text = document.getElementById(elementId).innerText;
navigator.clipboard.writeText(text).then(() => {
alert('Copied to clipboard');
}).catch(err => {
console.error('Failed to copy: ', err);
});
}

9
public/js/register.js Normal file
View File

@ -0,0 +1,9 @@
function validateEmail() {
const email = document.getElementById('email').value;
const regex = /^[a-zA-Z0-9.-]+$/;
if (!regex.test(email)) {
alert('An invalid email has been entered. You may only include letters, numbers, periods, and dashes. Make sure you do not include @p0ntus.com');
return false;
}
return true;
}

View File

@ -1,4 +1,4 @@
<%- include('../shards/header', { title: '404 Not Found - p0ntus mail' }) %>
<%- include('../shards/header', { title: '404 Not Found - p0ntus mail', currentPage: 'err' }) %>
<div class="container">
<i class="il mt-2">404 Not Found</i>
<hr>

View File

@ -1,4 +1,4 @@
<%- include('../shards/header', { title: '500 Internal Server Error - p0ntus mail' }) %>
<%- 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>

View File

@ -1,4 +1,4 @@
<%- include('../shards/header', { title: 'Request Status - p0ntus mail' }) %>
<%- include('../shards/header', { title: 'Request Status - p0ntus mail', currentPage: 'err' }) %>
<div class="container">
<i class="il mt-2">We need your email</i>
<hr>

View File

@ -10,26 +10,33 @@
</a>
</div>
<i class="il mt-5">If you haven't filled out a registration request</i>
<p class="mt-2"><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>
<hr>
<form action="/register" method="POST">
<div class="form-group">
<label for="fullName">Name that goes in email header (full name/username/alias)</label>
<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" onsubmit="return validateEmail()">
<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">
<label for="email" class="mt-1">Desired email address (e.g., yourname<b>@p0ntus.com</b>) - <b>Do not enter your current email in this box</b></label>
<input type="email" class="form-control" id="email" name="email" required>
<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-append">
<span class="input-group-text">@p0ntus.com</span>
</div>
</div>
<small class="form-text text-muted">Only letters, numbers, periods, and dashes are allowed.</small>
</div>
<div class="form-group">
<label for="reason" class="mt-1">Reason for wanting an email (at least one full sentence)</label>
<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">
<label for="telegram" class="mt-1">Telegram username</label>
<input type="text" class="form-control" id="telegram" name="telegram" required>
<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">Register</button>
<button type="submit" class="btn btn-dark mt-3"><i class="fa-solid fa-user-plus ico-sm"></i> Register</button>
</form>
</div>
<script src="/js/register.js"></script>
<%- include('shards/footer') %>