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

Amplify defineAuth how to pass to UserPool in Passwordless lib #209

Open
VadzimBelski-ScienceSoft opened this issue Oct 27, 2024 · 3 comments

Comments

@VadzimBelski-ScienceSoft

Hi,

I am trying to make a sinergy for Amplify Auth definitions with Passwordless.

My Backend.ts looks like this but unfortunetely it does not deploy

import * as cdk from "aws-cdk-lib";
import { defineBackend } from '@aws-amplify/backend';
import { auth } from './auth/resource';
import { data } from './data/resource';
import { PaswordlessStack } from './passwordless/resource';
import * as cognito from "aws-cdk-lib/aws-cognito";




/**
 * @see https://docs.amplify.aws/react/build-a-backend/ to add storage, functions, and more
 */
const backend = defineBackend({
  auth,
  data
});

// extract L1 CfnUserPool resources
const { cfnUserPool } = backend.auth.resources.cfnResources;

const passwordlessStack = new PaswordlessStack(  
  backend.createStack('PaswordlessStack'),
  'PaswordlessStack',
  cfnUserPool
);

backend.addOutput({
  custom: {
    region: "us-east-1",
    cognitoIdpEndpoint: passwordlessStack.passwordless.userPoolClients!.at(0)!.userPoolClientId,
    userPoolId: passwordlessStack.passwordless.userPool.userPoolId,
    ClientId: passwordlessStack.passwordless.userPoolClients!.at(0)!.userPoolClientId,
    Fido2Url: passwordlessStack.passwordless.fido2Api!.url!,
  },
});

My Paswordless looks like this


import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import { Passwordless } from "amazon-cognito-passwordless-auth/cdk";
import * as cognito from "aws-cdk-lib/aws-cognito";


export class PaswordlessStack extends cdk.Stack {
  public readonly passwordless: Passwordless;
  constructor(scope: Construct, id: string, userPool: cognito.IUserPool, props?: cdk.StackProps) {
    super(scope, id, props);

    this.passwordless = new Passwordless(this, "Passwordless", {
      userPool: userPool,
      allowedOrigins: [
        "http://localhost",
        "http://localhost:3000",
      ],
      magicLink: {
        sesFromAddress: "[email protected]", // must be a verified domain or identity in Amazon SES
        secretsTableProps: {
          removalPolicy: cdk.RemovalPolicy.DESTROY,
          billingMode: cdk.aws_dynamodb.BillingMode.PAY_PER_REQUEST,
        },
      },
      userPoolProps: {
        removalPolicy: cdk.RemovalPolicy.DESTROY,
      },
      fido2: {
        authenticatorsTableProps: {
          removalPolicy: cdk.RemovalPolicy.DESTROY,
          billingMode: cdk.aws_dynamodb.BillingMode.PAY_PER_REQUEST,
        },
        relyingPartyName: "Passwordless Fido2 Example",
        allowedRelyingPartyIds: [
          "localhost", // Domain names that you wish to use as Relying Party ID
        ],
        attestation: "none",
        userVerification: "required",
        updatedCredentialsNotification: {
          sesFromAddress: "[email protected]", // must be a verified domain or identity in Amazon SES
        },
      },
      smsOtpStepUp: {},
      userPoolClientProps: {
        // perrty short so you see token refreshes in action often:
        idTokenValidity: cdk.Duration.minutes(5),
        accessTokenValidity: cdk.Duration.minutes(5),
        refreshTokenValidity: cdk.Duration.hours(1),
        // while testing/experimenting it's best to set this to false,
        // so that when you try to sign in with a user that doesn't exist,
        // Cognito will tell you that––and you don't wait for a magic link
        // that will never arrive in your inbox:
        preventUserExistenceErrors: false,
      },
      // while testing/experimenting it's heplful to see e.g. full request details in logs:
      logLevel: "DEBUG",
    });
    new cdk.CfnOutput(this, "ClientId", {
      value: this.passwordless.userPoolClients!.at(0)!.userPoolClientId,
    });
    new cdk.CfnOutput(this, "cognitoIdpEndpoint", {
        value: this.passwordless.userPool.userPoolProviderUrl
    });
    new cdk.CfnOutput(this, "userPoolId", {
        value: this.passwordless.userPool.userPoolId
    });
    new cdk.CfnOutput(this, "Fido2Url", {
      value: this.passwordless.fido2Api!.url!,
    });
  }
}

from what i understand is that i can not modify Amplify cdk provisioned resources so i can not merge this 2 libs to work.

Please give me directions.

@ottokruse
Copy link
Contributor

The Passwordless CDK construct needs to create its own User Pool, or at least have the User Pool in the same CDK stack. That's why it can take in a UserPool as prop but not an IUserPool. If you can somehow make that happen it should work together. I don't know enough about Amplify to suggest to you if and how that can be down with Amplify.

@ottokruse
Copy link
Contributor

Also see pointers here: #118

@seaver-choy
Copy link

seaver-choy commented Dec 3, 2024

I tried doing this here:

import { Passwordless } from "amazon-cognito-passwordless-auth";
import { auth } from "./auth/resource";

/**
 * @see https://docs.amplify.aws/react/build-a-backend/ to add storage, functions, and more
 */
const backend = defineBackend({
  auth,
});

const { cfnResources } = backend.auth.resources;

Passwordless.configure({
  userPoolId: cfnResources.cfnUserPool.attrUserPoolId,  
  clientId: cfnResources.cfnUserPoolClient.attrClientId, 
  clientSecret: cfnResources.cfnUserPoolClient.attrClientSecret
});

Seems like it's building and it's working, we'll do further tests though.

Thank you for this @ottokruse

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants