Replace passport openidconnect plugin with openid-client, add JWKS and logout URL server settings, use email and email_verified instead of username

This commit is contained in:
advplyr 2023-11-04 15:36:43 -05:00
parent cfe0c2a986
commit 840811b464
5 changed files with 125 additions and 44 deletions

View File

@ -23,6 +23,10 @@
<ui-text-input-with-label ref="userInfoUrl" v-model="newAuthSettings.authOpenIDUserInfoURL" :disabled="savingSettings" :label="'Userinfo URL'" class="mb-2" /> <ui-text-input-with-label ref="userInfoUrl" v-model="newAuthSettings.authOpenIDUserInfoURL" :disabled="savingSettings" :label="'Userinfo URL'" class="mb-2" />
<ui-text-input-with-label ref="jwksUrl" v-model="newAuthSettings.authOpenIDJwksURL" :disabled="savingSettings" :label="'JWKS URL'" class="mb-2" />
<ui-text-input-with-label ref="logoutUrl" v-model="newAuthSettings.authOpenIDLogoutURL" :disabled="savingSettings" :label="'Logout URL'" class="mb-2" />
<ui-text-input-with-label ref="openidClientId" v-model="newAuthSettings.authOpenIDClientID" :disabled="savingSettings" :label="'Client ID'" class="mb-2" /> <ui-text-input-with-label ref="openidClientId" v-model="newAuthSettings.authOpenIDClientID" :disabled="savingSettings" :label="'Client ID'" class="mb-2" />
<ui-text-input-with-label ref="openidClientSecret" v-model="newAuthSettings.authOpenIDClientSecret" :disabled="savingSettings" :label="'Client Secret'" class="mb-2" /> <ui-text-input-with-label ref="openidClientSecret" v-model="newAuthSettings.authOpenIDClientSecret" :disabled="savingSettings" :label="'Client Secret'" class="mb-2" />
@ -97,6 +101,10 @@ export default {
this.$toast.error('Userinfo URL required') this.$toast.error('Userinfo URL required')
isValid = false isValid = false
} }
if (!this.newAuthSettings.authOpenIDJwksURL) {
this.$toast.error('JWKS URL required')
isValid = false
}
if (!this.newAuthSettings.authOpenIDClientID) { if (!this.newAuthSettings.authOpenIDClientID) {
this.$toast.error('Client ID required') this.$toast.error('Client ID required')
isValid = false isValid = false

91
package-lock.json generated
View File

@ -17,10 +17,10 @@
"htmlparser2": "^8.0.1", "htmlparser2": "^8.0.1",
"node-tone": "^1.0.1", "node-tone": "^1.0.1",
"nodemailer": "^6.9.2", "nodemailer": "^6.9.2",
"openid-client": "^5.6.1",
"passport": "^0.6.0", "passport": "^0.6.0",
"passport-google-oauth20": "^2.0.0", "passport-google-oauth20": "^2.0.0",
"passport-jwt": "^4.0.1", "passport-jwt": "^4.0.1",
"passport-openidconnect": "^0.1.1",
"sequelize": "^6.32.1", "sequelize": "^6.32.1",
"socket.io": "^4.5.4", "socket.io": "^4.5.4",
"sqlite3": "^5.1.6", "sqlite3": "^5.1.6",
@ -1343,6 +1343,14 @@
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"optional": true "optional": true
}, },
"node_modules/jose": {
"version": "4.15.4",
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz",
"integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==",
"funding": {
"url": "https://github.com/sponsors/panva"
}
},
"node_modules/jsonwebtoken": { "node_modules/jsonwebtoken": {
"version": "9.0.0", "version": "9.0.0",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz",
@ -1883,6 +1891,14 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/object-hash": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz",
"integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==",
"engines": {
"node": ">= 6"
}
},
"node_modules/object-inspect": { "node_modules/object-inspect": {
"version": "1.12.2", "version": "1.12.2",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
@ -1891,6 +1907,14 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/oidc-token-hash": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz",
"integrity": "sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==",
"engines": {
"node": "^10.13.0 || >=12.0.0"
}
},
"node_modules/on-finished": { "node_modules/on-finished": {
"version": "2.4.1", "version": "2.4.1",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
@ -1918,6 +1942,20 @@
"wrappy": "1" "wrappy": "1"
} }
}, },
"node_modules/openid-client": {
"version": "5.6.1",
"resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.6.1.tgz",
"integrity": "sha512-PtrWsY+dXg6y8mtMPyL/namZSYVz8pjXz3yJiBNZsEdCnu9miHLB4ELVC85WvneMKo2Rg62Ay7NkuCpM0bgiLQ==",
"dependencies": {
"jose": "^4.15.1",
"lru-cache": "^6.0.0",
"object-hash": "^2.2.0",
"oidc-token-hash": "^5.0.3"
},
"funding": {
"url": "https://github.com/sponsors/panva"
}
},
"node_modules/p-map": { "node_modules/p-map": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
@ -1997,22 +2035,6 @@
"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",
@ -3929,6 +3951,11 @@
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"optional": true "optional": true
}, },
"jose": {
"version": "4.15.4",
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz",
"integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ=="
},
"jsonwebtoken": { "jsonwebtoken": {
"version": "9.0.0", "version": "9.0.0",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz",
@ -4330,11 +4357,21 @@
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
}, },
"object-hash": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz",
"integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw=="
},
"object-inspect": { "object-inspect": {
"version": "1.12.2", "version": "1.12.2",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
"integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ=="
}, },
"oidc-token-hash": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz",
"integrity": "sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw=="
},
"on-finished": { "on-finished": {
"version": "2.4.1", "version": "2.4.1",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
@ -4356,6 +4393,17 @@
"wrappy": "1" "wrappy": "1"
} }
}, },
"openid-client": {
"version": "5.6.1",
"resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.6.1.tgz",
"integrity": "sha512-PtrWsY+dXg6y8mtMPyL/namZSYVz8pjXz3yJiBNZsEdCnu9miHLB4ELVC85WvneMKo2Rg62Ay7NkuCpM0bgiLQ==",
"requires": {
"jose": "^4.15.1",
"lru-cache": "^6.0.0",
"object-hash": "^2.2.0",
"oidc-token-hash": "^5.0.3"
}
},
"p-map": { "p-map": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
@ -4409,15 +4457,6 @@
"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",

View File

@ -39,10 +39,10 @@
"htmlparser2": "^8.0.1", "htmlparser2": "^8.0.1",
"node-tone": "^1.0.1", "node-tone": "^1.0.1",
"nodemailer": "^6.9.2", "nodemailer": "^6.9.2",
"openid-client": "^5.6.1",
"passport": "^0.6.0", "passport": "^0.6.0",
"passport-google-oauth20": "^2.0.0", "passport-google-oauth20": "^2.0.0",
"passport-jwt": "^4.0.1", "passport-jwt": "^4.0.1",
"passport-openidconnect": "^0.1.1",
"sequelize": "^6.32.1", "sequelize": "^6.32.1",
"socket.io": "^4.5.4", "socket.io": "^4.5.4",
"sqlite3": "^5.1.6", "sqlite3": "^5.1.6",

View File

@ -5,8 +5,9 @@ const LocalStrategy = require('./libs/passportLocal')
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
const OpenIDConnectStrategy = require('passport-openidconnect') const OpenIDClient = require('openid-client')
const Database = require('./Database') const Database = require('./Database')
const Logger = require('./Logger')
/** /**
* @class Class for handling all the authentication related functionality. * @class Class for handling all the authentication related functionality.
@ -62,20 +63,33 @@ class Auth {
// Check if we should load the openid strategy // Check if we should load the openid strategy
if (global.ServerSettings.authActiveAuthMethods.includes("openid")) { if (global.ServerSettings.authActiveAuthMethods.includes("openid")) {
passport.use(new OpenIDConnectStrategy({ const openIdIssuerClient = new OpenIDClient.Issuer({
issuer: global.ServerSettings.authOpenIDIssuerURL, issuer: global.ServerSettings.authOpenIDIssuerURL,
authorizationURL: global.ServerSettings.authOpenIDAuthorizationURL, authorization_endpoint: global.ServerSettings.authOpenIDAuthorizationURL,
tokenURL: global.ServerSettings.authOpenIDTokenURL, token_endpoint: global.ServerSettings.authOpenIDTokenURL,
userInfoURL: global.ServerSettings.authOpenIDUserInfoURL, userinfo_endpoint: global.ServerSettings.authOpenIDUserInfoURL,
clientID: global.ServerSettings.authOpenIDClientID, jwks_uri: global.ServerSettings.authOpenIDJwksURL
clientSecret: global.ServerSettings.authOpenIDClientSecret, }).Client
callbackURL: '/auth/openid/callback', const openIdClient = new openIdIssuerClient({
scope: ["openid", "email", "profile"], client_id: global.ServerSettings.authOpenIDClientID,
skipUserProfile: false client_secret: global.ServerSettings.authOpenIDClientSecret
}, async (issuer, profile, done) => { })
// TODO: do we want to create the users which does not exist? const openIdClientStrategy = new OpenIDClient.Strategy({
client: openIdClient,
params: {
redirect_uri: '/auth/openid/callback',
scope: 'openid profile email'
}
}, async (tokenset, userinfo, done) => {
// TODO: Here is where to lookup the Abs user or register a new Abs user
Logger.debug(`[Auth] openid callback userinfo=`, userinfo)
const user = await Database.userModel.getUserByUsername(profile.username) let user = null
// TODO: Temporary lookup existing user by email. May be replaced by a setting to toggle this or use name
if (userinfo.email && userinfo.email_verified) {
user = await Database.userModel.getUserByEmail(userinfo.email)
// TODO: If using existing user then save userinfo.sub on user
}
if (!user?.isActive) { if (!user?.isActive) {
// deny login // deny login
@ -85,7 +99,12 @@ class Auth {
// permit login // permit login
return done(null, user) return done(null, user)
})) })
// The strategy name is set to the issuer hostname by default but didnt' see a way to override this
// @see https://github.com/panva/node-openid-client/blob/a84d022f195f82ca1c97f8f6b2567ebcef8738c3/lib/passport_strategy.js#L75
openIdClientStrategy.name = 'openid-client'
passport.use(openIdClientStrategy)
} }
// Load the JwtStrategy (always) -> for bearer token auth // Load the JwtStrategy (always) -> for bearer token auth
@ -99,7 +118,7 @@ class Auth {
process.nextTick(function () { process.nextTick(function () {
// only store id to session // only store id to session
return cb(null, JSON.stringify({ return cb(null, JSON.stringify({
"id": user.id, id: user.id,
})) }))
}) })
}) })
@ -216,7 +235,13 @@ class Auth {
// openid strategy login route (this redirects to the configured openid login provider) // openid strategy login route (this redirects to the configured openid login provider)
router.get('/auth/openid', (req, res, next) => { router.get('/auth/openid', (req, res, next) => {
const auth_func = passport.authenticate('openidconnect') // This is a (temporary?) hack to not have to get the full redirect URL from the user
// it uses the URL made in this request and adds the relative URL /auth/openid/callback
const strategy = passport._strategy('openid-client')
strategy._params.redirect_uri = new URL(`${req.protocol}://${req.get('host')}/auth/openid/callback`).toString()
const auth_func = passport.authenticate('openid-client')
// params (isRest, callback) to a cookie that will be send to the client // params (isRest, callback) to a cookie that will be send to the client
this.paramsToCookies(req, res) this.paramsToCookies(req, res)
auth_func(req, res, next) auth_func(req, res, next)
@ -224,7 +249,7 @@ class Auth {
// openid strategy callback route (this receives the token from the configured openid login provider) // openid strategy callback route (this receives the token from the configured openid login provider)
router.get('/auth/openid/callback', router.get('/auth/openid/callback',
passport.authenticate('openidconnect'), passport.authenticate('openid-client'),
// on a successfull login: read the cookies and react like the client requested (callback or json) // on a successfull login: read the cookies and react like the client requested (callback or json)
this.handleLoginSuccessBasedOnCookie.bind(this)) this.handleLoginSuccessBasedOnCookie.bind(this))

View File

@ -68,6 +68,8 @@ class ServerSettings {
this.authOpenIDAuthorizationURL = '' this.authOpenIDAuthorizationURL = ''
this.authOpenIDTokenURL = '' this.authOpenIDTokenURL = ''
this.authOpenIDUserInfoURL = '' this.authOpenIDUserInfoURL = ''
this.authOpenIDJwksURL = ''
this.authOpenIDLogoutURL = ''
this.authOpenIDClientID = '' this.authOpenIDClientID = ''
this.authOpenIDClientSecret = '' this.authOpenIDClientSecret = ''
this.authOpenIDButtonText = 'Login with OpenId' this.authOpenIDButtonText = 'Login with OpenId'
@ -122,6 +124,8 @@ class ServerSettings {
this.authOpenIDAuthorizationURL = settings.authOpenIDAuthorizationURL || '' this.authOpenIDAuthorizationURL = settings.authOpenIDAuthorizationURL || ''
this.authOpenIDTokenURL = settings.authOpenIDTokenURL || '' this.authOpenIDTokenURL = settings.authOpenIDTokenURL || ''
this.authOpenIDUserInfoURL = settings.authOpenIDUserInfoURL || '' this.authOpenIDUserInfoURL = settings.authOpenIDUserInfoURL || ''
this.authOpenIDJwksURL = settings.authOpenIDJwksURL || ''
this.authOpenIDLogoutURL = settings.authOpenIDLogoutURL || ''
this.authOpenIDClientID = settings.authOpenIDClientID || '' this.authOpenIDClientID = settings.authOpenIDClientID || ''
this.authOpenIDClientSecret = settings.authOpenIDClientSecret || '' this.authOpenIDClientSecret = settings.authOpenIDClientSecret || ''
this.authOpenIDButtonText = settings.authOpenIDButtonText || 'Login with OpenId' this.authOpenIDButtonText = settings.authOpenIDButtonText || 'Login with OpenId'
@ -148,6 +152,7 @@ class ServerSettings {
this.authOpenIDAuthorizationURL === '' || this.authOpenIDAuthorizationURL === '' ||
this.authOpenIDTokenURL === '' || this.authOpenIDTokenURL === '' ||
this.authOpenIDUserInfoURL === '' || this.authOpenIDUserInfoURL === '' ||
this.authOpenIDJwksURL === '' ||
this.authOpenIDClientID === '' || this.authOpenIDClientID === '' ||
this.authOpenIDClientSecret === '' this.authOpenIDClientSecret === ''
)) { )) {
@ -224,6 +229,8 @@ class ServerSettings {
authOpenIDAuthorizationURL: this.authOpenIDAuthorizationURL, authOpenIDAuthorizationURL: this.authOpenIDAuthorizationURL,
authOpenIDTokenURL: this.authOpenIDTokenURL, authOpenIDTokenURL: this.authOpenIDTokenURL,
authOpenIDUserInfoURL: this.authOpenIDUserInfoURL, authOpenIDUserInfoURL: this.authOpenIDUserInfoURL,
authOpenIDJwksURL: this.authOpenIDJwksURL,
authOpenIDLogoutURL: this.authOpenIDLogoutURL,
authOpenIDClientID: this.authOpenIDClientID, // Do not return to client authOpenIDClientID: this.authOpenIDClientID, // Do not return to client
authOpenIDClientSecret: this.authOpenIDClientSecret, // Do not return to client authOpenIDClientSecret: this.authOpenIDClientSecret, // Do not return to client
authOpenIDButtonText: this.authOpenIDButtonText, authOpenIDButtonText: this.authOpenIDButtonText,
@ -251,6 +258,8 @@ class ServerSettings {
authOpenIDAuthorizationURL: this.authOpenIDAuthorizationURL, authOpenIDAuthorizationURL: this.authOpenIDAuthorizationURL,
authOpenIDTokenURL: this.authOpenIDTokenURL, authOpenIDTokenURL: this.authOpenIDTokenURL,
authOpenIDUserInfoURL: this.authOpenIDUserInfoURL, authOpenIDUserInfoURL: this.authOpenIDUserInfoURL,
authOpenIDJwksURL: this.authOpenIDJwksURL,
authOpenIDLogoutURL: this.authOpenIDLogoutURL,
authOpenIDClientID: this.authOpenIDClientID, // Do not return to client authOpenIDClientID: this.authOpenIDClientID, // Do not return to client
authOpenIDClientSecret: this.authOpenIDClientSecret, // Do not return to client authOpenIDClientSecret: this.authOpenIDClientSecret, // Do not return to client
authOpenIDButtonText: this.authOpenIDButtonText, authOpenIDButtonText: this.authOpenIDButtonText,