1
- import AdminBro , { Router as AdminRouter } from "admin-bro" ;
1
+ import AdminBro from "admin-bro" ;
2
2
import express , { Router } from "express" ;
3
- import formidableMiddleware from "express-formidable" ;
4
3
import session from "express-session" ;
5
- import { createLogoutHandler } from "./authentication/logout.handler" ;
4
+ import { withLogout } from "./authentication/logout.handler" ;
6
5
import { buildRouter } from "./buildRouter" ;
7
6
import { OldBodyParserUsedError } from "./errors" ;
8
- import { FormidableOptions } from "./types" ;
7
+ import { AuthenticationOptions , FormidableOptions } from "./types" ;
8
+ import { withLogin } from "./authentication/login.handler" ;
9
+ import { withProtectedRoutesHandler } from "./authentication/protected-routes.handler" ;
10
+ import formidableMiddleware from "express-formidable" ;
9
11
10
12
/**
11
13
* @typedef {Function } Authenticate
@@ -24,16 +26,6 @@ import { FormidableOptions } from "./types";
24
26
* dependency. Normally express-session holds session in memory, which is
25
27
* not optimized for production usage and, in development, it causes
26
28
* logging out after every page refresh (if you use nodemon).
27
- *
28
- * @param {AdminBro } admin instance of AdminBro
29
- * @param {Object } auth authentication options
30
- * @param {module:@admin-bro/express.Authenticate } auth.authenticate authenticate function
31
- * @param {String } auth.cookiePassword secret used to encrypt cookies
32
- * @param {String } auth.cookieName=adminbro cookie name
33
- * @param {express.Router } [predefinedRouter] Express.js router
34
- * @param {SessionOptions } [sessionOptions] Options that are passed to [express-session](https://github.com/expressjs/session)
35
- * @param {ExpressFormidableOptions } [formidableOptions] Options that are passed to [express-session](https://github.com/expressjs/session)
36
- * @return {express.Router } Express.js router
37
29
* @static
38
30
* @memberof module:@admin-bro/express
39
31
* @example
@@ -55,11 +47,7 @@ import { FormidableOptions } from "./types";
55
47
*/
56
48
export const buildAuthenticatedRouter = (
57
49
admin : AdminBro ,
58
- auth : {
59
- cookiePassword : string ;
60
- cookieName ?: string ;
61
- authenticate : ( email : string , password : string ) => unknown | null ;
62
- } ,
50
+ auth : AuthenticationOptions ,
63
51
predefinedRouter ?: express . Router ,
64
52
sessionOptions ?: session . SessionOptions ,
65
53
formidableOptions ?: FormidableOptions
@@ -80,86 +68,11 @@ export const buildAuthenticatedRouter = (
80
68
name : auth . cookieName || "adminbro" ,
81
69
} )
82
70
) ;
83
-
84
71
router . use ( formidableMiddleware ( formidableOptions ) ) ;
85
72
86
- const { rootPath } = admin . options ;
87
- let { loginPath, logoutPath } = admin . options ;
88
- // since we are inside already namespaced router we have to replace login and logout routes that
89
- // they don't have rootUrl inside. So changing /admin/login to just /login.
90
- // but there is a case where user gives / as a root url and /login becomes `login`. We have to
91
- // fix it by adding / in front of the route
92
- loginPath = loginPath . replace ( rootPath , "" ) ;
93
- if ( ! loginPath . startsWith ( "/" ) ) {
94
- loginPath = `/${ loginPath } ` ;
95
- }
96
-
97
- logoutPath = logoutPath . replace ( rootPath , "" ) ;
98
- if ( ! logoutPath . startsWith ( "/" ) ) {
99
- logoutPath = `/${ logoutPath } ` ;
100
- }
101
-
102
- router . get ( loginPath , async ( req , res ) => {
103
- const login = await admin . renderLogin ( {
104
- action : admin . options . loginPath ,
105
- errorMessage : null ,
106
- } ) ;
107
- res . send ( login ) ;
108
- } ) ;
109
-
110
- router . post ( loginPath , async ( req , res , next ) => {
111
- const { email, password } = req . fields as {
112
- email : string ;
113
- password : string ;
114
- } ;
115
- const adminUser = await auth . authenticate ( email , password ) ;
116
- if ( adminUser ) {
117
- req . session . adminUser = adminUser ;
118
- req . session . save ( ( err ) => {
119
- if ( err ) {
120
- next ( err ) ;
121
- }
122
- if ( req . session . redirectTo ) {
123
- res . redirect ( req . session . redirectTo ) ;
124
- } else {
125
- res . redirect ( rootPath ) ;
126
- }
127
- } ) ;
128
- } else {
129
- const login = await admin . renderLogin ( {
130
- action : admin . options . loginPath ,
131
- errorMessage : "invalidCredentials" ,
132
- } ) ;
133
- res . send ( login ) ;
134
- }
135
- } ) ;
136
-
137
- router . use ( ( req , res , next ) => {
138
- if ( AdminRouter . assets . find ( ( asset ) => req . originalUrl . match ( asset . path ) ) ) {
139
- next ( ) ;
140
- } else if (
141
- req . session . adminUser ||
142
- // these routes doesn't need authentication
143
- req . originalUrl . startsWith ( admin . options . loginPath ) ||
144
- req . originalUrl . startsWith ( admin . options . logoutPath )
145
- ) {
146
- next ( ) ;
147
- } else {
148
- // If the redirection is caused by API call to some action just redirect to resource
149
- const [ redirectTo ] = req . originalUrl . split ( "/actions" ) ;
150
- req . session . redirectTo = redirectTo . includes ( `${ rootPath } /api` )
151
- ? rootPath
152
- : redirectTo ;
153
- req . session . save ( ( err ) => {
154
- if ( err ) {
155
- next ( err ) ;
156
- }
157
- res . redirect ( admin . options . loginPath ) ;
158
- } ) ;
159
- }
160
- } ) ;
161
-
162
- router . get ( logoutPath , createLogoutHandler ( admin ) ) ;
73
+ withProtectedRoutesHandler ( router , admin ) ;
74
+ withLogin ( router , admin , auth ) ;
75
+ withLogout ( router , admin ) ;
163
76
164
77
return buildRouter ( admin , router , formidableOptions ) ;
165
78
} ;
0 commit comments