I'm having trouble customizing my Auth Flow with AWS-cognito and AWS-Ses. I would like to do a simple magic link auth, that sends a token by mail whenever a user whats to sign in. My problem is : I need to customize this email before sending it to the users mailbox. I want to have a link that redirects users to my website but they can come from different locations. Let's say, I'm going to redirect some users to https://mysite/foo?<token> and some others to https://mysite/bar?<token>.
But I'm not able to pass custom variables to my AWS cognito auth Triggers.
Right now I have a CUSTOM_AUTH flow, and I use @aws-sdk/client-cognito-identity-provider to initiateAuthCommand. I do not want to use Amplify because all the rest of my app uses the aws SDK.
Here is how I call the initiateAuth command :
import { CognitoIdentityProviderClient, InitiateAuthCommand } from '@aws-sdk/client-cognito-identity-provider'
const poolConfig = {
accessKeyId: process.env.AWS_APIKEY,
secretAccessKey: process.env.AWS_SECRETKEY,
region: process.env.AWS_REGION,
poolId: process.env.AWS_COGNITO_POOL_ID,
poolClientId: process.env.AWS_COGNITO_POOL_CLIENT_ID
}
const provider = new CognitoIdentityProviderClient(poolConfig)
const authInput = {
AuthFlow: "CUSTOM_AUTH",
AuthParameters : {
USERNAME: "test@mydomain.com",
},
ClientId: process.env.AWS_COGNITO_POOL_CLIENT_ID
}
const signinCommand = new InitiateAuthCommand(authInput)
try {
const res = await provider.send(signinCommand)
console.log('Signin success. Result: ', res)
} catch (e) {
console.log('Signin fail. Error: ', e)
}
and here is my createAuthChallenge trigger :
import { SESv2Client, SendEmailCommand } from "@aws-sdk/client-sesv2";
import { randomDigits } from 'crypto-secure-random-digit';
const config = {
accessKeyId: process.env.AWS_APIKEY,
secretAccessKey: process.env.AWS_SECRETKEY,
region: process.env.AWS_REGION,
}
const client = new SESv2Client(config);
export const handler = async (event) => {
let secretLoginCode;
if (!event.request.session || !event.request.session.length) {
secretLoginCode = randomDigits(10).join('');
// My problem is here, I can't manage to retrieve here a custom variable, that would be
// originUrl in this example
await sendEmail(event.request.userAttributes.email, originUrl, secretLoginCode);
} else {
const previousChallenge = event.request.session.slice(-1)[0];
secretLoginCode = previousChallenge.challengeMetadata.match(/CODE-(\d*)/)[1];
}
event.response.publicChallengeParameters = {
email: event.request.userAttributes.email
};
event.response.privateChallengeParameters = { secretLoginCode };
event.response.challengeMetadata = `CODE-${secretLoginCode}`;
return event;
};
async function sendEmail(emailAddress, originUrl, secretLoginCode) {
var params = {
Destination: {
ToAddresses: [
emailAddress
]
},
Content: {
Simple: {
Body: {
Html: {
Charset: "UTF-8",
Data: `<p>Your link to connect is : <a href="${originUrl}/register?t=${secretLoginCode}">here</a></p>`
},
},
Subject: {
Charset: 'UTF-8',
Data: 'Test email'
}
}
},
FromEmailAddress: 'fromAddress@mydomain.com',
};
const command = new SendEmailCommand(params);
await client.send(command);
}
I have tried a lot of things that seems to be documented in AWS docs here :
It's talking about an EnablePropagateAdditionalUserContextData boolean in my app's client but it looks that this is for a different use case. For device fingerprinting and so. Moreover, it costs extra because you have to enable 'advanced security' and I can't do that as I'm not in charge of the billing. Thus it seems weird to have to pay extra to do something as simple as this.
I have also tried to use ClientMetadata. It should be available in the request to the lambda as this docs shows :
But this doc says that these parameters are not communicated to the createAuthChallenge trigger :
https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html
Why ? Why can't I send custom data to my lambda trigger ? I'm sure I'm missing something but I admit being out of ressource to resolve this. I have tried a lot of things but with no result. It is weird because the need to do this kind of thing must be really common, especially if using a CUSTOM_FLOW_AUTH.
What am I missing ? Does someone around here already had this issue ?
Thanks :)