1
1
"use strict" ;
2
2
3
3
const METABASE_SITE_URL =
4
- process . env . METABASE_SITE_URL || "http://localhost:3000" ;
4
+ process . env . METABASE_SITE_URL || "http://localhost:3000" ;
5
5
const METABASE_JWT_SHARED_SECRET =
6
- process . env . METABASE_JWT_SHARED_SECRET ||
7
- "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" ;
8
- const mods = 'logo=false&top_nav=false&search=false&new_button=false&side_nav=false&header=false&additional_info=false&breadcrumbs=false&action_buttons=false'
6
+ process . env . METABASE_JWT_SHARED_SECRET ||
7
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" ;
8
+
9
+ const mods = "logo=false" ;
10
+
9
11
/**
10
12
* Module dependencies.
11
13
*/
@@ -28,173 +30,173 @@ app.set("views", path.join(__dirname, "views"));
28
30
29
31
app . use ( express . urlencoded ( { extended : false } ) ) ;
30
32
app . use (
31
- session ( {
32
- resave : false , // don't save session if unmodified
33
- saveUninitialized : false , // don't create session until something stored
34
- secret : "shhhh, very secret" ,
35
- } )
33
+ session ( {
34
+ resave : false , // don't save session if unmodified
35
+ saveUninitialized : false , // don't create session until something stored
36
+ secret : "shhhh, very secret" ,
37
+ } )
36
38
) ;
37
39
38
40
// Session-persisted message middleware
39
41
40
42
app . use ( function ( req , res , next ) {
41
- var err = req . session . error ;
42
- var msg = req . session . success ;
43
- delete req . session . error ;
44
- delete req . session . success ;
45
- res . locals . message = "" ;
46
- if ( err ) res . locals . message = '<p class="msg error">' + err + "</p>" ;
47
- if ( msg ) res . locals . message = '<p class="msg success">' + msg + "</p>" ;
48
- next ( ) ;
43
+ var err = req . session . error ;
44
+ var msg = req . session . success ;
45
+ delete req . session . error ;
46
+ delete req . session . success ;
47
+ res . locals . message = "" ;
48
+ if ( err ) res . locals . message = '<p class="msg error">' + err + "</p>" ;
49
+ if ( msg ) res . locals . message = '<p class="msg success">' + msg + "</p>" ;
50
+ next ( ) ;
49
51
} ) ;
50
52
51
53
// dummy database
52
54
53
55
var users = [
54
- {
55
- firstName : "Rene" ,
56
- lastName : "Mueller" ,
57
-
58
- accountId : 28 ,
59
- accountName : "Customer-Acme" ,
60
- } ,
61
- {
62
- firstName : "Cecilia" ,
63
- lastName : "Stark" ,
64
-
65
- accountId : 132 ,
66
- accountName : "Customer-Fake" ,
67
- } ,
56
+ {
57
+ firstName : "Rene" ,
58
+ lastName : "Mueller" ,
59
+
60
+ accountId : 28 ,
61
+ accountName : "Customer-Acme" ,
62
+ } ,
63
+ {
64
+ firstName : "Cecilia" ,
65
+ lastName : "Stark" ,
66
+
67
+ accountId : 132 ,
68
+ accountName : "Customer-Fake" ,
69
+ } ,
68
70
] ;
69
71
70
72
// when you create a user, generate a salt
71
73
// and hash the password ('foobar' is the pass here)
72
74
73
75
hash ( { password : "foobar" } , function ( err , pass , salt , hash ) {
74
- if ( err ) throw err ;
75
- // store the salt & hash in the "db"
76
- users . forEach ( ( element ) => {
77
- element . salt = salt ;
78
- element . hash = hash ;
79
- } ) ;
76
+ if ( err ) throw err ;
77
+ // store the salt & hash in the "db"
78
+ users . forEach ( ( element ) => {
79
+ element . salt = salt ;
80
+ element . hash = hash ;
81
+ } ) ;
80
82
} ) ;
81
83
82
84
function findUserbyEmail ( email ) {
83
- var u = users . find ( ( u ) => u . email === email ) ;
84
- return u ;
85
+ var u = users . find ( ( u ) => u . email === email ) ;
86
+ return u ;
85
87
}
86
88
87
89
// Authenticate using our plain-object database of doom!
88
90
89
91
function authenticate ( email , pass , fn ) {
90
- if ( ! module . parent ) console . log ( "authenticating %s:%s" , email , pass ) ;
91
- var user = findUserbyEmail ( email ) ;
92
- // query the db for the given email
93
- if ( ! user ) return fn ( null , null ) ;
94
- // apply the same algorithm to the POSTed password, applying
95
- // the hash against the pass / salt, if there is a match we
96
- // found the user
97
- hash ( { password : pass , salt : user . salt } , function ( err , pass , salt , hash ) {
98
- if ( err ) return fn ( err ) ;
99
- if ( hash === user . hash ) return fn ( null , user ) ;
100
- fn ( null , null ) ;
101
- } ) ;
92
+ if ( ! module . parent ) console . log ( "authenticating %s:%s" , email , pass ) ;
93
+ var user = findUserbyEmail ( email ) ;
94
+ // query the db for the given email
95
+ if ( ! user ) return fn ( null , null ) ;
96
+ // apply the same algorithm to the POSTed password, applying
97
+ // the hash against the pass / salt, if there is a match we
98
+ // found the user
99
+ hash ( { password : pass , salt : user . salt } , function ( err , pass , salt , hash ) {
100
+ if ( err ) return fn ( err ) ;
101
+ if ( hash === user . hash ) return fn ( null , user ) ;
102
+ fn ( null , null ) ;
103
+ } ) ;
102
104
}
103
105
104
106
function restrict ( req , res , next ) {
105
- if ( req . session . user ) {
106
- next ( ) ;
107
- } else {
108
- req . session . returnTo = req . originalUrl ;
109
- req . session . error = "Access denied!" ;
110
- res . redirect ( "/login" ) ;
111
- }
107
+ if ( req . session . user ) {
108
+ next ( ) ;
109
+ } else {
110
+ req . session . returnTo = req . originalUrl ;
111
+ req . session . error = "Access denied!" ;
112
+ res . redirect ( "/login" ) ;
113
+ }
112
114
}
113
115
114
116
const signUserToken = ( user ) =>
115
- jwt . sign (
116
- {
117
- email : user . email ,
118
- first_name : user . firstName ,
119
- last_name : user . lastName ,
120
- account_id : user . accountId ,
121
- groups : [ user . accountName ] ,
122
- exp : Math . round ( Date . now ( ) / 1000 ) + 60 * 10 , // 10 minute expiration
123
- } ,
124
- METABASE_JWT_SHARED_SECRET
125
- ) ;
117
+ jwt . sign (
118
+ {
119
+ email : user . email ,
120
+ first_name : user . firstName ,
121
+ last_name : user . lastName ,
122
+ account_id : user . accountId ,
123
+ groups : [ user . accountName ] ,
124
+ exp : Math . round ( Date . now ( ) / 1000 ) + 60 * 10 , // 10 minute expiration
125
+ } ,
126
+ METABASE_JWT_SHARED_SECRET
127
+ ) ;
126
128
127
129
app . get ( "/" , function ( req , res ) {
128
- res . redirect ( "/analytics" ) ;
130
+ res . redirect ( "/analytics" ) ;
129
131
} ) ;
130
132
131
133
app . get ( "/analytics" , restrict , function ( req , res ) {
132
- // replace ID "1" with the ID number in the path of your dashboard in Metabase.
133
- const METABASE_DASHBOARD_PATH = "/dashboard/1" ;
134
- var iframeUrl = `/sso/metabase?return_to=${ METABASE_DASHBOARD_PATH } ` ;
135
- res . send (
136
- `<iframe src="${ iframeUrl } " frameborder="0" width="1280" height="1000" allowtransparency></iframe>`
137
- ) ;
134
+ // replace ID "1" with the ID number in the path of your dashboard in Metabase.
135
+ const METABASE_DASHBOARD_PATH = "/dashboard/1" ;
136
+ var iframeUrl = `/sso/metabase?return_to=${ METABASE_DASHBOARD_PATH } ` ;
137
+ res . send (
138
+ `<iframe src="${ iframeUrl } " frameborder="0" width="1280" height="1000" allowtransparency></iframe>`
139
+ ) ;
138
140
} ) ;
139
141
140
142
app . get ( "/logout" , function ( req , res ) {
141
- // destroy the user's session to log them out
142
- // will be re-created next request
143
- req . session . destroy ( function ( ) {
144
- res . redirect ( "/" ) ;
145
- } ) ;
143
+ // destroy the user's session to log them out
144
+ // will be re-created next request
145
+ req . session . destroy ( function ( ) {
146
+ res . redirect ( "/" ) ;
147
+ } ) ;
146
148
} ) ;
147
149
148
150
app . get ( "/login" , function ( req , res ) {
149
- res . render ( "login" ) ;
151
+ res . render ( "login" ) ;
150
152
} ) ;
151
153
152
154
app . post ( "/login" , function ( req , res , next ) {
153
- authenticate ( req . body . email , req . body . password , function ( err , user ) {
154
- if ( err ) return next ( err ) ;
155
- if ( user ) {
156
- // Regenerate session when signing in
157
- // to prevent fixation
158
- var returnTo = req . session . returnTo ;
159
- req . session . regenerate ( function ( ) {
160
- // Store the user's primary key
161
- // in the session store to be retrieved,
162
- // or in this case the entire user object
163
- req . session . user = user ;
164
- req . session . success =
165
- "Authenticated as " +
166
- user . firstName +
167
- "" +
168
- user . lastName +
169
- ' click to <a href="/logout">logout</a>. ' +
170
- ' click to access <a href="/analytics">analytics</a>' ;
171
- res . redirect ( returnTo || "/" ) ;
172
- delete req . session . returnTo ;
173
- } ) ;
174
- } else {
175
- req . session . error =
176
- "Authentication failed, please check your " +
177
- " email and password." +
178
- ' (use "[email protected] " or "[email protected] " and password "foobar")' ;
179
- res . redirect ( "/login" ) ;
180
- }
181
- } ) ;
155
+ authenticate ( req . body . email , req . body . password , function ( err , user ) {
156
+ if ( err ) return next ( err ) ;
157
+ if ( user ) {
158
+ // Regenerate session when signing in
159
+ // to prevent fixation
160
+ var returnTo = req . session . returnTo ;
161
+ req . session . regenerate ( function ( ) {
162
+ // Store the user's primary key
163
+ // in the session store to be retrieved,
164
+ // or in this case the entire user object
165
+ req . session . user = user ;
166
+ req . session . success =
167
+ "Authenticated as " +
168
+ user . firstName +
169
+ "" +
170
+ user . lastName +
171
+ ' click to <a href="/logout">logout</a>. ' +
172
+ ' click to access <a href="/analytics">analytics</a>' ;
173
+ res . redirect ( returnTo || "/" ) ;
174
+ delete req . session . returnTo ;
175
+ } ) ;
176
+ } else {
177
+ req . session . error =
178
+ "Authentication failed, please check your " +
179
+ " email and password." +
180
+ ' (use "[email protected] " or "[email protected] " and password "foobar")' ;
181
+ res . redirect ( "/login" ) ;
182
+ }
183
+ } ) ;
182
184
} ) ;
183
185
184
186
app . get ( "/sso/metabase" , restrict , ( req , res ) => {
185
- res . redirect (
186
- url . format ( {
187
- pathname : `${ METABASE_SITE_URL } /auth/sso` ,
188
- query : {
189
- jwt : signUserToken ( req . session . user ) ,
190
- return_to : `${ req . query . return_to || "/" } ?${ mods } ` ,
191
- } ,
192
- } )
193
- ) ;
187
+ res . redirect (
188
+ url . format ( {
189
+ pathname : `${ METABASE_SITE_URL } /auth/sso` ,
190
+ query : {
191
+ jwt : signUserToken ( req . session . user ) ,
192
+ return_to : `${ req . query . return_to || "/" } ?${ mods } ` ,
193
+ } ,
194
+ } )
195
+ ) ;
194
196
} ) ;
195
197
196
198
const PORT = 8080 ;
197
199
if ( ! module . parent ) {
198
- app . listen ( PORT ) ;
199
- console . log ( `Express started serving on port ${ PORT } ` ) ;
200
+ app . listen ( PORT ) ;
201
+ console . log ( `Express started serving on port ${ PORT } ` ) ;
200
202
}
0 commit comments