0

I assume this is should be a common feature of most websites, but I have seen no documentation for it. I have a website that has three groups of people that use it:

  1. Clients
  2. Teachers
  3. Admins

When a client signs up with the Authenticator Component, it currently adds the user to the Cognito pool, but not to any specific group. I would like to capture this sign-up request, then create a new cognito user inside the Client pool.

I have a graphql schema that allows access to data based on the cognito group:

type ClassGroup @model @auth(rules: [{allow: public, operations: [read]}, {allow: groups, groups: ["admins"], operations: [read, create, update, delete]}]) {
  id: ID!
  className: String
  semesterPrice: Float
}

To make that group change, I have to do it manually inside the Amplify Console: Image of default user with no assigned user group. Cut off to hide email Adding user to the Cognito group

I How can I accomplish this separation of users and accessibility inside AWS? How can I allow one group of users to access certain data and other users to access other data?

Lacrosse343
  • 491
  • 1
  • 3
  • 18
  • See also the Amplify tutorial here: https://aws.amazon.com/blogs/mobile/amplify-framework-adds-supports-for-aws-lambda-triggers-in-auth-and-storage-categories/ – Lacrosse343 Apr 10 '23 at 00:18
  • also by running `amplify update auth` and stepping through all options again, you can add Admin Query API, add the additional capabilities of adding to group. this will make a API gateway and function made for that. More details at https://docs.amplify.aws/cli/auth/admin/#admin-queries-api – Lacrosse343 Apr 10 '23 at 21:03

1 Answers1

1

Your graphql Schema can look like this:

type EmployerAccount
  @model
  @auth(
    rules: [
      { allow: owner, operations: [create, update, delete, read] }
      { allow: private, operations: [read] }
      { allow: public, provider: iam, operations: [read] }
    ]
  ) {
...
}

You can add a custom:group attribute in your cognito pool like this:

  await Auth.signUp({
    username: email,
    password,
    attributes: {
      "custom:group": "Employer"
    },
  });

You can then use a Post Confirmation Lambda Function on your Cognito pool to send them to specific tables.

CLI:

Run amplify update auth and add this as a trigger.

Lambda Function

/**
 * @type {import('@types/aws-lambda').APIGatewayProxyHandler}
 */
var dynamodb = require("aws-sdk/clients/dynamodb");
var ddb = new dynamodb({ region: "eu-west-1" });

exports.handler = async (event, context) => {
  console.log("EVENT", event);
  console.log("CONTEXT", context);

  let date = new Date();

  // As this is a PostConfirmation trigger, it can be triggered by other events
  // We only want to run the code below if the triggerSource is PostConfirmation_ConfirmSignUp
  // The other one is possibly "forgot_password" (which we don't want to run this code for)

  const valueTrigger = event.triggerSource;
  const confirmSignUp = "PostConfirmation_ConfirmSignUp";

  // If the triggerSource is PostConfirmation_ConfirmSignUp, then we know that the user has just signed up
  if (valueTrigger === confirmSignUp) {
    // We only want to run the code below if the user has a sub (unique user ID)
    if (event.request.userAttributes.sub) {


      // I will use their custom group to determine which parameters need to be passed into the DynamoDB call
      const paramsToUse = event.request.userAttributes["custom:group"] === "eMPLOYER" ? candidateParams : employerParams;

      // These are the parameters we need to pass to DynamoDB for the initial user creation
      let params = {
        Item: {...},
        TableName:
          event.request.userAttributes["custom:group"] === "Candidates"
            ? process.env[TABLE_NAME]
            : process.env.[TABLE_NAME],
      };

      try {
        await ddb.putItem(params).promise();
      } catch (err) {
        console.error("ERROR", err);
      }
      console.log("Success: Everything executed correctly");
      context.done(null, event);
    } else {
      console.error("ERROR: Nothing was written to DynamoDB");
      context.done(null, event);
    }
  } else {
    console.log("Not Confirm Signup, thus not running the code");
    context.done(null, event);
  }
};
Luke
  • 761
  • 1
  • 18