Skip to content

Commit 4653ec0

Browse files
committed
Add basic rate limiter
1 parent 1a294fe commit 4653ec0

1 file changed

Lines changed: 33 additions & 2 deletions

File tree

OpenFlow/src/LoginProvider.ts

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import * as SAMLStrategy from "passport-saml";
1010
import * as GoogleStrategy from "passport-google-oauth20";
1111
import * as LocalStrategy from "passport-local";
1212

13+
1314
import * as passport from "passport";
1415
import { Config } from "./Config";
1516

@@ -19,12 +20,31 @@ import { Audit } from "./Audit";
1920
import * as saml from "saml20";
2021
const multer = require('multer');
2122
const GridFsStorage = require('multer-gridfs-storage');
23+
const { RateLimiterMemory, RateLimiterRes } = require('rate-limiter-flexible')
2224
import { GridFSBucket, ObjectID, Db, Cursor, Binary } from "mongodb";
2325
import { Base, User, NoderedUtil, TokenUser, WellknownIds, Rights, Role } from "openflow-api";
2426
import { DBHelper } from "./DBHelper";
2527
const safeObjectID = (s: string | number | ObjectID) => ObjectID.isValid(s) ? new ObjectID(s) : null;
2628

27-
const stringify = require('json-stringify-safe');
29+
const BaseRateLimiter = new RateLimiterMemory({
30+
points: 10,
31+
duration: 5,
32+
});
33+
34+
const rateLimiter = (req: express.Request, res: express.Response, next: express.NextFunction): void => {
35+
BaseRateLimiter
36+
.consume(req.ip)
37+
.then((e) => {
38+
// console.log("NO_RATE_LIMIT consumedPoints: " + e.consumedPoints + " remainingPoints: " + e.remainingPoints);
39+
next();
40+
})
41+
.catch((e) => {
42+
console.log("RATE_LIMIT consumedPoints: " + e.consumedPoints + " remainingPoints: " + e.remainingPoints + " msBeforeNext: " + e.msBeforeNext);
43+
res.status(429).json({ response: 'RATE_LIMIT' });
44+
});
45+
};
46+
47+
2848

2949
interface IVerifyFunction { (error: any, profile: any): void; }
3050
export class Provider extends Base {
@@ -66,10 +86,20 @@ export class LoginProvider {
6686
public static _providers: any = {};
6787
public static login_providers: Provider[] = [];
6888

89+
public static escape(s: string): string {
90+
let lookup: any = {
91+
'&': "&",
92+
'"': """,
93+
'<': "&lt;",
94+
'>': "&gt;"
95+
};
96+
return s.replace(/[&"<>]/g, (c) => lookup[c]);
97+
}
6998
public static redirect(res: any, originalUrl: string) {
7099
res.write('<!DOCTYPE html>');
71100
res.write('<body>');
72-
res.write('<script>top.location = "' + encodeURI(originalUrl) + '";</script>');
101+
// res.write('<script>top.location = "' + encodeURI(originalUrl) + '";</script>');
102+
res.write('<script>top.location = "' + LoginProvider.escape(originalUrl) + '";</script>');
73103
// res.write('<a href="' + originalUrl + '">click here</a>');
74104
res.write('</body>');
75105
res.write('</html>');
@@ -135,6 +165,7 @@ export class LoginProvider {
135165
done(null, user);
136166
// Audit.LoginSuccess(TokenUser.From(user), "weblogin", "cookie", "");
137167
});
168+
app.use(rateLimiter);
138169

139170
app.use(function (req, res, next) {
140171
res.header('Access-Control-Allow-Origin', (req.headers.origin as any));

0 commit comments

Comments
 (0)