Skip to content

Instantly share code, notes, and snippets.

@onhate
Last active December 19, 2024 13:59
Show Gist options
  • Select an option

  • Save onhate/67797decbb5a262786cea405f8bf29a1 to your computer and use it in GitHub Desktop.

Select an option

Save onhate/67797decbb5a262786cea405f8bf29a1 to your computer and use it in GitHub Desktop.

Revisions

  1. onhate revised this gist Feb 9, 2022. 1 changed file with 49 additions and 28 deletions.
    77 changes: 49 additions & 28 deletions pre-signup.ts
    Original file line number Diff line number Diff line change
    @@ -1,46 +1,67 @@
    import { PreSignUpTriggerEvent, PreSignUpTriggerHandler } from 'aws-lambda';
    import { CognitoIdentityServiceProvider } from 'aws-sdk';

    const providerName = {
    const cognito = new CognitoIdentityServiceProvider();

    const knownProviderNames = {
    google: 'Google',
    facebook: 'Facebook'
    };

    const getProviderName = async (userPoolId: string, providerName: string) => {
    if (knownProviderNames[providerName]) {
    return knownProviderNames[providerName];
    }

    const { Providers } = await cognito.listIdentityProviders({ UserPoolId: userPoolId }).promise();
    for (const provider of Providers) {
    if (provider.ProviderName.toLowerCase() === providerName.toLowerCase()) {
    return provider.ProviderName;
    }
    }
    };

    const tryMergeUserAccounts = async (event: PreSignUpTriggerEvent) => {
    const { userPoolId, userName } = event;
    const { email } = event.request.userAttributes;
    const [provider, providerValue] = userName.split('_');
    const [provider, ...providerValues] = userName.split('_');
    const providerValue = providerValues.join('_');

    // merge social provider with existing cognito user by email
    if (['facebook', 'google'].includes(provider) && providerValue) {
    const cognito = new CognitoIdentityServiceProvider();
    const { Users } = await cognito
    .listUsers({
    UserPoolId: userPoolId,
    AttributesToGet: ['email'],
    Filter: `email = "${email}"`
    })
    .promise();

    for (const user of Users) {
    await cognito
    .adminLinkProviderForUser({
    if (provider.length > 0 && providerValue.length > 0) {
    const [{ Users }, providerName] = await Promise.all([
    cognito
    .listUsers({
    UserPoolId: userPoolId,
    DestinationUser: {
    ProviderName: 'Cognito',
    ProviderAttributeValue: user.Username
    },
    SourceUser: {
    ProviderName: providerName[provider],
    ProviderAttributeName: 'Cognito_Subject',
    ProviderAttributeValue: providerValue
    }
    AttributesToGet: ['email'],
    Filter: `email = "${email}"`,
    Limit: 1
    })
    .promise();
    }
    .promise(),
    getProviderName(userPoolId, provider)
    ]);

    // return true to indicate users were merged
    return Users.length > 0;
    if (providerName && Users.length > 0) {
    for (const user of Users) {
    await cognito
    .adminLinkProviderForUser({
    UserPoolId: userPoolId,
    DestinationUser: {
    ProviderName: 'Cognito',
    ProviderAttributeValue: user.Username
    },
    SourceUser: {
    ProviderName: providerName,
    ProviderAttributeName: 'Cognito_Subject',
    ProviderAttributeValue: providerValue
    }
    })
    .promise();
    }

    // return true to indicate users were merged
    return true;
    }
    }

    return false;
  2. onhate created this gist Jun 3, 2021.
    53 changes: 53 additions & 0 deletions pre-signup.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,53 @@
    import { PreSignUpTriggerEvent, PreSignUpTriggerHandler } from 'aws-lambda';
    import { CognitoIdentityServiceProvider } from 'aws-sdk';

    const providerName = {
    google: 'Google',
    facebook: 'Facebook'
    };

    const tryMergeUserAccounts = async (event: PreSignUpTriggerEvent) => {
    const { userPoolId, userName } = event;
    const { email } = event.request.userAttributes;
    const [provider, providerValue] = userName.split('_');

    // merge social provider with existing cognito user by email
    if (['facebook', 'google'].includes(provider) && providerValue) {
    const cognito = new CognitoIdentityServiceProvider();
    const { Users } = await cognito
    .listUsers({
    UserPoolId: userPoolId,
    AttributesToGet: ['email'],
    Filter: `email = "${email}"`
    })
    .promise();

    for (const user of Users) {
    await cognito
    .adminLinkProviderForUser({
    UserPoolId: userPoolId,
    DestinationUser: {
    ProviderName: 'Cognito',
    ProviderAttributeValue: user.Username
    },
    SourceUser: {
    ProviderName: providerName[provider],
    ProviderAttributeName: 'Cognito_Subject',
    ProviderAttributeValue: providerValue
    }
    })
    .promise();
    }

    // return true to indicate users were merged
    return Users.length > 0;
    }

    return false;
    };

    export const handler: PreSignUpTriggerHandler = async (event, _, callback) => {
    // continue the flow only if did not link providers
    const wereUsersMerged = await tryMergeUserAccounts(event);
    return wereUsersMerged ? undefined : callback(null, event);
    };