Casper Alant
Casper Alant

Reputation: 462

How do you create a Cognito user and get their accountId or cognitoIdentityId?

I'm using Appsync with the AWS_IAM authorization type. The identity of the user is provided in the $context.identity of the resolver:

{
"accountId": "123456789",
"cognitoIdentityAuthProvider": "\"cognito-idp.eu-west-1.amazonaws.com/eu-west-1_ABCDABCD\",\"cognito-idp.eu-west-1.amazonaws.com/eu-west-1_ABCDABCD:CognitoSignIn:SomeGuid\"",
"cognitoIdentityAuthType": "authenticated",
"cognitoIdentityId": "eu-west-1:SomeGuid",
"cognitoIdentityPoolId": "eu-west-1:SomeGuid",
"sourceIp": [
    "123.456.78.9"
],
"userArn": "arn:aws:sts::123456789:assumed-role/some-role-name/CognitoIdentityCredentials",
"username": "ABCD1234:CognitoIdentityCredentials"
}

For now I'm using the cognitoIdentityId as the primary identifier of the user in my application. I'm happy to switch to accountId if needs be. My only requirement is that the primary identifier comes from identity object shown above, since I don't want to add additional request just to get the ID.

The problem: I have a workflow that requires a user to exist before the person logs in and uses the application. So I need to create the user and assign data to it. Somewhere down the line, the person may actually login for the first time and should have access to data that has been assigned to the user.

I can create the user in Cognito, but I can't seem to find a way to retrieve or generate the accountId or the cognitoIdentityId of the user that they would have when they eventually login to the application. Please help.

Edit #1

I figured out accountId has nothing to do with the user identity. It is the accountId of the AWS user that deployed the service (Appsync or Cognito, I don't know). So it is the same for all users.

So my question remains, how do I generate or retrieve the cognitoIdentityId of a user after creating it in the Cognito User Pool?

Upvotes: 0

Views: 842

Answers (1)

Casper Alant
Casper Alant

Reputation: 462

I figured out a solution the essentially logs in as the user in order to get Cognito Identity ID:

import { config, CognitoIdentityServiceProvider, CognitoIdentity } from 'aws-sdk';
config.update({
  region: process.env.REGION,
  apiVersions: {
    cognitoidentityserviceprovider: '2016-04-18',
    cognitoidentity: '2014-06-30',
    // other service API versions
  }
});

export async function createUser(name: string, given_name: string, family_name: string, phone_number: string) {
  var cognitoidentityserviceprovider = new CognitoIdentityServiceProvider();
  var params = {
    UserPoolId: process.env.USER_POOL_ID,
    Username: phone_number, /* required */
    MessageAction: "SUPPRESS",
    UserAttributes: [
      {
        Name: 'name', /* required */
        Value: name
      },
      {
        Name: 'given_name', /* required */
        Value: given_name
      },
      {
        Name: 'family_name', /* required */
        Value: family_name
      },
      {
        Name: 'phone_number', /* required */
        Value: phone_number
      },
      {
         Name: "phone_number_verified",
         Value: "true"
      }
    ]
  };

  console.log("adminCreateUser")
  let adminCreateUserResonse: CognitoIdentityServiceProvider.AdminCreateUserResponse = await new Promise(resolve => {
    cognitoidentityserviceprovider.adminCreateUser(params, function(err, data) {
      if (err) console.log(err, err.stack); // an error occurred
      else {
        console.log(data);           // successful response
        console.log("adminCreateUser complete")
        resolve(data)
      }
    })
  });

  let identity: CognitoIdentity.GetIdResponse = await new Promise(resolve => {
    setPassword(phone_number, resolve)
  });

  let user_attributes = adminCreateUserResonse.User.Attributes
  let sub = user_attributes.find(a => a.Name == "sub")

}

function setPassword(phone_number: string, resolve: any) {
  var cognitoidentityserviceprovider = new CognitoIdentityServiceProvider();
  let password = generator.generate({
    length: 32,
    numbers: true,
    symbols: true,
    lowercase: true,
    uppercase: true
  });

  var setPasswordParams = {
    Password: password, /* required */
    UserPoolId: process.env.USER_POOL_ID, /* required */
    Username: phone_number, /* required */
    Permanent: true
  };

  console.log("adminSetUserPassword")
  cognitoidentityserviceprovider.adminSetUserPassword(setPasswordParams, function(err, data) {
    if (err) console.log(err, err.stack); // an error occurred
    else {
      console.log(data);           // successful response
      console.log("adminSetUserPassword complete")
      initiateAuth(phone_number, password, resolve)
    }
  })
}

function initiateAuth(phone_number: string, password: string, resolve: any) {
  var cognitoidentityserviceprovider = new CognitoIdentityServiceProvider();
  let initiateAuthParams = {
    AuthFlow: "ADMIN_USER_PASSWORD_AUTH",
    AuthParameters: {
      "USERNAME" : phone_number,
      "PASSWORD" : password
    },
    UserPoolId: process.env.USER_POOL_ID, /* required */
    ClientId: process.env.CLIENT_ID
  }
  console.log("adminInitiateAuth")
  cognitoidentityserviceprovider.adminInitiateAuth(initiateAuthParams, function(err, data) {
    if (err) console.log(err, err.stack); // an error occurred
    else {
      console.log(data);           // successful response
      console.log("adminInitiateAuth complete")
      getId(data, resolve)
    }
  })
}

function getId(data: CognitoIdentityServiceProvider.AdminInitiateAuthResponse, resolve: any) {
  const cognitoidentity = new CognitoIdentity()
  let login_provider = "cognito-idp." + process.env.REGION + ".amazonaws.com/" + process.env.USER_POOL_ID
  console.log("login_provider: " + login_provider)
  let getIdParams = {
    "AccountId": process.env.AWS_ACCOUNT_ID,
    "IdentityPoolId": process.env.IDENTITY_POOL_ID,
    "Logins": {}
  }
  getIdParams.Logins[login_provider] = data.AuthenticationResult.IdToken
  console.log("getId")
  cognitoidentity.getId(getIdParams, function(err, data) {
    if (err) console.log(err, err.stack); // an error occurred
    else {
      console.log(data);           // successful response
      console.log("getId complete")
      resolve(data)
    }
  })
}

Upvotes: 1

Related Questions