forked from betagouv/sante-psy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
250 lines (219 loc) · 8.42 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
require('dotenv').config();
const bodyParser = require('body-parser');
const express = require('express');
const expressSanitizer = require('express-sanitizer');
const path = require('path');
const flash = require('connect-flash');
const expressJWT = require('express-jwt');
const rateLimit = require("express-rate-limit");
const slowDown = require("express-slow-down");
const cookieParser = require('cookie-parser');
const cookieSession = require('cookie-session');
const csrf = require('csurf');
const config = require('./utils/config');
const date = require('./utils/date');
const cspConfig = require('./utils/csp-config');
const sentry = require('./utils/sentry');
const appName = config.appName;
const appDescription = 'Accompagnement psychologique pour les étudiants';
const appRepo = 'https://github.com/betagouv/sante-psy';
const app = express();
const landingController = require('./controllers/landingController');
const dashboardController = require('./controllers/dashboardController');
const appointmentsController = require('./controllers/appointmentsController');
const patientsController = require('./controllers/patientsController');
const psyListingController = require('./controllers/psyListingController');
const loginController = require('./controllers/loginController');
const faqController = require('./controllers/faqController');
const reimbursementController = require('./controllers/reimbursementController');
// Desactivate debug log for production as they are a bit too verbose
if( !config.activateDebug ) {
console.log("console.debug is not active - thanks to ACTIVATE_DEBUG_LOG env variable");
console.debug = function desactivateDebug() {};
}
app.use(cspConfig);
app.use(bodyParser.urlencoded({ extended: true }))
app.use(flash());
app.use(cookieParser(config.secret));
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
app.use('/static', express.static('static'));
app.use('/static/gouvfr', express.static(
path.join(__dirname, 'node_modules/@gouvfr/dsfr/dist'))
);
app.use('/static/jquery', express.static(
path.join(__dirname, 'node_modules/jquery/dist'))
);
app.use('/static/tabulator-tables', express.static(
path.join(__dirname, 'node_modules/tabulator-tables/dist'))
);
// This session cookie (connect.sid) is only used for displaying the flash messages.
// The other session cookie (token) contains the authenticated user session.
app.use(cookieSession({
secret: config.secret,
resave: false,
saveUninitialized: true,
maxAge: parseInt(config.sessionDurationHours) * 60 * 60 * 1000
}));
app.use(flash());
if (config.useCSRF) {
console.log("Using CSRF protection");
app.use(csrf({ cookie: true }));
} else {
console.log('NOT using CSRF protection due to env variable USE_CSRF - should only be used for test');
}
// Mount express-sanitizer middleware here
app.use(expressSanitizer());
// Populate some variables for all views
app.use(function populate(req, res, next){
if (config.useCSRF) {
res.locals._csrf = req.csrfToken();
} else {
res.locals._csrf = '';
}
res.locals.appName = appName;
res.locals.appDescription = appDescription;
res.locals.appRepo = appRepo;
res.locals.page = req.url;
res.locals.contactEmail = config.contactEmail;
res.locals.errors = req.flash('error');
res.locals.infos = req.flash('info');
res.locals.successes = req.flash('success');
res.locals.featureReimbursementPage = config.featureReimbursementPage;
next();
})
app.use(
expressJWT({
secret: config.secret,
algorithms: ['HS256'],
getToken: function fromHeaderOrQuerystring (req) {
if( req.cookies !== undefined ) {
return req.cookies.token;
} else {
return null;
}
}
}).unless({
path: [
'/',
'/psychologue/login',
'/trouver-un-psychologue',
'/consulter-les-psychologues',
'/mentions-legales',
'/donnees-personnelles-et-gestion-des-cookies',
'/faq',
],
}),
);
app.use((err, req, res, next) => {
if (err.name === 'UnauthorizedError') {
const psychologueWorkspaceRegexp = new RegExp(/\/psychologue\//, 'g');
if (psychologueWorkspaceRegexp.test(req.originalUrl)) {
req.flash(
'error',
`Vous n'êtes pas identifié pour accéder à cette page ou votre accès n'est plus valide\
- la connexion est valide durant ${config.sessionDurationHours} heures`,
);
console.log("No token - redirect to login");
return res.redirect(`/psychologue/login`);
} else {
req.flash('error', "Cette page n'existe pas.");
return res.redirect(`/`);
}
} else if( req.cookies === undefined ) {
req.flash('error', "Cette page n'existe pas.");
res.redirect('/');
} else if (err !== 'EBADCSRFTOKEN') { // handle CSRF token errors here
console.warn(`CSRF token errors detected ${req.csrfToken()} but have ${res.req.body._csrf} in form data`);
res.status(403);
req.flash('error', "Une erreur est survenue, pouvez-vous réssayer ?");
return res.redirect(`/psychologue/mes-seances`);
}
return next(err);
});
app.locals.date = date
// prevent abuse
const rateLimiter = rateLimit({
windowMs: 5 * 60 * 1000, // 5 minute window
max: 1000, // start blocking after X requests for windowMs time
message: "Trop de requête venant de cette IP, veuillez essayer plus tard."
});
app.use(rateLimiter);
app.get('/', landingController.getLanding);
if (config.featurePsyList) {
// prevent abuse for some rules
const speedLimiter = slowDown({
windowMs: 5 * 60 * 1000, // 5 minutes
delayAfter: 100, // allow X requests per 5 minutes, then...
delayMs: 500 // begin adding 500ms of delay per request above 100:
// request # 101 is delayed by 500ms
// request # 102 is delayed by 1000ms
// request # 103 is delayed by 1500ms
// etc.
});
app.get('/trouver-un-psychologue', speedLimiter, psyListingController.getPsychologist);
app.get('/consulter-les-psychologues', speedLimiter, psyListingController.getPsychologist);
}
if (config.featurePsyPages) {
app.get('/psychologue/login', loginController.getLogin);
// prevent abuse for some rules
const speedLimiterLogin = slowDown({
windowMs: 5 * 60 * 1000, // 5 minutes
delayAfter: 10, // allow X requests per 5 minutes, then...
delayMs: 500 // begin adding 500ms of delay per request above 100:
});
app.post('/psychologue/login',
speedLimiterLogin,
loginController.emailValidators,
loginController.postLogin);
app.get('/psychologue/logout', loginController.getLogout);
app.get('/psychologue/mes-seances', dashboardController.dashboard)
app.get('/psychologue/nouvelle-seance', appointmentsController.newAppointment)
app.post('/psychologue/creer-nouvelle-seance',
appointmentsController.createNewAppointmentValidators,
appointmentsController.createNewAppointment)
app.post('/psychologue/api/supprimer-seance',
appointmentsController.deleteAppointmentValidators,
appointmentsController.deleteAppointment)
app.get('/psychologue/nouveau-patient', patientsController.newPatient)
app.post('/psychologue/api/creer-nouveau-patient',
patientsController.createNewPatientValidators,
patientsController.createNewPatient)
app.get('/psychologue/modifier-patient',
patientsController.getEditPatientValidators,
patientsController.getEditPatient)
app.post('/psychologue/api/modifier-patient',
patientsController.editPatientValidators,
patientsController.editPatient)
if (config.featureReimbursementPage) {
app.get('/psychologue/mes-remboursements', reimbursementController.reimbursement)
app.post('/psychologue/api/renseigner-convention',
reimbursementController.updateConventionInfoValidators,
reimbursementController.updateConventionInfo
)
}
}
app.get('/faq', faqController.getFaq);
app.get('/mentions-legales', (req, res) => {
res.render('legalNotice', {
pageTitle: "Mentions Légales",
});
})
app.get('/donnees-personnelles-et-gestion-des-cookies', (req, res) => {
res.render('données-personnelles-et-gestion-des-cookies', {
pageTitle: "Données personnelles",
})
})
app.get('*', function redirect404(req, res){
if( req.cookies === undefined ) {
req.flash('error', "Cette page n'existe pas.")
res.redirect('/');
} else {
req.flash('error', "Cette page n'existe pas.")
return res.redirect(`/psychologue/mes-seances`);
}
});
sentry.initCaptureConsoleWithHandler(app);
module.exports = app.listen(config.port, () => {
console.log(`${appName} listening at http://localhost:${config.port}`);
})