website/src/server.js
Jonathan Barrow d5a05e0502
feat: add terms
These terms are almost entirely a mashup of generated/pre-made documents from both https://termly.io/ and https://www.termsfeed.com/, which were then merged together and modified to the best of our ability to fit our specific needs. However we are not legal experts, and there is quite a lot of legalese here, and possibly broad policies with regards to collection/retention/sharing which we do NOT necessarily want/need. Our goal is to collect as LITTLE information about users as possible, and to never sell or directly share that data with any 3rd parties besides those required for operation, such as Cloudflare and Stripe. I have done my best to remove all the broad policies that would allow us to sell user data, as we do NOT want to do that, but I am no legal expert and may have missed things. In those cases, we are more than happy to revise/remove the problematic areas to clarify our goals/intentions
2025-03-17 18:13:56 -04:00

195 lines
4.6 KiB
JavaScript

process.title = 'Pretendo - Website';
process.on('SIGTERM', () => {
process.exit(0);
});
const express = require('express');
const handlebars = require('express-handlebars');
const morgan = require('morgan');
const expressLocale = require('express-locale');
const cookieParser = require('cookie-parser');
// const Stripe = require('stripe');
const config = require('./config');
const redirectMiddleware = require('./middleware/redirect');
const renderDataMiddleware = require('./middleware/render-data');
const database = require('./database');
const logger = require('./logger');
const { http: { port } } = config;
const app = express();
// const stripe = new Stripe(config.stripe.secret_key);
logger.info('Setting up Middleware');
app.use(morgan('dev'));
// app.use(express.json());
app.use(express.json({
verify: (req, res, buf) => {
req.rawBody = buf;
}
}));
app.use(express.urlencoded({
extended: true
}));
app.use(cookieParser());
app.use(expressLocale({
priority: ['cookie', 'accept-language', 'map', 'default'],
cookie: { name: 'preferredLocale' },
// Map unavailable regions to available locales from the same language
map: {
/* TODO: map more regions to the available locales */
'en': 'en-US', 'en-AU': 'en-US', 'en-CA': 'en-US',
'ar': 'ar-AR',
'ca': 'ca-ES',
'cs': 'cs-CZ',
'cn': 'zh-CN',
'de': 'de-DE',
'nl': 'nl-NL',
'es': 'es-ES',
'fr': 'fr-FR', 'fr-CA': 'fr-FR', 'fr-CH': 'fr-FR',
'fi': 'fi-FI',
'it': 'it-IT', 'it-CH': 'it-IT',
'ja': 'ja-JP',
'kk': 'kk-KZ',
'ko': 'ko-KR',
'nb': 'nb-NO',
'no': 'nb-NO',
'pl': 'pl-PL',
'pt': 'pt-BR',
'ro': 'ro-RO',
'ru': 'ru-RU',
'sr': 'sr-RS',
'tr': 'tr-TR',
'uk': 'uk-UA'
},
allowed: [
'en', 'en-US', 'en-GB', 'en-AU', 'en-CA',
'ar', 'ar-AR',
'ast',
'ca-ES',
'cs-CZ',
'cn', 'zh-CN', 'zh-HK', 'zh-TW',
'de', 'de-DE',
'nl', 'nl-NL',
'es', 'es-ES',
'fi', 'fi-FI',
'fr', 'fr-FR', 'fr-CA', 'fr-CH',
'it', 'it-IT', 'it-CH',
'ja', 'ja-JP',
'kk', 'kk-KZ',
'ko', 'ko-KR',
'nb', 'no', 'nb-NO',
'pl', 'pl-PL',
'pt', 'pt-BR',
'ro', 'ro-RO',
'ru', 'ru-RU',
'sr', 'sr-RS',
'tr', 'tr-TR',
'uk', 'uk-UA',
'en@uwu'
],
default: 'en-US'
}));
app.use(redirectMiddleware);
app.use(renderDataMiddleware);
logger.info('Setting up static public folder');
app.use(express.static('public'));
logger.info('Importing routes');
const routes = {
home: require('./routes/home'),
terms: require('./routes/terms'),
faq: require('./routes/faq'),
docs: require('./routes/docs'),
progress: require('./routes/progress'),
account: require('./routes/account'),
blog: require('./routes/blog'),
localization: require('./routes/localization'),
aprilfools: require('./routes/aprilfools')
};
app.use('/', routes.home);
app.use('/terms', routes.terms);
app.use('/faq', routes.faq);
app.use('/docs', routes.docs);
app.use('/progress', routes.progress);
app.use('/account', routes.account);
app.use('/localization', routes.localization);
app.use('/blog', routes.blog);
app.use('/nso-legacy-pack', routes.aprilfools);
logger.info('Creating 404 status handler');
// This works because it is the last router created
// Meaning the request could not find a valid router
app.use((request, response) => {
response.render('404');
});
logger.info('Setting up handlebars engine');
app.engine('handlebars', handlebars({
helpers: {
doFaq(value, options) {
let htmlLeft = '';
let htmlRight = '';
for (const [i, v] of Object.entries(value)) {
const appendHtml = options.fn({
...v
}); // Tis is an HTML string
if (i % 2 === 0) {
htmlLeft += appendHtml;
} else {
htmlRight += appendHtml;
}
}
return `
<div class="left questions-left">
${htmlLeft}
</div>
<div class="right questions-right">
${htmlRight}
</div>
`;
},
eq(value1, value2) {
return value1 === value2;
},
neq(value1, value2) {
return value1 !== value2;
},
greaterThan(value1, value2) {
return value1 > value2;
},
slug(string) {
return string.toLowerCase().replaceAll(/ /g, '-');
},
section(name, options) {
if (!this._sections) {
this._sections = {};
}
if (!this._sections[name]) {
this._sections[name] = [];
}
this._sections[name].push(options.fn(this));
return null;
}
}
}));
app.set('view engine', 'handlebars');
logger.info('Starting server');
database.connect().then(() => {
app.listen(port, async () => {
/*
const events = await stripe.events.list({
delivery_success: false // failed webhooks
});
for (const event of events.data) {
await util.handleStripeEvent(event);
}
*/
logger.success(`Server listening on http://localhost:${port}`);
});
});