@@ -10,6 +10,7 @@ import * as SAMLStrategy from "passport-saml";
1010import * as GoogleStrategy from "passport-google-oauth20" ;
1111import * as LocalStrategy from "passport-local" ;
1212
13+
1314import * as passport from "passport" ;
1415import { Config } from "./Config" ;
1516
@@ -19,12 +20,31 @@ import { Audit } from "./Audit";
1920import * as saml from "saml20" ;
2021const multer = require ( 'multer' ) ;
2122const GridFsStorage = require ( 'multer-gridfs-storage' ) ;
23+ const { RateLimiterMemory, RateLimiterRes } = require ( 'rate-limiter-flexible' )
2224import { GridFSBucket , ObjectID , Db , Cursor , Binary } from "mongodb" ;
2325import { Base , User , NoderedUtil , TokenUser , WellknownIds , Rights , Role } from "openflow-api" ;
2426import { DBHelper } from "./DBHelper" ;
2527const 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
2949interface IVerifyFunction { ( error : any , profile : any ) : void ; }
3050export 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+ '<' : "<" ,
94+ '>' : ">"
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