/
dfe-signin-strategy.js
99 lines (94 loc) · 3.53 KB
/
dfe-signin-strategy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
'use strict'
const config = require('../config')
const { Strategy, Issuer } = require('openid-client')
const logger = require('../services/log.service').getLogger()
const asyncRetry = require('login.dfe.async-retry')
const dfeSigninService = require('../services/dfe-signin.service')
const passport = require('passport')
const authModes = require('../lib/consts/auth-modes')
/**
* Asynchronous setup of DfE signin with retry strategy for issuer discovery
* @returns {Strategy} configured Passport Strategy
*/
const initSignOnAsync = async () => {
Issuer.defaultHttpOptions = { timeout: config.Auth.dfeSignIn.issuerDiscoveryTimeoutMs }
let issuer
try {
issuer = await asyncRetry(async () =>
Issuer.discover(config.Auth.dfeSignIn.authUrl), asyncRetry.strategies.apiStrategy)
} catch (error) {
logger.error(`error discovering dfe signin service:${error.message}`)
throw error
}
logger.info('dfe sign on initialised')
const client = new issuer.Client({
client_id: config.Auth.dfeSignIn.clientId,
client_secret: config.Auth.dfeSignIn.clientSecret,
post_logout_redirect_uri: `${config.Runtime.externalHost}/sign-out-dso`
})
if (config.Auth.dfeSignIn.clockToleranceSeconds && config.Auth.dfeSignIn.clockToleranceSeconds > 0) {
client.CLOCK_TOLERANCE = config.Auth.dfeSignIn.clockToleranceSeconds
}
return new Strategy({
client,
params: {
scope: config.Auth.dfeSignIn.openIdScope,
redirect_uri: `${config.Runtime.externalHost}/auth-dso`
}
}, async (tokenset, authUserInfo, done) => {
try {
// authUserInfo appears to be exactly the same as what client.userinfo returns 🤷♂️
// let userInfo = await client.userinfo(tokenset.access_token)
const userInfo = await dfeSigninService.initialiseUser(authUserInfo, tokenset)
done(null, userInfo)
} catch (error) {
logger.error(error)
done(error)
}
})
}
/**
* Synchronous setup of DfE signin with no fault tolerance on issuer discovery.
* Configures passport with strategy once created
* @returns {void}
*/
const initSignOnSync = () => {
Issuer.defaultHttpOptions = { timeout: config.Auth.dfeSignIn.issuerDiscoveryTimeoutMs }
logger.debug('discovering dfe signin service issuer...')
Issuer.discover(config.Auth.dfeSignIn.authUrl)
.then((issuer) => {
logger.info('dfe sign on discovered successfully')
const client = new issuer.Client({
client_id: config.Auth.dfeSignIn.clientId,
client_secret: config.Auth.dfeSignIn.clientSecret
})
if (config.Auth.dfeSignIn.clockToleranceSeconds && config.Auth.dfeSignIn.clockToleranceSeconds > 0) {
client.CLOCK_TOLERANCE = config.Auth.dfeSignIn.clockToleranceSeconds
}
const dfeStrategy = new Strategy({
client,
params: {
scope: config.Auth.dfeSignIn.openIdScope
}
}, async (tokenset, authUserInfo, done) => {
try {
// authUserInfo appears to be exactly the same as what client.userinfo returns 🤷♂️
// let userInfo = await client.userinfo(tokenset.access_token)
const userInfo = await dfeSigninService.initialiseUser(authUserInfo, tokenset)
done(null, userInfo)
} catch (error) {
logger.error(error)
done(error)
}
})
passport.use(authModes.dfeSignIn, dfeStrategy)
})
.catch((error) => {
logger.error(`dfe signin initialisation failed:${error.message}`)
throw error
})
}
module.exports = {
initialise: initSignOnSync,
initialiseAsync: initSignOnAsync
}