Update OAuth2 Configuration

This commit is contained in:
yzx9 2023-11-22 15:32:01 +08:00
parent a40aec7677
commit b225d6a8ce
2 changed files with 33 additions and 23 deletions

View file

@ -126,6 +126,23 @@ LDAP_CONTACT_FILTER: (objectClass=person)
LDAP_CONTACTS: 'true' LDAP_CONTACTS: 'true'
``` ```
### OAuth2 Configuration
GitHub:
```
OAUTH2_CLIENT_ID: YOUR_CLIENT_ID
OAUTH2_CLIENT_SECRET: YOUR_CLIENT_SECRET
OAUTH2_SCOPE: YOUR_SCOPE
OAUTH2_AUTHORIZATION_URL: https://github.com/login/oauth/authorize
OAUTH2_TOKEN_URL: https://github.com/login/oauth/access_token
OAUTH2_PROFILE_URL: https://api.github.com/user
OAUTH2_USER_ATTR_EMAIL: email
OAUTH2_USER_ATTR_UID: id
OAUTH2_USER_ATTR_FIRSTNAME: name
OAUTH2_USER_ATTR_LASTNAME:
```
### Sharelatex Configuration ### Sharelatex Configuration
Edit SHARELATEX_ environment variables in [docker-compose.traefik.yml](docker-compose.traefik.yml) or [docker-compose.certbot.yml](docker-compose.certbot.yml) to fit your local setup Edit SHARELATEX_ environment variables in [docker-compose.traefik.yml](docker-compose.traefik.yml) or [docker-compose.certbot.yml](docker-compose.certbot.yml) to fit your local setup

View file

@ -276,11 +276,11 @@ const AuthenticationController = {
oauth2Redirect(req, res, next) { oauth2Redirect(req, res, next) {
const redirectURI = encodeURIComponent(`${process.env.SHARELATEX_SITE_URL}/oauth/callback`) const redirectURI = encodeURIComponent(`${process.env.SHARELATEX_SITE_URL}/oauth/callback`)
const next = ( const next = (
process.env.OAUTH_AUTH_URL process.env.OAUTH2_AUTHORIZATION_URL
+ `?response_type=code` + `?response_type=code`
+ `&client_id=${process.env.OAUTH_CLIENT_ID}` + `&client_id=${process.env.OAUTH2_CLIENT_ID}`
+ `&redirect_uri=${redirectURI}` + `&redirect_uri=${redirectURI}`
+ `&scope=${process.env.OAUTH_SCOPE}` // TODO: state + `&scope=${process.env.OAUTH2_SCOPE ?? ""}` // TODO: state
) )
res.redirect(next) res.redirect(next)
}, },
@ -288,49 +288,42 @@ const AuthenticationController = {
async oauth2Callback(req, res, next) { async oauth2Callback(req, res, next) {
try { try {
const redirectURI = encodeURIComponent(`${process.env.SHARELATEX_SITE_URL}/oauth/callback`); const redirectURI = encodeURIComponent(`${process.env.SHARELATEX_SITE_URL}/oauth/callback`);
const tokenResponse = await fetch(process.env.OAUTH_ACCESS_URL, { const tokenResponse = await fetch(process.env.OAUTH2_TOKEN_URL, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
body: JSON.stringify({ body: JSON.stringify({
grant_type: "authorization_code", grant_type: "authorization_code",
client_id: process.env.OAUTH_CLIENT_ID, client_id: process.env.OAUTH2_CLIENT_ID,
client_secret: process.env.OAUTH_CLIENT_SECRET, client_secret: process.env.OAUTH2_CLIENT_SECRET,
code: req.query.code, code: req.query.code,
redirect_uri: redirectURI, redirect_uri: redirectURI,
}) })
}) })
const tokenData = await tokenResponse.json() const tokenData = await tokenResponse.json()
console.log("OAuth2 respond", JSON.stringify(tokenData)) // TODO: remove console.log("OAuth2 respond", JSON.stringify(tokenData)) // TODO: remove
console.log("OAuth2 accessToken", tokenData.access_token) // TODO: remove console.log("OAuth2 accessToken", tokenData.access_token) // TODO: remove
const infoResponse = await fetch(process.env.OAUTH_USER_URL, { const profileResponse = await fetch(process.env.OAUTH2_PROFILE_URL, {
method: 'GET', method: 'GET',
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Authorization": `Bearer ${tokenData.access_token}` "Authorization": `Bearer ${tokenData.access_token}`
} }
}) })
const info = await infoResponse.json() const profile = await profileResponse.json()
console.log("OAuth2 user info", JSON.stringify(info.data)) console.log("OAuth2 user info", JSON.stringify(profile.data))
// TODO: legacy, check standard OAuth response const email = profile[process.env.OAUTH2_USER_ATTR_EMAIL ?? "email"]
if (info.data.err) { const uid = profile[process.env.OAUTH2_USER_ATTR_UID ?? "uid"]
res.json({message: info.data.err}) const firstname = profile?.[process.env.OAUTH2_USER_ATTR_FIRSTNAME] ?? email
return const lastname = profile?.[process.env.OAUTH2_USER_ATTR_LASTNAME] ?? ""
}
// TODO: check standard OAuth response
const mail = info.mail
const uid = info.uid
const firstname = info.givenName
const lastname = info.sn
const isAdmin = false // TODO: how to determine? const isAdmin = false // TODO: how to determine?
const query = { email: mail } const query = { email }
User.findOne(query, (error, user) => { User.findOne(query, (error, user) => {
if (error) { if (error) {
console.log(error) console.log(error)
@ -351,7 +344,7 @@ const AuthenticationController = {
uid, uid,
firstname, firstname,
lastname, lastname,
mail, email,
isAdmin isAdmin
) )
}) })