fix(auth): add state parameters and PKCE support

Only the OAuth2 auth strategy was using the state parameter,
which should be used as described in the RFC. The other
auth strategies such as GitHub, GitLab or Google were lacking
the state parameter.
This change adds the required state parameter as well as
enabling PKCE support on providers where it's possible.

Signed-off-by: Erik Michelson <github@erik.michelson.eu>
This commit is contained in:
Erik Michelson
2025-12-03 21:07:56 +01:00
parent 53f2ada7a3
commit 35f36fccba
12 changed files with 53 additions and 24 deletions

View File

@@ -104,7 +104,8 @@ module.exports = {
tokenURL: undefined,
clientID: undefined,
clientSecret: undefined,
scope: undefined
scope: undefined,
pkce: false
},
facebook: {
clientID: undefined,

View File

@@ -115,7 +115,8 @@ module.exports = {
clientSecret: process.env.CMD_OAUTH2_CLIENT_SECRET,
scope: process.env.CMD_OAUTH2_SCOPE,
rolesClaim: process.env.CMD_OAUTH2_ROLES_CLAIM,
accessRole: process.env.CMD_OAUTH2_ACCESS_ROLE
accessRole: process.env.CMD_OAUTH2_ACCESS_ROLE,
pkce: toBooleanConfig(process.env.CMD_OAUTH2_PKCE)
},
dropbox: {
clientID: process.env.CMD_DROPBOX_CLIENTID,

View File

@@ -12,7 +12,9 @@ passport.use(new DropboxStrategy({
apiVersion: '2',
clientID: config.dropbox.clientID,
clientSecret: config.dropbox.clientSecret,
callbackURL: config.serverURL + '/auth/dropbox/callback'
callbackURL: config.serverURL + '/auth/dropbox/callback',
state: true,
pkce: true
}, passportGeneralCallback))
dropboxAuth.get('/auth/dropbox', function (req, res, next) {

View File

@@ -12,7 +12,9 @@ const facebookAuth = module.exports = Router()
passport.use(new FacebookStrategy({
clientID: config.facebook.clientID,
clientSecret: config.facebook.clientSecret,
callbackURL: config.serverURL + '/auth/facebook/callback'
callbackURL: config.serverURL + '/auth/facebook/callback',
state: true,
pkce: true
}, passportGeneralCallback))
facebookAuth.get('/auth/facebook', function (req, res, next) {

View File

@@ -12,7 +12,9 @@ const githubAuth = module.exports = Router()
passport.use(new GithubStrategy({
clientID: config.github.clientID,
clientSecret: config.github.clientSecret,
callbackURL: config.serverURL + '/auth/github/callback'
callbackURL: config.serverURL + '/auth/github/callback',
pkce: true,
state: true
}, passportGeneralCallback))
githubAuth.get('/auth/github', function (req, res, next) {

View File

@@ -14,7 +14,9 @@ passport.use(new GitlabStrategy({
clientID: config.gitlab.clientID,
clientSecret: config.gitlab.clientSecret,
scope: config.gitlab.scope,
callbackURL: config.serverURL + '/auth/gitlab/callback'
callbackURL: config.serverURL + '/auth/gitlab/callback',
pkce: true,
state: true
}, passportGeneralCallback))
gitlabAuth.get('/auth/gitlab', function (req, res, next) {

View File

@@ -12,7 +12,9 @@ passport.use(new GoogleStrategy({
clientID: config.google.clientID,
clientSecret: config.google.clientSecret,
callbackURL: config.serverURL + '/auth/google/callback',
userProfileURL: 'https://www.googleapis.com/oauth2/v3/userinfo'
userProfileURL: 'https://www.googleapis.com/oauth2/v3/userinfo',
pkce: true,
state: true
}, passportGeneralCallback))
googleAuth.get('/auth/google', function (req, res, next) {

View File

@@ -16,7 +16,8 @@ const mattermostStrategy = new OAuthStrategy({
tokenURL: config.mattermost.baseURL + '/oauth/access_token',
clientID: config.mattermost.clientID,
clientSecret: config.mattermost.clientSecret,
callbackURL: config.serverURL + '/auth/mattermost/callback'
callbackURL: config.serverURL + '/auth/mattermost/callback',
state: true
}, passportGeneralCallback)
mattermostStrategy.userProfile = (accessToken, done) => {

View File

@@ -138,6 +138,7 @@ passport.use(new OAuth2CustomStrategy({
callbackURL: config.serverURL + '/auth/oauth2/callback',
userProfileURL: config.oauth2.userProfileURL,
scope: config.oauth2.scope,
pkce: config.oauth2.pkce,
state: true
}, passportGeneralCallback))