- aggiunto componenti per Home Template... ma ancora da provare
- sistemato catprods - Sistemato menu
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
DATABASE=test_FreePlanet
|
||||
DATABASE=test_PiuCheBuono
|
||||
UDB=paofreeplanet
|
||||
PDB=mypassword@1A
|
||||
SEND_EMAIL=0
|
||||
SEND_EMAIL_ORDERS=1
|
||||
PORT=3000
|
||||
appTelegram_TEST=["1","13"]
|
||||
appTelegram=["1","13"]
|
||||
appTelegram_DEVELOP=["13"]
|
||||
appTelegram_TEST=["1","17"]
|
||||
appTelegram=["1","17"]
|
||||
appTelegram_DEVELOP=["17"]
|
||||
DOMAIN=mongodb://localhost:27017/
|
||||
AUTH_MONGODB=0
|
||||
ENABLE_PUSHNOTIFICATION=1
|
||||
@@ -29,7 +29,7 @@ GCM_API_KEY=""
|
||||
PROD=0
|
||||
PROJECT_DESCR_MAIN='__PROJECTS'
|
||||
SECRK=Askb38v23jjDFaoskBOWj92axXCQ
|
||||
TOKEN_LIFE=1m
|
||||
TOKEN_LIFE=2h
|
||||
REFRESH_TOKEN_LIFE=14d
|
||||
FTPSERVER_HOST=139.162.166.31
|
||||
FTPSERVER_PORT=21
|
||||
@@ -38,4 +38,9 @@ FTPSERVER_PWD=ftpmypwd@1A_
|
||||
AUTH_NEW_SITES=123123123
|
||||
SCRIPTS_DIR=admin_scripts
|
||||
CLOUDFLARE_TOKENS=[{"label":"Paolo.arena77@gmail.com","value":"M9EM309v8WFquJKpYgZCw-TViM2wX6vB3wlK6GD0"},{"label":"gruppomacro.com","value":"bqmzGShoX7WqOBzkXocoECyBkPq3GfqcM5t6VFd8"}]
|
||||
MIAB_HOST=box.lamiaposta.org
|
||||
MIAB_ADMIN_EMAIL=admin@lamiaposta.org
|
||||
MIAB_ADMIN_PASSWORD=passpao1pabox@1A
|
||||
DS_API_KEY="sk-222e3addb3d8455d8b0516d93906eec7"
|
||||
SERVER_A_URL="http://51.77.156.69:3000"
|
||||
API_KEY_MSSQL="m68yADSr123MIVIDA@154$DSAGVOK"
|
||||
@@ -33,6 +33,7 @@
|
||||
"express": "^4.21.2",
|
||||
"formidable": "^3.5.2",
|
||||
"ghostscript4js": "^3.2.3",
|
||||
"helmet": "^8.1.0",
|
||||
"i18n": "^0.15.1",
|
||||
"image-downloader": "^4.3.0",
|
||||
"internet-available": "^1.0.0",
|
||||
@@ -42,6 +43,7 @@
|
||||
"lodash": "^4.17.21",
|
||||
"mongodb": "^6.14.2",
|
||||
"mongoose": "^8.12.1",
|
||||
"morgan": "^1.10.1",
|
||||
"multer": "^1.4.5-lts.2",
|
||||
"mysql": "^2.18.1",
|
||||
"node-cron": "^3.0.3",
|
||||
|
||||
46
src/server/controllers/events.controller.js
Normal file
46
src/server/controllers/events.controller.js
Normal file
@@ -0,0 +1,46 @@
|
||||
// @ts-check
|
||||
const EventModel = require('../models/Event');
|
||||
const { pick } = require('../utils/pick');
|
||||
|
||||
async function listEvents(req, res) {
|
||||
const { limit = '6', page = '1', from, to, sort = 'start' } = /** @type {any} */ (req.query);
|
||||
const q = {};
|
||||
if (from) q.start = { ...(q.start || {}), $gte: new Date(from) };
|
||||
if (to) q.start = { ...(q.start || {}), $lte: new Date(to) };
|
||||
|
||||
const lim = Math.min(Number(limit) || 6, 50);
|
||||
const skip = (Math.max(Number(page) || 1, 1) - 1) * lim;
|
||||
|
||||
const [items, total] = await Promise.all([
|
||||
EventModel.find(q)
|
||||
.sort({ [sort]: 1 })
|
||||
.skip(skip)
|
||||
.limit(lim)
|
||||
.lean(),
|
||||
EventModel.countDocuments(q),
|
||||
]);
|
||||
|
||||
res.set('Cache-Control', 'public, max-age=30, stale-while-revalidate=120');
|
||||
return res.json({ items, total, page: Number(page), limit: lim });
|
||||
}
|
||||
|
||||
async function createEvent(req, res) {
|
||||
const data = pick(req.body, ['title', 'start', 'end', 'place', 'teaser', 'cover', 'to']);
|
||||
const doc = await EventModel.create(data);
|
||||
return res.status(201).json(doc);
|
||||
}
|
||||
|
||||
async function updateEvent(req, res) {
|
||||
const data = pick(req.body, ['title', 'start', 'end', 'place', 'teaser', 'cover', 'to']);
|
||||
const doc = await EventModel.findByIdAndUpdate(req.params.id, data, { new: true });
|
||||
if (!doc) return res.status(404).json({ message: 'Evento non trovato' });
|
||||
return res.json(doc);
|
||||
}
|
||||
|
||||
async function deleteEvent(req, res) {
|
||||
const r = await EventModel.findByIdAndDelete(req.params.id);
|
||||
if (!r) return res.status(404).json({ message: 'Evento non trovato' });
|
||||
return res.status(204).send();
|
||||
}
|
||||
|
||||
module.exports = { listEvents, createEvent, updateEvent, deleteEvent };
|
||||
18
src/server/controllers/home.controller.js
Normal file
18
src/server/controllers/home.controller.js
Normal file
@@ -0,0 +1,18 @@
|
||||
// @ts-check
|
||||
const { HomeModel } = require('../models/Home');
|
||||
|
||||
async function getHome(req, res) {
|
||||
const doc = await HomeModel.findOne({});
|
||||
if (!doc) return res.status(404).json({ message: 'Home non configurata' });
|
||||
res.set('Cache-Control', 'public, max-age=60, stale-while-revalidate=300');
|
||||
res.set('ETag', `"${doc.updatedAt?.getTime?.() || Date.now()}"`);
|
||||
return res.json(doc);
|
||||
}
|
||||
|
||||
async function upsertHome(req, res) {
|
||||
const payload = req.body || {};
|
||||
const doc = await HomeModel.findOneAndUpdate({}, payload, { upsert: true, new: true, setDefaultsOnInsert: true });
|
||||
return res.json(doc);
|
||||
}
|
||||
|
||||
module.exports = { getHome, upsertHome };
|
||||
20
src/server/controllers/newsletter.controller.js
Normal file
20
src/server/controllers/newsletter.controller.js
Normal file
@@ -0,0 +1,20 @@
|
||||
// @ts-check
|
||||
async function subscribe(req, res) {
|
||||
const { email } = req.body || {};
|
||||
if (!email || !/.+@.+\..+/.test(email)) {
|
||||
return res.status(400).json({ message: 'Email non valida' });
|
||||
}
|
||||
// Integra qui Mailchimp/Sendinblue se necessario
|
||||
return res.status(200).json({ ok: true });
|
||||
}
|
||||
|
||||
async function unsubscribe(req, res) {
|
||||
const { email } = req.body || {};
|
||||
if (!email || !/.+@.+\..+/.test(email)) {
|
||||
return res.status(400).json({ message: 'Email non valida' });
|
||||
}
|
||||
// Integra qui Mailchimp/Sendinblue se necessario
|
||||
return res.status(200).json({ ok: true });
|
||||
}
|
||||
|
||||
module.exports = { subscribe, unsubscribe };
|
||||
41
src/server/controllers/posts.controller.js
Normal file
41
src/server/controllers/posts.controller.js
Normal file
@@ -0,0 +1,41 @@
|
||||
// @ts-check
|
||||
const { PostModel } = require('../models/Post');
|
||||
const { pick } = require('../utils/pick');
|
||||
|
||||
async function listPosts(req, res) {
|
||||
const { limit = '3', page = '1', sort = '-date', category } = /** @type {any} */ (req.query);
|
||||
const q = {};
|
||||
if (category) q.category = category;
|
||||
|
||||
const lim = Math.min(Number(limit) || 3, 50);
|
||||
const skip = (Math.max(Number(page) || 1, 1) - 1) * lim;
|
||||
|
||||
const [items, total] = await Promise.all([
|
||||
PostModel.find(q).sort(sort).skip(skip).limit(lim).lean(),
|
||||
PostModel.countDocuments(q)
|
||||
]);
|
||||
|
||||
res.set('Cache-Control', 'public, max-age=30, stale-while-revalidate=120');
|
||||
return res.json({ items, total, page: Number(page), limit: lim });
|
||||
}
|
||||
|
||||
async function createPost(req, res) {
|
||||
const data = pick(req.body, ['title','date','category','teaser','cover','to','bodyMd']);
|
||||
const doc = await PostModel.create(data);
|
||||
return res.status(201).json(doc);
|
||||
}
|
||||
|
||||
async function updatePost(req, res) {
|
||||
const data = pick(req.body, ['title','date','category','teaser','cover','to','bodyMd']);
|
||||
const doc = await PostModel.findByIdAndUpdate(req.params.id, data, { new: true });
|
||||
if (!doc) return res.status(404).json({ message: 'Post non trovato' });
|
||||
return res.json(doc);
|
||||
}
|
||||
|
||||
async function deletePost(req, res) {
|
||||
const r = await PostModel.findByIdAndDelete(req.params.id);
|
||||
if (!r) return res.status(404).json({ message: 'Post non trovato' });
|
||||
return res.status(204).send();
|
||||
}
|
||||
|
||||
module.exports = { listPosts, createPost, updatePost, deletePost };
|
||||
10
src/server/db/connect.js
Normal file
10
src/server/db/connect.js
Normal file
@@ -0,0 +1,10 @@
|
||||
// @ts-check
|
||||
const mongoose = require('mongoose');
|
||||
const { env } = require('../config/env');
|
||||
|
||||
export async function connectDB() {
|
||||
if (mongoose.connection.readyState === 1) return;
|
||||
mongoose.set('strictQuery', true);
|
||||
await mongoose.connect(env.MONGO_URI);
|
||||
console.log('[mongo] connected');
|
||||
}
|
||||
59
src/server/db/seed.js
Normal file
59
src/server/db/seed.js
Normal file
@@ -0,0 +1,59 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const url = require('url');
|
||||
// const { connectDB } = require('./connect');
|
||||
const { HomeModel } = require('../models/Home');
|
||||
const { EventModel } = require('../models/Event');
|
||||
const { PostModel } = require('../models/Post');
|
||||
|
||||
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
|
||||
|
||||
async function run() {
|
||||
// await connectDB();
|
||||
|
||||
// Adatta il percorso se frontend e backend sono separati
|
||||
const samplePath = path.resolve(__dirname, '../../../src/server/mocks/home.sample.json');
|
||||
const raw = fs.readFileSync(samplePath, 'utf-8');
|
||||
const json = JSON.parse(raw);
|
||||
|
||||
// Home snapshot
|
||||
await HomeModel.deleteMany({});
|
||||
await HomeModel.create({
|
||||
hero: json.hero,
|
||||
pillars: json.pillars,
|
||||
testimonials: json.testimonials,
|
||||
gallery: json.gallery,
|
||||
faq: json.faq,
|
||||
partners: json.partners,
|
||||
posts: json.posts
|
||||
});
|
||||
|
||||
// Events
|
||||
await EventModel.deleteMany({});
|
||||
await EventModel.insertMany(json.events.map((e) => ({
|
||||
title: e.title,
|
||||
start: new Date(e.start),
|
||||
end: e.end ? new Date(e.end) : undefined,
|
||||
place: e.place,
|
||||
teaser: e.teaser,
|
||||
cover: e.cover,
|
||||
to: e.to
|
||||
})));
|
||||
|
||||
// Posts
|
||||
await PostModel.deleteMany({});
|
||||
await PostModel.insertMany(json.posts.map((p) => ({
|
||||
title: p.title,
|
||||
date: new Date(p.date),
|
||||
category: p.category,
|
||||
teaser: p.teaser,
|
||||
cover: p.cover,
|
||||
to: p.to,
|
||||
bodyMd: `# ${p.title}\n\n${p.teaser}\n`
|
||||
})));
|
||||
|
||||
console.log('[seed] done');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
run().catch((e) => { console.error(e); process.exit(1); });
|
||||
6
src/server/middleware/asyncHandler.js
Normal file
6
src/server/middleware/asyncHandler.js
Normal file
@@ -0,0 +1,6 @@
|
||||
// @ts-check
|
||||
const ah = (fn) => (req, res, next) =>
|
||||
Promise.resolve(fn(req, res, next)).catch((err) => next(err));
|
||||
|
||||
|
||||
module.exports = { ah };
|
||||
13
src/server/middleware/error.js
Normal file
13
src/server/middleware/error.js
Normal file
@@ -0,0 +1,13 @@
|
||||
// @ts-check
|
||||
function notFound(_req, res) {
|
||||
res.status(404).json({ message: 'Not Found' });
|
||||
}
|
||||
|
||||
function errorHandler(err, _req, res, _next) {
|
||||
const status = err.status || 500;
|
||||
const message = err.message || 'Server Error';
|
||||
if (status >= 500) console.error(err);
|
||||
res.status(status).json({ message });
|
||||
}
|
||||
|
||||
module.exports = { notFound, errorHandler };
|
||||
21
src/server/middleware/rateLimit.js
Normal file
21
src/server/middleware/rateLimit.js
Normal file
@@ -0,0 +1,21 @@
|
||||
// @ts-check
|
||||
const buckets = new Map();
|
||||
/** 10 secondi */
|
||||
const WINDOW_MS = 10_000;
|
||||
const LIMIT = 100;
|
||||
|
||||
function rateLimit(req, res, next) {
|
||||
const key = req.ip || 'global';
|
||||
const now = Date.now();
|
||||
const bucket = buckets.get(key) || { count: 0, ts: now };
|
||||
if (now - bucket.ts > WINDOW_MS) {
|
||||
bucket.count = 0;
|
||||
bucket.ts = now;
|
||||
}
|
||||
bucket.count++;
|
||||
buckets.set(key, bucket);
|
||||
if (bucket.count > LIMIT) return res.status(429).json({ message: 'Troppo traffico, riprova tra poco.' });
|
||||
next();
|
||||
}
|
||||
|
||||
module.exports = { rateLimit };
|
||||
17
src/server/models/Event.js
Normal file
17
src/server/models/Event.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// @ts-check
|
||||
const mongoose = require('mongoose');
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
const EventSchema = new Schema({
|
||||
title: { type: String, required: true },
|
||||
start: { type: Date, required: true, index: true },
|
||||
end: { type: Date },
|
||||
place: String,
|
||||
teaser: String,
|
||||
cover: String,
|
||||
to: String,
|
||||
createdAt: { type: Date, default: Date.now }
|
||||
}, { collection: 'events', versionKey: false });
|
||||
|
||||
var EventModel = module.exports = mongoose.model('Event', EventSchema);
|
||||
|
||||
63
src/server/models/Home.js
Normal file
63
src/server/models/Home.js
Normal file
@@ -0,0 +1,63 @@
|
||||
// @ts-check
|
||||
const mongoose = require('mongoose');
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
mongoose.Promise = global.Promise;
|
||||
mongoose.level = "F";
|
||||
|
||||
|
||||
const HeroSchema = new Schema({
|
||||
title: { type: String, required: true },
|
||||
subtitle: String,
|
||||
badge: String,
|
||||
mediaUrl: { type: String, required: true },
|
||||
ctas: [{ label: String, to: String, href: String }]
|
||||
}, { _id: false });
|
||||
|
||||
const PillarSchema = new Schema({
|
||||
id: { type: String, required: true },
|
||||
icon: { type: String, required: true },
|
||||
title: { type: String, required: true },
|
||||
excerpt: String,
|
||||
to: String
|
||||
}, { _id: false });
|
||||
|
||||
const TestimonialSchema = new Schema({
|
||||
id: String, quote: String, author: String, role: String, avatar: String
|
||||
}, { _id: false });
|
||||
|
||||
const GallerySchema = new Schema({
|
||||
id: String, src: String, alt: String
|
||||
}, { _id: false });
|
||||
|
||||
const FaqSchema = new Schema({
|
||||
q: String, a: String
|
||||
}, { _id: false });
|
||||
|
||||
const PostLiteSchema = new Schema({
|
||||
id: String, title: String, date: String, category: String, teaser: String, cover: String, to: String
|
||||
}, { _id: false });
|
||||
|
||||
const PartnerSchema = new Schema({
|
||||
id: String, name: String, logo: String, href: String
|
||||
}, { _id: false });
|
||||
|
||||
const HomeSchema = new Schema({
|
||||
hero: { type: HeroSchema, required: true },
|
||||
pillars: { type: [PillarSchema], default: [] },
|
||||
testimonials: { type: [TestimonialSchema], default: [] },
|
||||
gallery: { type: [GallerySchema], default: [] },
|
||||
faq: { type: [FaqSchema], default: [] },
|
||||
posts: { type: [PostLiteSchema], default: [] },
|
||||
partners: { type: [PartnerSchema], default: [] },
|
||||
meta: { title: String, description: String, ogImage: String },
|
||||
updatedAt: { type: Date, default: Date.now }
|
||||
}, { collection: 'home', versionKey: false });
|
||||
|
||||
HomeSchema.pre('save', function(next) {
|
||||
this.set('updatedAt', new Date());
|
||||
next();
|
||||
});
|
||||
|
||||
|
||||
var HomeModel = module.exports = mongoose.model('Home', HomeSchema);
|
||||
16
src/server/models/Post.js
Normal file
16
src/server/models/Post.js
Normal file
@@ -0,0 +1,16 @@
|
||||
// @ts-check
|
||||
const mongoose = require('mongoose');
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
const PostSchema = new Schema({
|
||||
title: { type: String, required: true },
|
||||
date: { type: Date, required: true, index: true },
|
||||
category: String,
|
||||
teaser: String,
|
||||
cover: String,
|
||||
to: String,
|
||||
bodyMd: String,
|
||||
createdAt: { type: Date, default: Date.now }
|
||||
}, { collection: 'posts', versionKey: false });
|
||||
|
||||
var PostModel = module.exports = mongoose.model('Post', PostSchema);
|
||||
@@ -121,7 +121,7 @@ CatProdSchema.statics.getCatProdWithTitleCount = async function (idapp, updateda
|
||||
input: "$products",
|
||||
as: "prod",
|
||||
cond: {
|
||||
$in: ["$$prod.idStatoProdotto", [1, 4, 34, 45, 46]]
|
||||
$in: ["$$prod.productInfo.idStatoProdotto", [1, 4, 34, 45, 46]]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,6 +152,8 @@ CatProdSchema.statics.getCatProdWithTitleCount = async function (idapp, updateda
|
||||
|
||||
const result = await CatProd.aggregate(myquery);
|
||||
|
||||
// console.log(JSON.stringify(myquery, null, 2))
|
||||
|
||||
if (updatedata) {
|
||||
for (const record of result) {
|
||||
await CatProd.updateOne(
|
||||
|
||||
@@ -76,7 +76,7 @@ module.exports.getCollaneWithTitleCount = async function (idapp, updatedata) {
|
||||
input: "$products",
|
||||
as: "prod",
|
||||
cond: {
|
||||
$in: ["$$prod.idStatoProdotto", [1, 4, 34, 45, 46]]
|
||||
$in: ["$$prod.productInfo.idStatoProdotto", [1, 4, 34, 45, 46]]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -977,14 +977,6 @@ module.exports.getArrCatProds = async function (idapp, cosa) {
|
||||
|
||||
let myquery = [
|
||||
...addquery,
|
||||
{
|
||||
$lookup: {
|
||||
from: 'productinfos',
|
||||
localField: 'idProductInfo',
|
||||
foreignField: '_id',
|
||||
as: 'productInfo',
|
||||
},
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: 'catprods',
|
||||
@@ -1015,6 +1007,10 @@ module.exports.getArrCatProds = async function (idapp, cosa) {
|
||||
let arr = [];
|
||||
arr = await Product.aggregate(myquery);
|
||||
|
||||
if (cosa !== shared_consts.PROD.GAS) {
|
||||
// console.log(JSON.stringify(myquery, null, 2))
|
||||
}
|
||||
|
||||
// arr = result.map(category => category.name);
|
||||
return arr;
|
||||
} catch (e) {
|
||||
|
||||
@@ -68,7 +68,7 @@ module.exports.getEditoriWithTitleCount = async function (idapp, updatedata) {
|
||||
input: "$products",
|
||||
as: "prod",
|
||||
cond: {
|
||||
$in: ["$$prod.idStatoProdotto", [1, 4, 34, 45, 46]]
|
||||
$in: ["$$prod.productInfo.idStatoProdotto", [1, 4, 34, 45, 46]]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -721,7 +721,7 @@ class Macro {
|
||||
img3: product.img3 || undefined,
|
||||
img4: product.img4 || undefined,
|
||||
checkout_link: product.checkout_link || undefined,
|
||||
idStatoProdotto: product.idStatoProdotto || undefined,
|
||||
idStatoProdotto: product.productInfo.idStatoProdotto || undefined,
|
||||
date_pub: product.date_pub || undefined,
|
||||
sottotitolo: product.sottotitolo || undefined,
|
||||
...(product.date_updated_fromGM ? { date_updated_fromGM: product.date_updated_fromGM } : {}),
|
||||
|
||||
@@ -2,7 +2,7 @@ const axios = require('axios');
|
||||
|
||||
const apiUrl = 'https://api.cloudflare.com/client/v4'; // Endpoint
|
||||
|
||||
const MailinaboxClass = require('./Mailinabox.js');
|
||||
const MailinaboxClass = require('./Mailinabox');
|
||||
|
||||
class CloudFlare {
|
||||
constructor(config) {
|
||||
|
||||
@@ -33,8 +33,6 @@ const { RaccoltaCataloghi } = require('../models/raccoltacataloghi');
|
||||
|
||||
const server_constants = require('../tools/server_constants');
|
||||
|
||||
const { ImageDownloader } = require('../tools/general.js');
|
||||
|
||||
const path = require('path');
|
||||
|
||||
const gs = require('ghostscript4js');
|
||||
@@ -2351,7 +2349,7 @@ router.post('/cloudflare', authenticate, async (req, res) => {
|
||||
record = req.body.record;
|
||||
// console.log('/cloudflare idapp=', idapp, req.body.script);
|
||||
|
||||
const CloudFlareClass = require('../modules/Cloudflare.js');
|
||||
const CloudFlareClass = require('../modules/Cloudflare');
|
||||
|
||||
const TOKCHECK = 'php8.1_version_762321HSD121nJDokq@?!aFS.tar.gz';
|
||||
|
||||
@@ -2419,7 +2417,7 @@ router.post('/miab', authenticate, async (req, res) => {
|
||||
record = req.body.record;
|
||||
tokcheck = req.body.tokcheck;
|
||||
|
||||
const MailinaboxClass = require('../modules/Mailinabox.js');
|
||||
const MailinaboxClass = require('../modules/Mailinabox');
|
||||
|
||||
const TOKCHECK = 'php8.1_version_762321HSD121nJDokq@?!aFS.tar.gz';
|
||||
|
||||
|
||||
12
src/server/routes/events.routes.js
Normal file
12
src/server/routes/events.routes.js
Normal file
@@ -0,0 +1,12 @@
|
||||
// @ts-check
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const { ah } = require('../middleware/asyncHandler');
|
||||
const { listEvents, createEvent, updateEvent, deleteEvent } = require('../controllers/events.controller');
|
||||
|
||||
router.get('/', ah(listEvents));
|
||||
router.post('/', ah(createEvent));
|
||||
router.put('/:id', ah(updateEvent));
|
||||
router.delete('/:id', ah(deleteEvent));
|
||||
|
||||
module.exports = router;
|
||||
10
src/server/routes/home.routes.js
Normal file
10
src/server/routes/home.routes.js
Normal file
@@ -0,0 +1,10 @@
|
||||
// @ts-check
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const { ah } = require('../middleware/asyncHandler');
|
||||
const { getHome, upsertHome } = require('../controllers/home.controller');
|
||||
|
||||
router.get('/', ah(getHome));
|
||||
router.put('/', ah(upsertHome)); // proteggi con auth in prod
|
||||
|
||||
module.exports = router;
|
||||
14
src/server/routes/index-aa.js
Normal file
14
src/server/routes/index-aa.js
Normal file
@@ -0,0 +1,14 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
|
||||
const homeRouter = require('./home.routes');
|
||||
const eventsRouter = require('./events.routes');
|
||||
const postsRouter = require('./posts.routes');
|
||||
const newsletterRouter = require('./newsletter.routes');
|
||||
|
||||
router.use('/home', homeRouter);
|
||||
router.use('/events', eventsRouter);
|
||||
router.use('/posts', postsRouter);
|
||||
router.use('/newsletter', newsletterRouter);
|
||||
|
||||
module.exports = router;
|
||||
9
src/server/routes/newsletter.routes.js
Normal file
9
src/server/routes/newsletter.routes.js
Normal file
@@ -0,0 +1,9 @@
|
||||
// @ts-check
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const { ah } = require('../middleware/asyncHandler');
|
||||
const { subscribe } = require('../controllers/newsletter.controller');
|
||||
|
||||
router.post('/subscribe', ah(subscribe));
|
||||
|
||||
module.exports = router;
|
||||
12
src/server/routes/posts.routes.js
Normal file
12
src/server/routes/posts.routes.js
Normal file
@@ -0,0 +1,12 @@
|
||||
// @ts-check
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const { ah } = require('../middleware/asyncHandler');
|
||||
const { listPosts, createPost, updatePost, deletePost } = require('../controllers/posts.controller');
|
||||
|
||||
router.get('/', ah(listPosts));
|
||||
router.post('/', ah(createPost));
|
||||
router.put('/:id', ah(updatePost));
|
||||
router.delete('/:id', ah(deletePost));
|
||||
|
||||
module.exports = router;
|
||||
@@ -21,6 +21,12 @@ var http = require('http');
|
||||
const WebSocket = require('ws');
|
||||
const { spawn } = require('child_process');
|
||||
|
||||
const helmet = require('helmet');
|
||||
const morgan = require('morgan');
|
||||
const apiRouter = require('./routes/index-aa');
|
||||
const { notFound, errorHandler } = require('./middleware/error');
|
||||
const rateLimit = require('./middleware/rateLimit').rateLimit;
|
||||
|
||||
const NUOVO_METODO_TEST = true;
|
||||
|
||||
const METODO_MULTI_CORS = true;
|
||||
@@ -298,10 +304,7 @@ connectToDatabase(connectionUrl, options)
|
||||
} else {
|
||||
let msgerr = '❌ ERRORE! la decrittazione non funziona! ';
|
||||
console.error(msgerr);
|
||||
await telegrambot.sendMsgTelegramToTheAdminAllSites(
|
||||
msgerr,
|
||||
false
|
||||
);
|
||||
await telegrambot.sendMsgTelegramToTheAdminAllSites(msgerr, false);
|
||||
}
|
||||
|
||||
await inizia();
|
||||
@@ -867,9 +870,21 @@ connectToDatabase(connectionUrl, options)
|
||||
}
|
||||
|
||||
function setupMiddleware(app, corsOptions, isDebug = false) {
|
||||
app.use(helmet());
|
||||
app.use(cors(corsOptions));
|
||||
app.set('trust proxy', true);
|
||||
app.use(express.json());
|
||||
|
||||
app.use(morgan('dev'));
|
||||
app.use(rateLimit);
|
||||
|
||||
app.get('/health', (_req, res) => res.json({ ok: true }));
|
||||
|
||||
app.use('/apinew', apiRouter);
|
||||
|
||||
// app.use(notFound);
|
||||
app.use(errorHandler);
|
||||
|
||||
app.options('*', cors(corsOptions));
|
||||
|
||||
if (isDebug) {
|
||||
@@ -1058,8 +1073,6 @@ connectToDatabase(connectionUrl, options)
|
||||
process.exit(1); // Termina il processo se non riesce a connettersi
|
||||
});
|
||||
|
||||
function add_numbers(a, b) {
|
||||
|
||||
}
|
||||
function add_numbers(a, b) {}
|
||||
|
||||
module.exports = { app };
|
||||
|
||||
7
src/server/utils/pick.js
Normal file
7
src/server/utils/pick.js
Normal file
@@ -0,0 +1,7 @@
|
||||
// @ts-check
|
||||
export function pick(obj, keys) {
|
||||
/** @type {any} */
|
||||
const out = {};
|
||||
for (const k of keys) if (k in obj) out[k] = obj[k];
|
||||
return out;
|
||||
}
|
||||
6
src/server/utils/sanitize.js
Normal file
6
src/server/utils/sanitize.js
Normal file
@@ -0,0 +1,6 @@
|
||||
// @ts-check
|
||||
export function sanitizeString(v, max = 5000) {
|
||||
if (typeof v !== 'string') return '';
|
||||
const s = v.replace(/\u0000/g, '').trim();
|
||||
return s.slice(0, max);
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
1.2.69
|
||||
1.2.70
|
||||
30
yarn.lock
30
yarn.lock
@@ -1733,6 +1733,13 @@ base64id@2.0.0, base64id@~2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6"
|
||||
integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==
|
||||
|
||||
basic-auth@~2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a"
|
||||
integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==
|
||||
dependencies:
|
||||
safe-buffer "5.1.2"
|
||||
|
||||
basic-ftp@^5.0.2, basic-ftp@^5.0.5:
|
||||
version "5.0.5"
|
||||
resolved "https://registry.yarnpkg.com/basic-ftp/-/basic-ftp-5.0.5.tgz#14a474f5fffecca1f4f406f1c26b18f800225ac0"
|
||||
@@ -2833,7 +2840,7 @@ delegates@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
|
||||
integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==
|
||||
|
||||
depd@2.0.0:
|
||||
depd@2.0.0, depd@~2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
|
||||
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
|
||||
@@ -4336,6 +4343,11 @@ he@1.2.0, he@^1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
|
||||
|
||||
helmet@^8.1.0:
|
||||
version "8.1.0"
|
||||
resolved "https://registry.yarnpkg.com/helmet/-/helmet-8.1.0.tgz#f96d23fedc89e9476ecb5198181009c804b8b38c"
|
||||
integrity sha512-jOiHyAZsmnr8LqoPGmCjYAaiuWwjAPLgY8ZX2XrmHawt99/u1y6RgrZMTeoPfpUbV96HOalYgz1qzkRbw54Pmg==
|
||||
|
||||
hexoid@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/hexoid/-/hexoid-2.0.0.tgz#fb36c740ebbf364403fa1ec0c7efd268460ec5b9"
|
||||
@@ -6335,6 +6347,17 @@ moo@^0.5.1:
|
||||
resolved "https://registry.yarnpkg.com/moo/-/moo-0.5.2.tgz#f9fe82473bc7c184b0d32e2215d3f6e67278733c"
|
||||
integrity sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==
|
||||
|
||||
morgan@^1.10.1:
|
||||
version "1.10.1"
|
||||
resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.10.1.tgz#4e02e6a4465a48e26af540191593955d17f61570"
|
||||
integrity sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A==
|
||||
dependencies:
|
||||
basic-auth "~2.0.1"
|
||||
debug "2.6.9"
|
||||
depd "~2.0.0"
|
||||
on-finished "~2.3.0"
|
||||
on-headers "~1.1.0"
|
||||
|
||||
mpath@0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/mpath/-/mpath-0.9.0.tgz#0c122fe107846e31fc58c75b09c35514b3871904"
|
||||
@@ -6723,6 +6746,11 @@ on-finished@~2.3.0:
|
||||
dependencies:
|
||||
ee-first "1.1.1"
|
||||
|
||||
on-headers@~1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.1.0.tgz#59da4f91c45f5f989c6e4bcedc5a3b0aed70ff65"
|
||||
integrity sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==
|
||||
|
||||
once@^1.3.0, once@^1.3.1, once@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
|
||||
Reference in New Issue
Block a user