codimd/lib/auth/oauth2/strategy.ts
Raccoon ce5800b533
ts: lib/auth/oauth2/strategy.js
Signed-off-by: Raccoon <raccoon@hackmd.io>
2021-06-16 18:35:28 +08:00

72 lines
2.1 KiB
TypeScript

import {InternalOAuthError, Strategy} from "passport-oauth2";
import * as config from "../../config";
export function parseProfile (data) {
const username = extractProfileAttribute(data, config.oauth2.userProfileUsernameAttr)
const displayName = extractProfileAttribute(data, config.oauth2.userProfileDisplayNameAttr)
const email = extractProfileAttribute(data, config.oauth2.userProfileEmailAttr)
const photo = extractProfileAttribute(data, config.oauth2.userProfilePhotoAttr)
if (!username) {
throw new Error('cannot fetch username: please set correct CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR')
}
return {
id: username,
username: username,
displayName: displayName,
email: email,
photo: photo
}
}
export function extractProfileAttribute (data, path) {
if (!data) return undefined
if (typeof path !== 'string') return undefined
// can handle stuff like `attrs[0].name`
path = path.split('.')
for (const segment of path) {
const m = segment.match(/([\d\w]+)\[(.*)\]/)
if (!m) {
data = data[segment]
} else {
if (m.length < 3) return undefined
if (!data[m[1]]) return undefined
data = data[m[1]][m[2]]
}
if (!data) return undefined
}
return data
}
export class OAuth2CustomStrategy extends Strategy {
private _userProfileURL: any;
constructor (options, verify) {
options.customHeaders = options.customHeaders || {}
super(options, verify)
this.name = 'oauth2'
this._userProfileURL = options.userProfileURL
this._oauth2.useAuthorizationHeaderforGET(true)
}
userProfile (accessToken, done) {
this._oauth2.get(this._userProfileURL, accessToken, function (err, body, res) {
if (err) {
return done(new InternalOAuthError('Failed to fetch user profile', err))
}
let profile, json
try {
json = JSON.parse(body as any)
profile = parseProfile(json)
} catch (ex) {
return done(new InternalOAuthError('Failed to parse user profile' + ex.toString(), null))
}
profile.provider = 'oauth2'
done(null, profile)
})
}
}