Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AWS Cognito client SDK v3 returns 'byteLength' of undefined when running Admin disable user command #2160

Closed
Monir-Shembesh opened this issue Mar 21, 2021 · 11 comments
Labels
bug This issue is a bug.

Comments

@Monir-Shembesh
Copy link

Describe the bug

I am trying to disable users from my node JS backend using the AWS SDK v3. everything works normally except for the disable/enable user command.

Your environment

SDK version number

"@aws-sdk/client-cognito-identity-provider": "^3.8.1",

Is the issue in the browser/Node.js/ReactNative?

Node.js

Details of the browser/Node.js/ReactNative version

v14.16.0

Steps to reproduce

const aws_creds = {
  accessKeyId: process.env.ACCESS_KEY_ID,
  secretAccessKey: process.env.SECRET_ACCESS_KEY,
};
const cognitoConfig = {
  region: process.env.REGION,
  credentials: aws_creds,
};

const cognito_v3 = new CognitoIdentityProviderClient(cognitoConfig);

Then in my route I am running this try / catch block

try {
    if (status === "enable") {
      const enableUserCommand = new AdminEnableUserCommand(userDetails);
      const enableUserResults = await cognito_v3.send(enableUserCommand);
      return res.status(200).json(enableUserResults);
    }
    const disableUserCommand = new AdminDisableUserCommand(userDetails);
    const disableUserResults = await cognito_v3.send(disableUserCommand);
    return res.status(200).json(disableUserResults);
  } catch (err) {
    console.log(err);
    return res.status(400).json(err);
  }

Observed behavior

Returns the following error

TypeError: Cannot read property 'byteLength' of undefined
    at Object.fromArrayBuffer (C:\Users\SER-01\Documents\ctr\simsim\simsim-backend\lambdas\simsim-auth\node_modules\@aws-sdk\util-buffer-from\dist\cjs\index.js:6:60)
    at castSourceData (C:\Users\SER-01\Documents\ctr\simsim\simsim-backend\lambdas\simsim-auth\node_modules\@aws-sdk\hash-node\dist\cjs\index.js:29:31)
    at Hash.update (C:\Users\SER-01\Documents\ctr\simsim\simsim-backend\lambdas\simsim-auth\node_modules\@aws-sdk\hash-node\dist\cjs\index.js:12:26)
    at hmac (C:\Users\SER-01\Documents\ctr\simsim\simsim-backend\lambdas\simsim-auth\node_modules\@aws-sdk\signature-v4\dist\cjs\credentialDerivation.js:60:10)
    at Object.getSigningKey (C:\Users\SER-01\Documents\ctr\simsim\simsim-backend\lambdas\simsim-auth\node_modules\@aws-sdk\signature-v4\dist\cjs\credentialDerivation.js:32:29)
    at SignatureV4.getSigningKey (C:\Users\SER-01\Documents\ctr\simsim\simsim-backend\lambdas\simsim-auth\node_modules\@aws-sdk\signature-v4\dist\cjs\SignatureV4.js:139:39)
    at SignatureV4.signRequest (C:\Users\SER-01\Documents\ctr\simsim\simsim-backend\lambdas\simsim-auth\node_modules\@aws-sdk\signature-v4\dist\cjs\SignatureV4.js:98:73)
    at async C:\Users\SER-01\Documents\ctr\simsim\simsim-backend\lambdas\simsim-auth\node_modules\@aws-sdk\middleware-signing\dist\cjs\middleware.js:14:22
    at async StandardRetryStrategy.retry (C:\Users\SER-01\Documents\ctr\simsim\simsim-backend\lambdas\simsim-auth\node_modules\@aws-sdk\middleware-retry\dist\cjs\defaultStrategy.js:56:46)
    at async C:\Users\SER-01\Documents\ctr\simsim\simsim-backend\lambdas\simsim-auth\node_modules\@aws-sdk\middleware-logger\dist\cjs\loggerMiddleware.js:6:22
    at async C:\Users\SER-01\Documents\ctr\simsim\simsim-backend\lambdas\simsim-auth\src\routes\auth.js:232:33 {
  '$metadata': { attempts: 1, totalRetryDelay: 0 }
}

Expected behavior

returns '200' and user is either disabled or enabled

Additional context

The Disable/Enable feature works normally in v2 of the SDK but for some reason it is not in V3. Every other command I tried worked normally like its intended to but these two.

@Monir-Shembesh Monir-Shembesh added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Mar 21, 2021
@simonireilly
Copy link

simonireilly commented Mar 23, 2021

I also had an issue with the same error message when using the identity provider to assumeRoles with mfaProvider codes.

The bug for me was that the STS AssumeRole command returns capital case keys as AccessKeyId which needed to be mapped to lower case types in the sts assume role response:

Full Sample Code:

import { STSClient, AssumeRoleCommand } from "@aws-sdk/client-sts";
import { Credentials } from "@aws-sdk/types";
import { AssumeRoleParams } from "@aws-sdk/credential-provider-ini";
import { fromIni } from "@aws-sdk/credential-provider-ini";

import {
  DynamoDBClient,
  ListTablesCommand,
  ListTablesCommandOutput,
} from "@aws-sdk/client-dynamodb";

export const roleAssumer = async (
  sourceCredentials: Credentials,
  params: AssumeRoleParams
): Promise<Credentials> => {
  const client = new STSClient({
    region: "eu-west-2",
    credentials: sourceCredentials,
  });

  const command = new AssumeRoleCommand(params);
  const response = await client.send(command);
  
  // Here the keys must be remapped or I get the error `byteLength` of undefined when assuming roles.
  return {
    ...response.Credentials,
    accessKeyId: response.Credentials.AccessKeyId,
    secretAccessKey: response.Credentials.SecretAccessKey,
    sessionToken: response.Credentials.SessionToken,
  };
};

const credentials = fromIni({
  profile,
  roleAssumer,
  mfaCodeProvider: (mfaSerial: string): Promise<string> => {
    return new Promise((resolve) => resolve(mfaCode));
  },
});

console.info("Credentials", { credentials });

const client = new DynamoDBClient({
  region: "eu-west-2",
  credentials,
  logger: console,
});

result = await client.send(new ListTablesCommand({ Limit: 10 }));

Looking at the credentials type in the provider you mention, the keys are listed as Capital keys:

export interface Credentials {
/**
* <p>The Access Key portion of the credentials.</p>
*/
AccessKeyId?: string;
/**
* <p>The Secret Access Key portion of the credentials</p>
*/
SecretKey?: string;
/**
* <p>The Session Token portion of the credentials</p>
*/
SessionToken?: string;
/**
* <p>The date at which these credentials will expire.</p>
*/
Expiration?: Date;
}

I believe then the error arises when the HMAC verification between the session token and the AWS access keys is trigger. This is why we ended up on with the same error in separate modules.

@Monir-Shembesh
Copy link
Author

still no luck with this unfortunately

@brandt-roberts
Copy link

Wish I had read this GitHub issue earlier... same issue for me (STSClient/DynamoDBClient) and remapping the properties works - but this is a glaring bug and needs to be fixed as a high priority.

Suggest either updating the SDK to return both upper and lower case props (only returns upper currently) or make a change in the following code (of course there could be additional places to update we haven't discovered yet).

These seem to be the offending lines (32,33) in @aws-sdk/signature-v4/dist/cjs/credentialDerivation.js:

const credsHash = await hmac(sha256Constructor, credentials.secretAccessKey, credentials.accessKeyId);
const cacheKey = `${shortDate}:${region}:${service}:${util_hex_encoding_1.toHex(credsHash)}:${credentials.sessionToken}`;

@simonireilly
Copy link

This may have been addressed by #2221 as the default role assumer for services is performing the remapping t the downcased keys.

/~https://github.com/simonireilly/aws-sdk-js-v3/blob/ae17f4c64f0390c9b879eb27390688ac156cac47/clients/client-sts/defaultStsRoleAssumers.ts#L55-L60

@Monir-Shembesh
Copy link
Author

@simonireilly will have to test it and then update the issue. Any idea of the release data of this merge?

@simonireilly
Copy link

@Monir-Shembesh it is out already, you need to upgrade to v3.12.0 👍

image

@brandt-roberts
Copy link

@Monir-Shembesh it is out already, you need to upgrade to v3.12.0 👍

image

I have commented out my remapping and installed all 3.12.0 versions and the 'byteLength' issue still persists. One noted difference is I am using the 'AssumeRoleWithSAMLCommand' command.

@ajredniwja
Copy link
Contributor

Hi @Monir-Shembesh, I am not quite able to reproduce the issue, I just use the commands. Is it a persisting issue with latest version of the SDK?

@ajredniwja ajredniwja added response-requested Waiting on additional info and feedback. Will move to \"closing-soon\" in 7 days. and removed needs-triage This issue or PR still needs to be triaged. labels Jun 3, 2021
@Monir-Shembesh
Copy link
Author

Monir-Shembesh commented Jun 8, 2021

hi @ajredniwja, yes it is still. Tbh I just went back to using V2 of the SDK as I have tried multiple solutions and nothing worked.

EDIT 1: Typos

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. Will move to \"closing-soon\" in 7 days. label Jun 9, 2021
@andrewli-ca
Copy link

I had a similar issue with V3 and I was setting the credentials like how you were doing it:

const aws_creds = {
  accessKeyId: process.env.ACCESS_KEY_ID,
  secretAccessKey: process.env.SECRET_ACCESS_KEY,
};

What solved the issue for me was to use the environment variables keys AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY and the SDK will automatically detect these AWS credentials.

With that said, you won't need to pass the credentials when instantiating your CognitoIdentityProviderClient anymore.

https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/loading-node-credentials-environment.html

@github-actions
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 22, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug This issue is a bug.
Projects
None yet
Development

No branches or pull requests

5 participants