Skip to content

Instantly share code, notes, and snippets.

@cchamikara
Last active March 20, 2021 20:58
Show Gist options
  • Save cchamikara/554a440aef0fbc305cff6ddc33850e20 to your computer and use it in GitHub Desktop.
Save cchamikara/554a440aef0fbc305cff6ddc33850e20 to your computer and use it in GitHub Desktop.
/**
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,
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment