|
/** |
|
If User logged in using social login |
|
|
|
i). create cognate user using email and a random password |
|
ii). then create social user and link it to Cognito user |
|
|
|
**/ |
|
const { CognitoIdentityServiceProvider } = require("aws-sdk"); |
|
|
|
const handler = async (event) => { |
|
const userPoolId = event.userPoolId; |
|
const trigger = event.triggerSource; |
|
const email = event.request.userAttributes.email; |
|
const givenName = event.request.userAttributes.given_name; |
|
const familyName = event.request.userAttributes.family_name; |
|
const emailVerified = event.request.userAttributes.email_verified; |
|
const identity = event.userName; |
|
const client = new CognitoIdentityServiceProvider(); |
|
|
|
console.log("emailVerified", emailVerified); |
|
|
|
if (trigger === "PreSignUp_ExternalProvider") { |
|
await client |
|
.listUsers({ |
|
UserPoolId: userPoolId, |
|
AttributesToGet: ["email", "family_name", "given_name"], |
|
Filter: `email = "${email}"`, |
|
}) |
|
.promise() |
|
.then(({ Users }) => |
|
Users.sort((a, b) => |
|
a.UserCreateDate > b.UserCreateDate ? 1 : -1 |
|
) |
|
) |
|
.then((users) => (users.length > 0 ? users[0] : null)) |
|
.then(async (user) => { |
|
// user with username password already exists, do nothing |
|
if (user) { |
|
return user; |
|
} |
|
|
|
// user with username password does not exists, create one |
|
const newUser = await client |
|
.adminCreateUser({ |
|
UserPoolId: userPoolId, |
|
Username: email, |
|
MessageAction: "SUPPRESS", // dont send email to user |
|
UserAttributes: [ |
|
{ |
|
Name: "given_name", |
|
Value: givenName, |
|
}, |
|
{ |
|
Name: "family_name", |
|
Value: familyName, |
|
}, |
|
{ |
|
Name: "email", |
|
Value: email, |
|
}, |
|
{ |
|
Name: "email_verified", |
|
Value: emailVerified, |
|
}, |
|
], |
|
}) |
|
.promise(); |
|
|
|
console.log("newUser", JSON.stringify(newUser)); |
|
|
|
try { |
|
// gotta set the password, else user wont be able to reset it |
|
const randomPassword = Math.random() |
|
.toString(36) |
|
.substring(2); |
|
|
|
await client |
|
.adminSetUserPassword({ |
|
UserPoolId: userPoolId, |
|
Username: newUser.User.Username, |
|
Password: randomPassword, |
|
Permanent: true, |
|
}) |
|
.promise(); |
|
} catch (e) { |
|
console.log("password error: ", e); |
|
} |
|
|
|
return newUser.User.Username; |
|
}) |
|
.then((username) => { |
|
// link external user to cognito user |
|
const split = identity.split("_"); |
|
const providerValue = split.length > 1 ? split[1] : null; |
|
const provider = ["Google", "Facebook"].find( |
|
(val) => split[0].toUpperCase() === val.toUpperCase() |
|
); |
|
|
|
if (!provider || !providerValue) { |
|
return Promise.reject(new Error("Invalid external user")); |
|
} |
|
|
|
return client |
|
.adminLinkProviderForUser({ |
|
UserPoolId: userPoolId, |
|
DestinationUser: { |
|
ProviderName: "Cognito", |
|
ProviderAttributeValue: username, |
|
}, |
|
SourceUser: { |
|
ProviderName: provider, |
|
ProviderAttributeName: "Cognito_Subject", |
|
ProviderAttributeValue: providerValue, |
|
}, |
|
}) |
|
.promise(); |
|
}); |
|
} |
|
|
|
return event; |
|
}; |
|
|
|
module.exports = { |
|
handler, |
|
}; |