Browse Source

sync third party profile on every login

pull/4023/head
Rory Powell 5 years ago
parent
commit
faf711e092
  1. 72
      packages/auth/src/middleware/passport/third-party-common.js

72
packages/auth/src/middleware/passport/third-party-common.js

@ -30,6 +30,7 @@ exports.authenticateThirdParty = async function (
// use the third party id // use the third party id
const userId = generateGlobalUserID(thirdPartyUser.userId) const userId = generateGlobalUserID(thirdPartyUser.userId)
// try to load by id
try { try {
dbUser = await db.get(userId) dbUser = await db.get(userId)
} catch (err) { } catch (err) {
@ -41,39 +42,45 @@ exports.authenticateThirdParty = async function (
err err
) )
} }
}
// check user already exists by email // fallback to loading by email
if (!dbUser) {
const users = await db.query(`database/${ViewNames.USER_BY_EMAIL}`, { const users = await db.query(`database/${ViewNames.USER_BY_EMAIL}`, {
key: thirdPartyUser.email, key: thirdPartyUser.email,
include_docs: true, include_docs: true,
}) })
const userExists = users.rows.length > 0
if (requireLocalAccount && !userExists) { if (users.rows.length > 0) {
dbUser = users.rows[0].doc
}
}
// exit early if there is still no user and auto creation is disabled
if (!dbUser && requireLocalAccount ) {
if (requireLocalAccount) {
return authError( return authError(
done, done,
"Email does not yet exist. You must set up your local budibase account first." "Email does not yet exist. You must set up your local budibase account first."
) )
} }
}
// create the user to save let user
let user // first time creation
if (userExists) { if (!dbUser) {
const existing = users.rows[0].doc user = constructNewUser(userId, thirdPartyUser)
user = constructMergedUser(userId, existing, thirdPartyUser) } else {
// existing user
// remove the local account to avoid conflicts user = constructMergedUser(userId, dbUser, thirdPartyUser)
await db.remove(existing._id, existing._rev) await db.remove(dbUser._id, dbUser._rev)
} else {
user = constructNewUser(userId, thirdPartyUser)
}
// save the user
const response = await db.post(user)
dbUser = user
dbUser._rev = response.rev
} }
// create or sync the user
const response = await db.post(user)
dbUser = user
dbUser._rev = response.rev
// authenticate // authenticate
const payload = { const payload = {
userId: dbUser._id, userId: dbUser._id,
@ -92,9 +99,10 @@ exports.authenticateThirdParty = async function (
* @returns a user object constructed from existing and third party information * @returns a user object constructed from existing and third party information
*/ */
function constructMergedUser(userId, existing, thirdPartyUser) { function constructMergedUser(userId, existing, thirdPartyUser) {
// sync third party fields
const user = constructNewUser(userId, thirdPartyUser) const user = constructNewUser(userId, thirdPartyUser)
// merge with existing account // merge existing fields
user.roles = existing.roles user.roles = existing.roles
user.builder = existing.builder user.builder = existing.builder
user.admin = existing.admin user.admin = existing.admin
@ -114,13 +122,27 @@ function constructNewUser(userId, thirdPartyUser) {
roles: {}, roles: {},
} }
// persist profile information
// @reviewers: Historically stored at the root level of the user
// Nest to prevent conflicts with future fields
// Is this okay to change?
if (thirdPartyUser.profile) { if (thirdPartyUser.profile) {
const profile = thirdPartyUser.profile
if (profile.name) {
const name = profile.name
// first name
if (name.givenName) {
user.firstName = name.givenName
}
// last name
if (name.familyName) {
user.lastName = name.familyName
}
}
// profile
// @reviewers: Historically stored at the root level of the user
// Nest to prevent conflicts with future fields
// Is this okay to change?
user.thirdPartyProfile = { user.thirdPartyProfile = {
...thirdPartyUser.profile._json, ...profile._json,
} }
} }

Loading…
Cancel
Save