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:
parent
03f439590a
commit
0e4774844a
@ -1,4 +1,4 @@
|
|||||||
FROM node:20
|
FROM node:22
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
COPY package*.json ./
|
COPY package*.json ./
|
||||||
RUN npm install --only=production
|
RUN npm install --only=production
|
||||||
|
@ -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`.
|
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
7
app.js
@ -4,7 +4,6 @@ const path = require('path');
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const session = require('express-session');
|
const session = require('express-session');
|
||||||
const { Sequelize, DataTypes } = require('sequelize');
|
const { Sequelize, DataTypes } = require('sequelize');
|
||||||
const { error } = require('console');
|
|
||||||
|
|
||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
const app = express();
|
const app = express();
|
||||||
@ -101,12 +100,15 @@ app.get('/register', (req, res) => {
|
|||||||
|
|
||||||
app.post('/register', async (req, res) => {
|
app.post('/register', async (req, res) => {
|
||||||
const { fullName, email, reason, telegram } = req.body;
|
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 });
|
await Request.create({ fullName, email, reason, telegram });
|
||||||
res.render('reg-success', { currentPage: 'register' });
|
res.render('reg-success', { currentPage: 'register' });
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/request', async (req, res) => {
|
app.get('/request', async (req, res) => {
|
||||||
console.log("Got /request");
|
|
||||||
const { email } = req.query;
|
const { email } = req.query;
|
||||||
|
|
||||||
if (!email) {
|
if (!email) {
|
||||||
@ -167,6 +169,7 @@ app.post('/admin/delete-request', checkAdminAuth, async (req, res) => {
|
|||||||
res.redirect('/admin/dashboard');
|
res.redirect('/admin/dashboard');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Start server on 3000
|
||||||
app.listen(3000, () => {
|
app.listen(3000, () => {
|
||||||
console.log('Server started on port 3000');
|
console.log('Server started on port 3000');
|
||||||
});
|
});
|
@ -1,8 +1,8 @@
|
|||||||
function copyToClipboard(elementId) {
|
function copyToClipboard(elementId) {
|
||||||
const text = document.getElementById(elementId).innerText;
|
const text = document.getElementById(elementId).innerText;
|
||||||
navigator.clipboard.writeText(text).then(() => {
|
navigator.clipboard.writeText(text).then(() => {
|
||||||
alert('Copied to clipboard');
|
alert('Copied to clipboard');
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.error('Failed to copy: ', err);
|
console.error('Failed to copy: ', err);
|
||||||
});
|
});
|
||||||
}
|
}
|
9
public/js/register.js
Normal file
9
public/js/register.js
Normal 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;
|
||||||
|
}
|
@ -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">
|
<div class="container">
|
||||||
<i class="il mt-2">404 Not Found</i>
|
<i class="il mt-2">404 Not Found</i>
|
||||||
<hr>
|
<hr>
|
||||||
|
@ -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">
|
<div class="container">
|
||||||
<i class="il mt-2">500 Internal Server Error</i>
|
<i class="il mt-2">500 Internal Server Error</i>
|
||||||
<hr>
|
<hr>
|
||||||
|
@ -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">
|
<div class="container">
|
||||||
<i class="il mt-2">We need your email</i>
|
<i class="il mt-2">We need your email</i>
|
||||||
<hr>
|
<hr>
|
||||||
|
@ -10,26 +10,33 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<i class="il mt-5">If you haven't filled out a registration request</i>
|
<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>
|
<hr>
|
||||||
<form action="/register" method="POST">
|
<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>
|
||||||
<div class="form-group">
|
<form action="/register" method="POST" onsubmit="return validateEmail()">
|
||||||
<label for="fullName">Name that goes in email header (full name/username/alias)</label>
|
<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>
|
<input type="text" class="form-control" id="fullName" name="fullName" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group mb-3">
|
||||||
<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>
|
<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>
|
||||||
<input type="email" class="form-control" id="email" name="email" required>
|
<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>
|
||||||
<div class="form-group">
|
<div class="form-group mb-3">
|
||||||
<label for="reason" class="mt-1">Reason for wanting an email (at least one full sentence)</label>
|
<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>
|
<textarea class="form-control" id="reason" name="reason" rows="3" required></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group mb-3">
|
||||||
<label for="telegram" class="mt-1">Telegram username</label>
|
<label for="telegram" class="mb-2">Telegram username</label>
|
||||||
<input type="text" class="form-control" id="telegram" name="telegram" required>
|
<input type="text" class="form-control" id="telegram" name="telegram" value="@" required>
|
||||||
</div>
|
</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>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
<script src="/js/register.js"></script>
|
||||||
<%- include('shards/footer') %>
|
<%- include('shards/footer') %>
|
Reference in New Issue
Block a user