sync third party profile on every login
This commit is contained in:
parent
7db8658518
commit
8bea18e696
|
@ -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
|
|
||||||
if (userExists) {
|
|
||||||
const existing = users.rows[0].doc
|
|
||||||
user = constructMergedUser(userId, existing, thirdPartyUser)
|
|
||||||
|
|
||||||
// remove the local account to avoid conflicts
|
|
||||||
await db.remove(existing._id, existing._rev)
|
|
||||||
} else {
|
|
||||||
user = constructNewUser(userId, thirdPartyUser)
|
|
||||||
}
|
|
||||||
|
|
||||||
// save the user
|
|
||||||
const response = await db.post(user)
|
|
||||||
dbUser = user
|
|
||||||
dbUser._rev = response.rev
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let user
|
||||||
|
// first time creation
|
||||||
|
if (!dbUser) {
|
||||||
|
user = constructNewUser(userId, thirdPartyUser)
|
||||||
|
} else {
|
||||||
|
// existing user
|
||||||
|
user = constructMergedUser(userId, dbUser, thirdPartyUser)
|
||||||
|
await db.remove(dbUser._id, dbUser._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…
Reference in New Issue