forked from Seneca-CDOT/telescope
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor auth routes into separate files
- Loading branch information
Showing
6 changed files
with
164 additions
and
140 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
const { Router } = require('@senecacdot/satellite'); | ||
const { errors } = require('celebrate'); | ||
|
||
const router = Router(); | ||
|
||
router.use('/login', require('./login')); | ||
router.use('/logout', require('./logout')); | ||
router.use('/sp', require('./saml-metadata')); | ||
|
||
// Let Celebrate handle validation errors | ||
router.use(errors()); | ||
|
||
module.exports = router; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
const { Router, logger, createError } = require('@senecacdot/satellite'); | ||
const passport = require('passport'); | ||
|
||
const { createToken } = require('../token'); | ||
const { | ||
validateRedirectAndStateParams, | ||
validateRedirectUriOrigin, | ||
captureAuthDetailsOnSession, | ||
} = require('../middleware'); | ||
|
||
const router = Router(); | ||
|
||
/** | ||
* /login allows users to authenticate with the external SAML SSO provider. | ||
* The caller needs to provide a request_uri query param to indicate where | ||
* we should redirect | ||
*/ | ||
router.get( | ||
'/', | ||
validateRedirectAndStateParams(), | ||
validateRedirectUriOrigin(), | ||
captureAuthDetailsOnSession(), | ||
passport.authenticate('saml') | ||
); | ||
|
||
/** | ||
* /login/callback is where the external SAML SSO provider will redirect | ||
* users upon successful login. We redirect the user back to wherever | ||
* they were trying to go, along with their original state unmodified. | ||
*/ | ||
router.post('/callback', passport.authenticate('saml'), (req, res, next) => { | ||
// We should have a login object in the session. If not, something's wrong. | ||
if (!req.session.authDetails) { | ||
logger.warn('/login/callback route hit without valid login session details'); | ||
next(createError(400, `unexpected access of /login/callback`)); | ||
return; | ||
} | ||
|
||
const { redirectUri, state } = req.session.authDetails; | ||
delete req.session.authDetails; | ||
logger.debug({ redirectUri, state }, 'processing /login/callback'); | ||
|
||
// Create a token for this user, setting their authorization roles | ||
const { user } = req; | ||
const token = createToken( | ||
user.email, | ||
user.firstName, | ||
user.lastName, | ||
user.displayName, | ||
user.roles, | ||
user.avatarUrl | ||
); | ||
|
||
let url = `${redirectUri}?access_token=${token}`; | ||
// Add the state we received before, if it was given at all | ||
if (state) { | ||
url += `&state=${state}`; | ||
} | ||
|
||
// TODO: send back expires info too? | ||
res.redirect(url); | ||
}); | ||
|
||
module.exports = router; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
const { Router, logger, createError } = require('@senecacdot/satellite'); | ||
const passport = require('passport'); | ||
|
||
const { | ||
validateRedirectAndStateParams, | ||
validateRedirectUriOrigin, | ||
captureAuthDetailsOnSession, | ||
} = require('../middleware'); | ||
|
||
const router = Router(); | ||
|
||
/** | ||
* /logout/callback is where the external SAML SSO provider will redirect | ||
* users upon successful logout. We support both GET and POST, since different | ||
* IdPs do it different ways. | ||
*/ | ||
function logout() { | ||
return (req, res, next) => { | ||
// We should have a logout object in the session. If not, something's wrong. | ||
if (!req.session.authDetails) { | ||
logger.warn('/logout/callback route hit without valid logout session details'); | ||
next(createError(400, `unexpected access of /logout/callback`)); | ||
return; | ||
} | ||
|
||
const { redirectUri, state } = req.session.authDetails; | ||
delete req.session.authDetails; | ||
logger.debug({ redirectUri, state }, 'processing /logout/callback'); | ||
|
||
// Clear session passport.js user info | ||
req.logout(); | ||
|
||
// Add the state on the redirect if present | ||
const url = state ? `${redirectUri}?state=${state}` : redirectUri; | ||
res.redirect(url); | ||
}; | ||
} | ||
|
||
router.get('/callback', logout()); | ||
router.post('/callback', logout()); | ||
|
||
/** | ||
* /logout allows users to use Single Logout and clear login tokens | ||
* from their passport.js session. | ||
*/ | ||
router.get( | ||
'/', | ||
validateRedirectAndStateParams(), | ||
validateRedirectUriOrigin(), | ||
captureAuthDetailsOnSession(), | ||
// passport.authenticate('saml'), | ||
(req, res, next) => { | ||
try { | ||
// eslint-disable-next-line no-underscore-dangle | ||
passport._strategy('saml').logout(req, (error, requestUrl) => { | ||
if (error) { | ||
logger.error({ error }, 'logout error - unable to generate logout URL'); | ||
next(createError(500, `unable to logout`)); | ||
} else { | ||
res.redirect(requestUrl); | ||
} | ||
}); | ||
} catch (error) { | ||
logger.error({ error }, 'logout error'); | ||
next(createError(500, `unable to logout`)); | ||
} | ||
} | ||
); | ||
|
||
module.exports = router; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
const { Router } = require('@senecacdot/satellite'); | ||
|
||
const { samlMetadata } = require('../authentication'); | ||
|
||
const router = Router(); | ||
|
||
/** | ||
* Provide SAML Metadata endpoint for our Service Provider's Entity ID. | ||
* The naming is {host}/sp, for example: http://localhost/v1/auth/sp | ||
*/ | ||
router.get('/', (req, res) => { | ||
res.type('application/xml'); | ||
res.status(200).send(samlMetadata()); | ||
}); | ||
|
||
module.exports = router; |