Name:
interface
Value:
Amplify has re-imagined the way frontend developers build fullstack applications. Develop and deploy without the hassle.

Choose your framework/language

Page updated Dec 9, 2024

Create a user profile record

You can use defineAuth and defineFunction to create a Cognito post confirmation Lambda trigger to create a profile record when a user is confirmed.

A user is "confirmed" when they verify their account. Typically this happens when the user confirms their email via the verification email. The post confirmation handler will not be triggered for federated sign-ins (i.e. social sign-in).

To get started, install the aws-lambda package, which is used to define the handler type.

Terminal
npm add --save-dev @types/aws-lambda

Update the amplify/data/resource.ts file to define a data model for the user's profile:

Make sure to configure the authorization rule to allow the postConfirmation resource as highlighted below. Granting access to resources creates environment variables for your Function such as the GraphQL API endpoint. To learn more visit the environment variables and secrets documentation for Functions.

amplify/data/resource.ts
import { type ClientSchema, a, defineData } from "@aws-amplify/backend";
import { postConfirmation } from "../auth/post-confirmation/resource";
const schema = a
.schema({
UserProfile: a
.model({
email: a.string(),
profileOwner: a.string(),
})
.authorization((allow) => [
allow.ownerDefinedIn("profileOwner"),
]),
})
.authorization((allow) => [allow.resource(postConfirmation)]);
export type Schema = ClientSchema<typeof schema>;
export const data = defineData({
schema,
authorizationModes: {
defaultAuthorizationMode: "apiKey",
apiKeyAuthorizationMode: {
expiresInDays: 30,
},
},
});

Create a new directory and a resource file, amplify/auth/post-confirmation/resource.ts. Then, define the Function with defineFunction:

amplify/auth/post-confirmation/resource.ts
import { defineFunction } from '@aws-amplify/backend';
export const postConfirmation = defineFunction({
name: 'post-confirmation',
});

Then, create the corresponding handler file, amplify/auth/post-confirmation/handler.ts, file with the following contents:

amplify/auth/post-confirmation/handler.ts
import type { PostConfirmationTriggerHandler } from "aws-lambda";
import { type Schema } from "../../data/resource";
import { Amplify } from "aws-amplify";
import { generateClient } from "aws-amplify/data";
import { getAmplifyDataClientConfig } from '@aws-amplify/backend/function/runtime';
import { env } from "$amplify/env/post-confirmation";
const { resourceConfig, libraryOptions } = await getAmplifyDataClientConfig(
env
);
Amplify.configure(resourceConfig, libraryOptions);
const client = generateClient<Schema>();
export const handler: PostConfirmationTriggerHandler = async (event) => {
await client.models.UserProfile.create({
email: event.request.userAttributes.email,
profileOwner: `${event.request.userAttributes.sub}::${event.userName}`,
});
return event;
};

When configuring Amplify with getAmplifyDataClientConfig, your function consumes schema information from an S3 bucket created during backend deployment with grants for the access your function need to use it. Any changes to this bucket outside of backend deployment may break your function.

Lastly, set the newly created Function resource on your auth resource:

amplify/auth/resource.ts
import { defineAuth } from '@aws-amplify/backend';
import { postConfirmation } from './post-confirmation/resource';
export const auth = defineAuth({
loginWith: {
email: true,
},
triggers: {
postConfirmation
}
});

After deploying the changes, whenever a user signs up and verifies their account a profile record is automatically created.