implement validation of email and password, ratelimiting, add ci for builds
This commit is contained in:
parent
edc18c2c18
commit
acefa334a5
30
.gitea/workflows/docker.yml
Normal file
30
.gitea/workflows/docker.yml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
name: Build and Push Docker Image
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build_and_push:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout Code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Log in to Gitea Package Registry
|
||||||
|
run: echo "${{ secrets.PACKAGE_TOKEN }}" | docker login $SERVER_URL -u $USERNAME --password-stdin
|
||||||
|
env:
|
||||||
|
SERVER_URL: ${{ secrets.SERVER_URL }}
|
||||||
|
USERNAME: ${{ secrets.USERNAME }}
|
||||||
|
PACKAGE_TOKEN: ${{ secrets.PACKAGE_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build Docker Image
|
||||||
|
run: docker build -t git.pontusmail.org/librecloud/mail-connect:latest .
|
||||||
|
|
||||||
|
- name: Push Docker Image
|
||||||
|
run: docker push git.pontusmail.org/librecloud/mail-connect:latest
|
@ -11,7 +11,10 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"child_process": "^1.0.2",
|
"child_process": "^1.0.2",
|
||||||
"dockerode": "^4.0.4",
|
"dockerode": "^4.0.4",
|
||||||
"express": "^4.21.2"
|
"express": "^4.21.2",
|
||||||
|
"express-rate-limit": "^7.5.0",
|
||||||
|
"password-validator": "^5.3.0",
|
||||||
|
"validator": "^13.12.0"
|
||||||
},
|
},
|
||||||
"trustedDependencies": [
|
"trustedDependencies": [
|
||||||
"protobufjs"
|
"protobufjs"
|
||||||
|
10
ratelimit.json
Normal file
10
ratelimit.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"/list": {
|
||||||
|
"windowMs": 60000,
|
||||||
|
"max": 20
|
||||||
|
},
|
||||||
|
"/add": {
|
||||||
|
"windowMs": 60000,
|
||||||
|
"max": 10
|
||||||
|
}
|
||||||
|
}
|
49
server.js
49
server.js
@ -1,10 +1,53 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
|
const fs = require('fs');
|
||||||
|
const rateLimit = require('express-rate-limit');
|
||||||
const Docker = require('dockerode');
|
const Docker = require('dockerode');
|
||||||
|
const validator = require('validator');
|
||||||
|
|
||||||
const docker = new Docker({ socketPath: '/var/run/docker.sock' });
|
const docker = new Docker({ socketPath: '/var/run/docker.sock' });
|
||||||
const app = express();
|
const app = express();
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
|
||||||
|
// Rate limiting
|
||||||
|
|
||||||
|
let rateLimitConfig = {};
|
||||||
|
try {
|
||||||
|
const data = fs.readFileSync('./ratelimit.json', 'utf8');
|
||||||
|
rateLimitConfig = JSON.parse(data);
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error loading rate limit config:', err);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createLimiter(options) {
|
||||||
|
return rateLimit({
|
||||||
|
windowMs: options.windowMs,
|
||||||
|
max: options.max,
|
||||||
|
message: "Too many requests, please try again another time.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rateLimitConfig['/list']) {
|
||||||
|
app.use('/list', createLimiter(rateLimitConfig['/list']));
|
||||||
|
}
|
||||||
|
if (rateLimitConfig['/add']) {
|
||||||
|
app.use('/add', createLimiter(rateLimitConfig['/add']));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utility fxns
|
||||||
|
|
||||||
|
function validateEmail(email) {
|
||||||
|
return typeof email === 'string' && validator.isEmail(email);
|
||||||
|
}
|
||||||
|
|
||||||
|
const PasswordValidator = require('password-validator');
|
||||||
|
const passwordSchema = new PasswordValidator();
|
||||||
|
passwordSchema
|
||||||
|
.is().min(8)
|
||||||
|
.is().max(64)
|
||||||
|
.has().letters()
|
||||||
|
.has().digits()
|
||||||
|
.has().not().spaces();
|
||||||
|
|
||||||
function listAccounts() {
|
function listAccounts() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const container = docker.getContainer('mailserver');
|
const container = docker.getContainer('mailserver');
|
||||||
@ -49,6 +92,8 @@ function listAccounts() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Routes
|
||||||
|
|
||||||
app.get('/list', (req, res) => {
|
app.get('/list', (req, res) => {
|
||||||
listAccounts()
|
listAccounts()
|
||||||
.then(accounts => res.json({ accounts }))
|
.then(accounts => res.json({ accounts }))
|
||||||
@ -57,8 +102,8 @@ app.get('/list', (req, res) => {
|
|||||||
|
|
||||||
app.post('/add', (req, res) => {
|
app.post('/add', (req, res) => {
|
||||||
const { email, password } = req.body;
|
const { email, password } = req.body;
|
||||||
if (!email || !password) {
|
if (!email || !validateEmail(email) || !password) {
|
||||||
return res.status(400).json({ error: "Email and password are required." });
|
return res.status(400).json({ error: "A valid email and password is required." });
|
||||||
}
|
}
|
||||||
|
|
||||||
const container = docker.getContainer('mailserver');
|
const container = docker.getContainer('mailserver');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user