mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-02-10 15:29:57 +01:00
Added passport-openidconnect implementation
This commit is contained in:
parent
08676a675a
commit
62b0940766
26
package-lock.json
generated
26
package-lock.json
generated
@ -19,6 +19,7 @@
|
|||||||
"passport-google-oauth20": "^2.0.0",
|
"passport-google-oauth20": "^2.0.0",
|
||||||
"passport-jwt": "^4.0.1",
|
"passport-jwt": "^4.0.1",
|
||||||
"passport-local": "^1.0.0",
|
"passport-local": "^1.0.0",
|
||||||
|
"passport-openidconnect": "^0.1.1",
|
||||||
"socket.io": "^4.5.4",
|
"socket.io": "^4.5.4",
|
||||||
"xml2js": "^0.4.23"
|
"xml2js": "^0.4.23"
|
||||||
},
|
},
|
||||||
@ -1138,6 +1139,22 @@
|
|||||||
"url": "https://github.com/sponsors/jaredhanson"
|
"url": "https://github.com/sponsors/jaredhanson"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/passport-openidconnect": {
|
||||||
|
"version": "0.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/passport-openidconnect/-/passport-openidconnect-0.1.1.tgz",
|
||||||
|
"integrity": "sha512-r0QJiWEzwCg2MeCIXVP5G6YxVRqnEsZ2HpgKRthZ9AiQHJrgGUytXpsdcGF9BRwd3yMrEesb/uG/Yxb86rrY0g==",
|
||||||
|
"dependencies": {
|
||||||
|
"oauth": "0.9.x",
|
||||||
|
"passport-strategy": "1.x.x"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/jaredhanson"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/passport-strategy": {
|
"node_modules/passport-strategy": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
|
||||||
@ -2417,6 +2434,15 @@
|
|||||||
"utils-merge": "1.x.x"
|
"utils-merge": "1.x.x"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"passport-openidconnect": {
|
||||||
|
"version": "0.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/passport-openidconnect/-/passport-openidconnect-0.1.1.tgz",
|
||||||
|
"integrity": "sha512-r0QJiWEzwCg2MeCIXVP5G6YxVRqnEsZ2HpgKRthZ9AiQHJrgGUytXpsdcGF9BRwd3yMrEesb/uG/Yxb86rrY0g==",
|
||||||
|
"requires": {
|
||||||
|
"oauth": "0.9.x",
|
||||||
|
"passport-strategy": "1.x.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"passport-strategy": {
|
"passport-strategy": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
"passport-google-oauth20": "^2.0.0",
|
"passport-google-oauth20": "^2.0.0",
|
||||||
"passport-jwt": "^4.0.1",
|
"passport-jwt": "^4.0.1",
|
||||||
"passport-local": "^1.0.0",
|
"passport-local": "^1.0.0",
|
||||||
|
"passport-openidconnect": "^0.1.1",
|
||||||
"socket.io": "^4.5.4",
|
"socket.io": "^4.5.4",
|
||||||
"xml2js": "^0.4.23"
|
"xml2js": "^0.4.23"
|
||||||
},
|
},
|
||||||
|
@ -5,6 +5,7 @@ const LocalStrategy = require('passport-local')
|
|||||||
const JwtStrategy = require('passport-jwt').Strategy;
|
const JwtStrategy = require('passport-jwt').Strategy;
|
||||||
const ExtractJwt = require('passport-jwt').ExtractJwt;
|
const ExtractJwt = require('passport-jwt').ExtractJwt;
|
||||||
const GoogleStrategy = require('passport-google-oauth20').Strategy;
|
const GoogleStrategy = require('passport-google-oauth20').Strategy;
|
||||||
|
var OpenIDConnectStrategy = require('passport-openidconnect');
|
||||||
const User = require('./objects/user/User.js')
|
const User = require('./objects/user/User.js')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,17 +25,52 @@ class Auth {
|
|||||||
if (global.ServerSettings.authActiveAuthMethods.includes("local")) {
|
if (global.ServerSettings.authActiveAuthMethods.includes("local")) {
|
||||||
passport.use(new LocalStrategy(this.localAuthCheckUserPw.bind(this)))
|
passport.use(new LocalStrategy(this.localAuthCheckUserPw.bind(this)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we should load the google-oauth20 strategy
|
// Check if we should load the google-oauth20 strategy
|
||||||
if (global.ServerSettings.authActiveAuthMethods.includes("google-oauth20")) {
|
if (global.ServerSettings.authActiveAuthMethods.includes("google-oauth20")) {
|
||||||
passport.use(new GoogleStrategy({
|
passport.use(new GoogleStrategy({
|
||||||
clientID: global.ServerSettings.authGoogleOauth20ClientID,
|
clientID: global.ServerSettings.authGoogleOauth20ClientID,
|
||||||
clientSecret: global.ServerSettings.authGoogleOauth20ClientSecret,
|
clientSecret: global.ServerSettings.authGoogleOauth20ClientSecret,
|
||||||
callbackURL: global.ServerSettings.authGoogleOauth20CallbackURL
|
callbackURL: global.ServerSettings.authGoogleOauth20CallbackURL
|
||||||
}, function (accessToken, refreshToken, profile, done) {
|
}, (function (accessToken, refreshToken, profile, done) {
|
||||||
// TODO: what to use as username
|
// TODO: what to use as username
|
||||||
// TODO: do we want to create the users which does not exist?
|
// TODO: do we want to create the users which does not exist?
|
||||||
return done(null, { username: profile.emails[0].value })
|
var user = this.db.users.find(u => u.username.toLowerCase() === profile.emails[0].value.toLowerCase())
|
||||||
}))
|
|
||||||
|
if (!user || !user.isActive) {
|
||||||
|
done(null, null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return done(null, user)
|
||||||
|
}).bind(this)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we should load the openid strategy
|
||||||
|
if (global.ServerSettings.authActiveAuthMethods.includes("openid")) {
|
||||||
|
passport.use(new OpenIDConnectStrategy({
|
||||||
|
issuer: global.ServerSettings.authOpenIDIssuerURL,
|
||||||
|
authorizationURL: global.ServerSettings.authOpenIDAuthorizationURL,
|
||||||
|
tokenURL: global.ServerSettings.authOpenIDTokenURL,
|
||||||
|
userInfoURL: global.ServerSettings.authOpenIDUserInfoURL,
|
||||||
|
clientID: global.ServerSettings.authOpenIDClientID,
|
||||||
|
clientSecret: global.ServerSettings.authOpenIDClientSecret,
|
||||||
|
callbackURL: global.ServerSettings.authOpenIDCallbackURL,
|
||||||
|
scope: ["openid", "email", "profile"],
|
||||||
|
skipUserProfile: false
|
||||||
|
},
|
||||||
|
(function (issuer, profile, done) {
|
||||||
|
// TODO: what to use as username
|
||||||
|
// TODO: do we want to create the users which does not exist?
|
||||||
|
var user = this.db.users.find(u => u.username.toLowerCase() === profile.emails[0].value.toLowerCase())
|
||||||
|
|
||||||
|
if (!user || !user.isActive) {
|
||||||
|
done(null, null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return done(null, user)
|
||||||
|
}).bind(this)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the JwtStrategy (always) -> for bearer token auth
|
// Load the JwtStrategy (always) -> for bearer token auth
|
||||||
@ -99,6 +135,18 @@ class Auth {
|
|||||||
}).bind(this)
|
}).bind(this)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// openid strategy login route (this redirects to the configured openid login provider)
|
||||||
|
router.get('/auth/openid', passport.authenticate('openidconnect'));
|
||||||
|
|
||||||
|
// openid strategy callback route (this receives the token from the configured openid login provider)
|
||||||
|
router.get('/auth/openid/callback',
|
||||||
|
passport.authenticate('openidconnect', { failureRedirect: '/login' }),
|
||||||
|
(function (req, res) {
|
||||||
|
// return the user login response json if the login was successfull
|
||||||
|
res.json(this.getUserLoginResponsePayload(req.user.username))
|
||||||
|
}).bind(this)
|
||||||
|
)
|
||||||
|
|
||||||
// Logout route
|
// Logout route
|
||||||
router.get('/logout', function (req, res) {
|
router.get('/logout', function (req, res) {
|
||||||
// TODO: invalidate possible JWTs
|
// TODO: invalidate possible JWTs
|
||||||
|
@ -67,6 +67,14 @@ class ServerSettings {
|
|||||||
this.authGoogleOauth20ClientSecret = ''
|
this.authGoogleOauth20ClientSecret = ''
|
||||||
this.authGoogleOauth20CallbackURL = ''
|
this.authGoogleOauth20CallbackURL = ''
|
||||||
|
|
||||||
|
// generic-oauth20 settings
|
||||||
|
this.authOpenIDIssuerURL = ''
|
||||||
|
this.authOpenIDAuthorizationURL = ''
|
||||||
|
this.authOpenIDTokenURL = ''
|
||||||
|
this.authOpenIDUserInfoURL = ''
|
||||||
|
this.authOpenIDClientID = ''
|
||||||
|
this.authOpenIDClientSecret = ''
|
||||||
|
this.authOpenIDCallbackURL = ''
|
||||||
|
|
||||||
if (settings) {
|
if (settings) {
|
||||||
this.construct(settings)
|
this.construct(settings)
|
||||||
@ -117,6 +125,14 @@ class ServerSettings {
|
|||||||
this.authGoogleOauth20ClientSecret = settings.authGoogleOauth20ClientSecret || ''
|
this.authGoogleOauth20ClientSecret = settings.authGoogleOauth20ClientSecret || ''
|
||||||
this.authGoogleOauth20CallbackURL = settings.authGoogleOauth20CallbackURL || ''
|
this.authGoogleOauth20CallbackURL = settings.authGoogleOauth20CallbackURL || ''
|
||||||
|
|
||||||
|
this.authOpenIDIssuerURL = settings.authOpenIDIssuerURL || ''
|
||||||
|
this.authOpenIDAuthorizationURL = settings.authOpenIDAuthorizationURL || ''
|
||||||
|
this.authOpenIDTokenURL = settings.authOpenIDTokenURL || ''
|
||||||
|
this.authOpenIDUserInfoURL = settings.authOpenIDUserInfoURL || ''
|
||||||
|
this.authOpenIDClientID = settings.authOpenIDClientID || ''
|
||||||
|
this.authOpenIDClientSecret = settings.authOpenIDClientSecret || ''
|
||||||
|
this.authOpenIDCallbackURL = settings.authOpenIDCallbackURL || ''
|
||||||
|
|
||||||
if (!Array.isArray(this.authActiveAuthMethods)) {
|
if (!Array.isArray(this.authActiveAuthMethods)) {
|
||||||
this.authActiveAuthMethods = ['local']
|
this.authActiveAuthMethods = ['local']
|
||||||
}
|
}
|
||||||
@ -131,6 +147,20 @@ class ServerSettings {
|
|||||||
this.authActiveAuthMethods.splice(this.authActiveAuthMethods.indexOf('google-oauth20', 0), 1);
|
this.authActiveAuthMethods.splice(this.authActiveAuthMethods.indexOf('google-oauth20', 0), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove uninitialized methods
|
||||||
|
// OpenID
|
||||||
|
if (this.authActiveAuthMethods.includes('generic-oauth20') && (
|
||||||
|
this.authOpenIDIssuerURL === '' ||
|
||||||
|
this.authOpenIDAuthorizationURL === '' ||
|
||||||
|
this.authOpenIDTokenURL === '' ||
|
||||||
|
this.authOpenIDUserInfoURL === '' ||
|
||||||
|
this.authOpenIDClientID === '' ||
|
||||||
|
this.authOpenIDClientSecret === '' ||
|
||||||
|
this.authOpenIDCallbackURL === ''
|
||||||
|
)) {
|
||||||
|
this.authActiveAuthMethods.splice(this.authActiveAuthMethods.indexOf('generic-oauth20', 0), 1);
|
||||||
|
}
|
||||||
|
|
||||||
// fallback to local
|
// fallback to local
|
||||||
if (!Array.isArray(this.authActiveAuthMethods) || this.authActiveAuthMethods.length == 0) {
|
if (!Array.isArray(this.authActiveAuthMethods) || this.authActiveAuthMethods.length == 0) {
|
||||||
this.authActiveAuthMethods = ['local']
|
this.authActiveAuthMethods = ['local']
|
||||||
@ -189,7 +219,14 @@ class ServerSettings {
|
|||||||
authActiveAuthMethods: this.authActiveAuthMethods,
|
authActiveAuthMethods: this.authActiveAuthMethods,
|
||||||
authGoogleOauth20ClientID: this.authGoogleOauth20ClientID, // Do not return to client
|
authGoogleOauth20ClientID: this.authGoogleOauth20ClientID, // Do not return to client
|
||||||
authGoogleOauth20ClientSecret: this.authGoogleOauth20ClientSecret, // Do not return to client
|
authGoogleOauth20ClientSecret: this.authGoogleOauth20ClientSecret, // Do not return to client
|
||||||
authGoogleOauth20CallbackURL: this.authGoogleOauth20CallbackURL
|
authGoogleOauth20CallbackURL: this.authGoogleOauth20CallbackURL,
|
||||||
|
authOpenIDIssuerURL: this.authOpenIDIssuerURL,
|
||||||
|
authOpenIDAuthorizationURL: this.authOpenIDAuthorizationURL,
|
||||||
|
authOpenIDTokenURL: this.authOpenIDTokenURL,
|
||||||
|
authOpenIDUserInfoURL: this.authOpenIDUserInfoURL,
|
||||||
|
authOpenIDClientID: this.authOpenIDClientID, // Do not return to client
|
||||||
|
authOpenIDClientSecret: this.authOpenIDClientSecret, // Do not return to client
|
||||||
|
authOpenIDCallbackURL: this.authOpenIDCallbackURL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,6 +235,8 @@ class ServerSettings {
|
|||||||
delete json.tokenSecret
|
delete json.tokenSecret
|
||||||
delete json.authGoogleOauth20ClientID
|
delete json.authGoogleOauth20ClientID
|
||||||
delete json.authGoogleOauth20ClientSecret
|
delete json.authGoogleOauth20ClientSecret
|
||||||
|
delete json.authOpenIDClientID
|
||||||
|
delete json.authOpenIDClientSecret
|
||||||
return json
|
return json
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user