This repository was archived by the owner on May 3, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 273
/
Copy pathapp.js
150 lines (120 loc) · 5.39 KB
/
app.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
const express = require('express');
const morgan = require('morgan');
const cors = require('cors');
const rateLimit = require('express-rate-limit');
const passport = require('passport');
const passportAzureAd = require('passport-azure-ad');
const authConfig = require('./authConfig.js');
const router = require('./routes/index');
const app = express();
/**
* If your app is behind a proxy, reverse proxy or a load balancer, consider
* letting express know that you are behind that proxy. To do so, uncomment
* the line below.
*/
// app.set('trust proxy', /* numberOfProxies */);
/**
* HTTP request handlers should not perform expensive operations such as accessing the file system,
* executing an operating system command or interacting with a database without limiting the rate at
* which requests are accepted. Otherwise, the application becomes vulnerable to denial-of-service attacks
* where an attacker can cause the application to crash or become unresponsive by issuing a large number of
* requests at the same time. For more information, visit: https://cheatsheetseries.owasp.org/cheatsheets/Denial_of_Service_Cheat_Sheet.html
*/
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes)
standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers
legacyHeaders: false, // Disable the `X-RateLimit-*` headers
});
// Apply the rate limiting middleware to all requests
app.use(limiter);
app.use(cors());
app.use(express.json())
app.use(express.urlencoded({ extended: false}));
app.use(morgan('dev'));
const options = {
identityMetadata: `https://${authConfig.metadata.b2cDomain}/${authConfig.credentials.tenantName}/${authConfig.policies.policyName}/${authConfig.metadata.version}/${authConfig.metadata.discovery}`,
clientID: authConfig.credentials.clientID,
audience: authConfig.credentials.clientID,
policyName: authConfig.policies.policyName,
isB2C: authConfig.settings.isB2C,
validateIssuer: authConfig.settings.validateIssuer,
loggingLevel: authConfig.settings.loggingLevel,
passReqToCallback: authConfig.settings.passReqToCallback,
loggingNoPII: authConfig.settings.loggingNoPII, // set this to true in the authConfig.js if you want to enable logging and debugging
};
const bearerStrategy = new passportAzureAd.BearerStrategy(options, (req,token, done) => {
/**
* Below you can do extended token validation and check for additional claims, such as:
* - check if the delegated permissions in the 'scp' are the same as the ones declared in the application registration.
*
* Bear in mind that you can do any of the above checks within the individual routes and/or controllers as well.
* For more information, visit: https://learn.microsoft.com/en-us/azure/active-directory-b2c/tokens-overview
*/
/**
* Lines below verifies if the caller's client ID is in the list of allowed clients.
* This ensures only the applications with the right client ID can access this API.
* To do so, we use "azp" claim in the access token. Uncomment the lines below to enable this check.
*/
// if (!myAllowedClientsList.includes(token.azp)) {
// return done(new Error('Unauthorized'), {}, "Client not allowed");
// }
// const myAllowedClientsList = [
// /* add here the client IDs of the applications that are allowed to call this API */
// ]
/**
* Access tokens that have no 'scp' (for delegated permissions).
*/
if (!token.hasOwnProperty('scp')) {
return done(new Error('Unauthorized'), null, 'No delegated permissions found');
}
done(null, {}, token);
});
app.use(passport.initialize());
passport.use(bearerStrategy);
app.use(
'/api',
(req, res, next) => {
passport.authenticate(
'oauth-bearer',
{
session: false,
},
(err, user, info) => {
if (err) {
/**
* An error occurred during authorization. Either pass the error to the next function
* for Express error handler to handle, or send a response with the appropriate status code.
*/
return res.status(401).json({ error: err.message });
}
if (!user) {
// If no user object found, send a 401 response.
return res.status(401).json({ error: 'Unauthorized' });
}
if (info) {
// access token payload will be available in req.authInfo downstream
req.authInfo = info;
return next();
}
}
)(req, res, next);
},
router, // the router with all the routes
(err, req, res, next) => {
/**
* Add your custom error handling logic here. For more information, see:
* http://expressjs.com/en/guide/error-handling.html
*/
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// send error response
res.status(err.status || 500).send(err);
}
);
const port = process.env.PORT || 5000;
app.listen(port, () => {
console.log('Listening on port ' + port);
});
module.exports = app;