From 798e62925a7e6a4d994e7221c6421c2f58787618 Mon Sep 17 00:00:00 2001 From: Jim Eagan <84857865+hibler13@users.noreply.github.com> Date: Fri, 8 Dec 2023 10:26:23 -0800 Subject: [PATCH] Catching up to main (#6640) * Update index.mdx (#6618) Update quickstart * Defer shortbread (#6575) * Update CODEOWNERS (#6626) * Update signInWithRedict docs (#6520) --------- Co-authored-by: Rene Brandel <4989523+renebrandel@users.noreply.github.com> * chore(js-storage): add bytesRange options to the example (#6621) * custom resource docs updates (#6616) * custom resource updates * Apply suggestions from code review Co-authored-by: josef --------- Co-authored-by: josef * update pr link checker to use python server (#6476) * update pr link checker to use github http-server action * change server to python server --------- Co-authored-by: Jacob Logan * fix: make gen2 banner button align better with text (#6635) * auth-events: small documentation fix (#6623) * edit override docs (#6615) * edit override docs * Apply suggestions from code review Co-authored-by: josef * add context around L1 and L2 constructs --------- Co-authored-by: josef * Update cspell.json (#6639) Added an entry for "bidirectionality" --------- Co-authored-by: Rene Brandel <4989523+renebrandel@users.noreply.github.com> Co-authored-by: Tim Nguyen <54393192+timngyn@users.noreply.github.com> Co-authored-by: Scott Rees <6165315+reesscot@users.noreply.github.com> Co-authored-by: Francisco Rodriguez Co-authored-by: Hui Zhao <10602282+HuiSF@users.noreply.github.com> Co-authored-by: Edward Foyle Co-authored-by: josef Co-authored-by: jacoblogan Co-authored-by: Jacob Logan Co-authored-by: Chen Cozoczaru --- .github/CODEOWNERS | 66 ++--- .../workflows/check_pr_for_broken_links.yml | 2 +- cspell.json | 1 + .../auth/add-social-provider/index.mdx | 233 ++++++++++-------- .../auth/auth-events/index.mdx | 2 +- .../storage/download/index.mdx | 14 +- src/pages/_app.tsx | 4 + src/pages/_document.tsx | 4 - .../custom-resources/index.mdx | 16 +- .../overriding-resources/index.mdx | 137 +++++++--- src/pages/gen2/start/quickstart/index.mdx | 2 +- src/styles/banner.scss | 14 +- 12 files changed, 301 insertions(+), 194 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 5ad5d2dbcd5..e2798515e67 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,6 +1,6 @@ * @aws-amplify/documentation-team -/src/fragments/ @renebrandel @aws-amplify/documentation-team -/src/pages/ @renebrandel @aws-amplify/documentation-team +/src/fragments/ @renebrandel @dbanksdesign @aws-amplify/documentation-team +/src/pages/ @renebrandel @dbanksdesign @aws-amplify/documentation-team #CLI /src/**/cli/ @josefaidt @aws-amplify/documentation-team @@ -9,80 +9,80 @@ /src/pages/console/ @dbanksdesign @aws-amplify/documentation-team #Analytics -/src/**/**/analytics @renebrandel @aws-amplify/documentation-team +/src/**/**/analytics @renebrandel @dbanksdesign @aws-amplify/documentation-team #Auth -/src/**/**/auth @renebrandel @aws-amplify/documentation-team -/src/**/**/authz @renebrandel @aws-amplify/documentation-team -/src/**/**/authentication @renebrandel @aws-amplify/documentation-team +/src/**/**/auth @renebrandel @dbanksdesign @aws-amplify/documentation-team +/src/**/**/authz @renebrandel @dbanksdesign @aws-amplify/documentation-team +/src/**/**/authentication @renebrandel @dbanksdesign @aws-amplify/documentation-team #Client Configuration -/src/**/**/client-configuration @renebrandel @hdworld11 @aws-amplify/documentation-team -/src/**/**/configuration @renebrandel @hdworld11 @aws-amplify/documentation-team +/src/**/**/client-configuration @renebrandel @dbanksdesign @hdworld11 @aws-amplify/documentation-team +/src/**/**/configuration @renebrandel @dbanksdesign @hdworld11 @aws-amplify/documentation-team #Common -/src/fragments/common @renebrandel @aws-amplify/documentation-team -/src/fragments/lib/common @renebrandel @aws-amplify/documentation-team +/src/fragments/common @renebrandel @dbanksdesign @aws-amplify/documentation-team +/src/fragments/lib/common @renebrandel @dbanksdesign @aws-amplify/documentation-team #Data -/src/**/**/datastore @renebrandel @aws-amplify/documentation-team -/src/**/**/data @renebrandel @aws-amplify/documentation-team +/src/**/**/datastore @renebrandel @dbanksdesign @aws-amplify/documentation-team +/src/**/**/data @renebrandel @dbanksdesign @aws-amplify/documentation-team #Debugging -/src/fragments/**/debugging @renebrandel @aws-amplify/documentation-team +/src/fragments/**/debugging @renebrandel @dbanksdesign @aws-amplify/documentation-team #Geo -/src/**/**/geo @renebrandel @aws-amplify/documentation-team +/src/**/**/geo @renebrandel @dbanksdesign @aws-amplify/documentation-team #Getting Started -/src/**/start @renebrandel @aws-amplify/documentation-team +/src/**/start @renebrandel @dbanksdesign @aws-amplify/documentation-team #GraphQL API -/src/**/**/api-graphql @renebrandel @aws-amplify/documentation-team -/src/**/**/graphqlapi @renebrandel @aws-amplify/documentation-team -/src/**/cli-legacy/graphql-transformer @renebrandel @aws-amplify/documentation-team -/src/fragments/sdk/api/**/graphql.mdx @renebrandel @aws-amplify/documentation-team +/src/**/**/api-graphql @renebrandel @dbanksdesign @aws-amplify/documentation-team +/src/**/**/graphqlapi @renebrandel @dbanksdesign @aws-amplify/documentation-team +/src/**/cli-legacy/graphql-transformer @renebrandel @dbanksdesign @aws-amplify/documentation-team +/src/fragments/sdk/api/**/graphql.mdx @renebrandel @dbanksdesign @aws-amplify/documentation-team #In-App Messaging -/src/**/**/in-app-messaging @renebrandel @aws-amplify/documentation-team +/src/**/**/in-app-messaging @renebrandel @dbanksdesign @aws-amplify/documentation-team #Info -/src/fragments/**/info @renebrandel @aws-amplify/documentation-team +/src/fragments/**/info @renebrandel @dbanksdesign @aws-amplify/documentation-team #Interactions -/src/**/**/interactions @renebrandel @aws-amplify/documentation-team +/src/**/**/interactions @renebrandel @dbanksdesign @aws-amplify/documentation-team #Logging -/src/fragments/lib/logging @renebrandel @aws-amplify/documentation-team +/src/fragments/lib/logging @renebrandel @dbanksdesign @aws-amplify/documentation-team #Predictions -/src/**/**/predictions @renebrandel @aws-amplify/documentation-team +/src/**/**/predictions @renebrandel @dbanksdesign @aws-amplify/documentation-team #Project Setup -/src/**/**/project-setup @renebrandel @hdworld11 @aws-amplify/documentation-team +/src/**/**/project-setup @renebrandel @dbanksdesign @hdworld11 @aws-amplify/documentation-team #PubSub -/src/**/**/pubsub @renebrandel @aws-amplify/documentation-team +/src/**/**/pubsub @renebrandel @dbanksdesign @aws-amplify/documentation-team #Push Notifications -/src/**/**/push-notifications @renebrandel @aws-amplify/documentation-team +/src/**/**/push-notifications @renebrandel @dbanksdesign @aws-amplify/documentation-team #Rest API -/src/**/**/api-rest @renebrandel @aws-amplify/documentation-team -/src/**/**/restapi @renebrandel @aws-amplify/documentation-team -/src/fragments/sdk/api/**/rest.mdx @renebrandel @aws-amplify/documentation-team +/src/**/**/api-rest @renebrandel @dbanksdesign @aws-amplify/documentation-team +/src/**/**/restapi @renebrandel @dbanksdesign @aws-amplify/documentation-team +/src/fragments/sdk/api/**/rest.mdx @renebrandel @dbanksdesign @aws-amplify/documentation-team #SSR -/src/fragments/lib/ssr @renebrandel @aws-amplify/documentation-team +/src/fragments/lib/ssr @renebrandel @dbanksdesign @aws-amplify/documentation-team #Storage /src/**/**/storage @hdworld11 @aws-amplify/documentation-team #Troubleshooting -/src/fragments/lib/troubleshooting @renebrandel @aws-amplify/documentation-team +/src/fragments/lib/troubleshooting @renebrandel @dbanksdesign @aws-amplify/documentation-team #Utilities -/src/**/**/utilities @renebrandel @aws-amplify/documentation-team +/src/**/**/utilities @renebrandel @dbanksdesign @aws-amplify/documentation-team #Docs Engineering /src/components @aws-amplify/documentation-team diff --git a/.github/workflows/check_pr_for_broken_links.yml b/.github/workflows/check_pr_for_broken_links.yml index 046b87bb843..56ee58fca3c 100644 --- a/.github/workflows/check_pr_for_broken_links.yml +++ b/.github/workflows/check_pr_for_broken_links.yml @@ -21,7 +21,7 @@ jobs: NODE_OPTIONS: --max_old_space_size=4096 - name: Run Server run: | - node ./node_modules/.bin/serve client/www/next-build --no-request-logging & + python -m http.server 3000 -d ${{ vars.BUILD_DIR }} & sleep 5 - name: Run Link Checker id: checkLinks diff --git a/cspell.json b/cspell.json index e8f0818d6b1..6a7bd00caf7 100644 --- a/cspell.json +++ b/cspell.json @@ -335,6 +335,7 @@ "beginsWith", "BelongsTo", "betatest", + "bidirectionality", "birthdate", "Bitbucket", "bizcorprole", diff --git a/src/pages/[platform]/build-a-backend/auth/add-social-provider/index.mdx b/src/pages/[platform]/build-a-backend/auth/add-social-provider/index.mdx index 4febe75e7f9..23d83572a0f 100644 --- a/src/pages/[platform]/build-a-backend/auth/add-social-provider/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/add-social-provider/index.mdx @@ -407,23 +407,86 @@ After configuring the OAuth endpoints (with Cognito Hosted UI), you can integrat A custom state is not required, but if you are looking to add one, you are able to do so by passing a string value (e.g. `signInWithRedirect({ customState: 'xyz' })`) and listening for the custom state via [Hub](/[platform]/build-a-backend/utilities/hub/). You can also use the Hub eventing system to catch errors using `signInWithRedirect()` to listen for the `signInWithRedirect_failure` event. - + ```ts -import React, { useEffect, useState } from "react"; -import { Amplify } from "aws-amplify"; import { Hub } from "aws-amplify/utils"; -import { signInWithRedirect, signOut, getCurrentUser } from "aws-amplify/auth"; -import { AuthUser } from "aws-amplify/auth"; -import config from './amplifyconfiguration.json'; +import { signInWithRedirect, getCurrentUser, AuthUser } from "aws-amplify/auth"; + +Hub.listen("auth", ({ payload }) => { + switch (payload.event) { + case "signInWithRedirect": + const user = await getCurrentUser(); + console.log(user.username); + break; + case "signInWithRedirect_failure": + // handle sign in failure + break; + case "customOAuthState": + const state = payload.data; // this will be customState provided on signInWithRedirect function + console.log(state); + break; + } +}); -Amplify.configure(config); +function handleSignInClick(customState: string) { + signInWithRedirect({ + provider: "Google", + customState + }); +} +``` + + + +```javascript +import { Hub } from "aws-amplify/utils"; +import { signInWithRedirect, getCurrentUser } from "aws-amplify/auth"; + +Hub.listen("auth", ({ payload }) => { + switch (payload.event) { + case "signInWithRedirect": + const user = await getCurrentUser(); + console.log(user.username); + break; + case "signInWithRedirect_failure": + // handle sign in failure + break; + case "customOAuthState": + const state = payload.data; // this will be customState provided on signInWithRedirect function + console.log(state); + break; + } +}); + +function handleSignInClick(customState) { + signInWithRedirect({ + provider: "Google", + customState + }); +} +``` + + + + + + + + + + + +```ts +import React, { useEffect, useState } from "react"; +import { Hub } from "aws-amplify/utils"; +import { signInWithRedirect, signOut, getCurrentUser, AuthUser } from "aws-amplify/auth"; function App() { - const [user, setUser] = useState(null); + const [user, setUser] = useState(null); const [error, setError] = useState(null); const [customState, setCustomState] = useState(null); @@ -434,10 +497,10 @@ function App() { getUser(); break; case "signInWithRedirect_failure": - setError("An error has ocurred during the Oauth flow."); + setError("An error has ocurred during the OAuth flow."); break; case "customOAuthState": - setCustomState(payload.data); + setCustomState(payload.data); // this is the customState provided on signInWithRedirect function break; } }); @@ -459,21 +522,22 @@ function App() { return (
- - + - - -
{user?.username}
+
{customState}
); } @@ -483,13 +547,9 @@ function App() { ```javascript -import React, { useEffect, useState } from 'react'; -import { Amplify } from 'aws-amplify'; -import { Hub } from 'aws-amplify/utils'; -import { signInWithRedirect, signOut, getCurrentUser } from 'aws-amplify/auth'; -import config from './amplifyconfiguration.json'; - -Amplify.configure(config); +import React, { useEffect, useState } from "react"; +import { Hub } from "aws-amplify/utils"; +import { signInWithRedirect, signOut, getCurrentUser } from "aws-amplify/auth"; function App() { const [user, setUser] = useState(null); @@ -497,16 +557,16 @@ function App() { const [customState, setCustomState] = useState(null); useEffect(() => { - const unsubscribe = Hub.listen('auth', ({ payload }) => { + const unsubscribe = Hub.listen("auth", ({ payload }) => { switch (payload.event) { - case 'signInWithRedirect': + case "signInWithRedirect": getUser(); break; - case 'signInWithRedirect_failure': - setError('An error has ocurred during the Oauth flow.'); + case "signInWithRedirect_failure": + setError("An error has ocurred during the OAuth flow."); break; - case 'customOAuthState': - setCustomState(payload.data); + case "customOAuthState": + setCustomState(payload.data); // this is the customState provided on signInWithRedirect function break; } }); @@ -522,27 +582,28 @@ function App() { setUser(currentUser); } catch (error) { console.error(error); - console.log('Not signed in'); + console.log("Not signed in"); } }; return (
- - + - - -
{user?.username}
+
{customState}
); } @@ -559,18 +620,19 @@ function App() { ```ts -import { useEffect, useState } from "react"; -import { Text, View, Linking, Button } from "react-native"; -import { Amplify } from "aws-amplify"; -import { Hub } from "aws-amplify/utils"; -import { signInWithRedirect, signOut, getCurrentUser } from "aws-amplify/auth"; -import { AuthUser } from "aws-amplify/auth"; -import config from './amplifyconfiguration.json'; +import React, { useEffect, useState } from "react"; +import { + Button, + SafeAreaView, + Text, +} from "react-native"; -Amplify.configure(config); +import { AuthUser, getCurrentUser, signInWithRedirect, signOut } from "aws-amplify/auth"; +import { Hub } from "@aws-amplify/core"; -function App() { - const [user, setUser] = useState(null); + +function App(): JSX.Element { + const [user, setUser] = useState(null); const [error, setError] = useState(null); const [customState, setCustomState] = useState(null); @@ -581,10 +643,10 @@ function App() { getUser(); break; case "signInWithRedirect_failure": - setError("An error has ocurred during the oauth flow."); + setError("An error has ocurred during the OAuth flow."); break; case "customOAuthState": - setCustomState(payload.data); + setCustomState(payload.data); // this is the customState provided on signInWithRedirect function break; } }); @@ -593,7 +655,7 @@ function App() { return unsubscribe; }, []); - + const getUser = async (): Promise => { try { const currentUser = await getCurrentUser(); @@ -605,23 +667,12 @@ function App() { }; return ( -
- - - - - - -
{user?.username}
-
+ + + {user?.username} + {customState} + + ); } ``` @@ -630,14 +681,15 @@ function App() { ```javascript -import { useEffect, useState } from 'react'; -import { Text, View, Linking, Button } from 'react-native'; -import { Amplify } from 'aws-amplify'; -import { Hub } from 'aws-amplify/utils'; -import { signInWithRedirect, signOut, getCurrentUser } from 'aws-amplify/auth'; -import config from './amplifyconfiguration.json'; +import React, { useEffect, useState } from "react"; +import { + Button, + SafeAreaView, + Text, +} from "react-native"; -Amplify.configure(config); +import { getCurrentUser, signInWithRedirect, signOut } from "aws-amplify/auth"; +import { Hub } from "@aws-amplify/core"; function App() { const [user, setUser] = useState(null); @@ -645,15 +697,15 @@ function App() { const [customState, setCustomState] = useState(null); useEffect(() => { - const unsubscribe = Hub.listen('auth', ({ payload }) => { + const unsubscribe = Hub.listen("auth", ({ payload }) => { switch (payload.event) { - case 'signInWithRedirect': + case "signInWithRedirect": getUser(); break; - case 'signInWithRedirect_failure': - setError('An error has ocurred during the Oauth flow.'); + case "signInWithRedirect_failure": + setError("An error has ocurred during the OAuth flow."); break; - case 'customOAuthState': + case "customOAuthState": setCustomState(payload.data); break; } @@ -663,35 +715,24 @@ function App() { return unsubscribe; }, []); - + const getUser = async () => { try { const currentUser = await getCurrentUser(); setUser(currentUser); } catch (error) { console.error(error); - console.log('Not signed in'); + console.log("Not signed in"); } }; return ( -
- - - - - - -
{user?.username}
-
+ + + {user?.username} + {customState} + + ); } ``` @@ -766,7 +807,7 @@ Amplify.configure({ }); function App() { - const [user, setUser] = useState(null); + const [user, setUser] = useState(null); const [error, setError] = useState(null); const [customState, setCustomState] = useState(null); diff --git a/src/pages/[platform]/build-a-backend/auth/auth-events/index.mdx b/src/pages/[platform]/build-a-backend/auth/auth-events/index.mdx index 80bda7d80f8..cb76e147964 100644 --- a/src/pages/[platform]/build-a-backend/auth/auth-events/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/auth-events/index.mdx @@ -69,7 +69,7 @@ Channels are logical group names that help you organize dispatching and listenin Here is a basic example of setting up a listener that logs an event emitted through the `auth` channel: ```javascript -import { Hub } from 'aws-amplify'; +import { Hub } from 'aws-amplify/utils'; const listener = (data) => { console.log(data); diff --git a/src/pages/[platform]/build-a-backend/storage/download/index.mdx b/src/pages/[platform]/build-a-backend/storage/download/index.mdx index 89f3668c2df..cf07e0419eb 100644 --- a/src/pages/[platform]/build-a-backend/storage/download/index.mdx +++ b/src/pages/[platform]/build-a-backend/storage/download/index.mdx @@ -110,14 +110,20 @@ Download a file to in-memory buffer. ```javascript import { downloadData } from 'aws-amplify/storage'; -// Download a file from s3 bucket +// Downloads file content to memory const { body, eTag } = await downloadData({ key, data: file, options: { - accessLevel: 'guest', // can be 'private' | 'protected' | 'guest' - targetIdentityId: 'xxxxxxx', // id of another user, if `level: protected` - onProgress // Optional progress callback. + accessLevel: 'guest', // access level of the file being downloaded + targetIdentityId: 'xxxxxxx', // the identity id of another user, required when setting accessLevel to 'protected' + onProgress: (event) => { + console.log(event.transferredBytes); + } // optional progress callback + bytesRange: { + start: 1024, + end: 2048 + } // optional bytes range parameter to download a part of the file, the 2nd MB of the file in this example } }).result; ``` diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index ae8977992cc..97db201b011 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -197,6 +197,10 @@ function MyApp({ Component, pageProps }) { > )} + ); } diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx index 037f0e9cae7..0f7b434f7e6 100644 --- a/src/pages/_document.tsx +++ b/src/pages/_document.tsx @@ -118,10 +118,6 @@ export default class MyDocument extends Document { src="https://prod.assets.shortbread.aws.dev/shortbread.js" defer > -
diff --git a/src/pages/gen2/build-a-backend/add-aws-services/custom-resources/index.mdx b/src/pages/gen2/build-a-backend/add-aws-services/custom-resources/index.mdx index b42dfa9d5db..84994043927 100644 --- a/src/pages/gen2/build-a-backend/add-aws-services/custom-resources/index.mdx +++ b/src/pages/gen2/build-a-backend/add-aws-services/custom-resources/index.mdx @@ -12,19 +12,25 @@ export function getStaticProps(context) { } + + +Custom resources allow you to integrate any AWS service into an Amplify backend. You are responsible for ensuring that your custom resources are secure, adhere to best practices, and work with the resources that Amplify creates in your project. + + + Amplify (Gen 2) provides the ability to add custom AWS resources to an Amplify project using the [AWS Cloud Development Kit (AWS CDK)](https://docs.aws.amazon.com/cdk/latest/guide/home.html). The CDK is an open source software development framework to define your cloud application resources using familiar programming languages, such as TypeScript. -CDK can be used within an Amplify project to add custom resources and configurations beyond what Amplify supports out of the box. For example, a developer could use CDK to hook up a Redis cache, add a Lambda function that runs on a schedule, or implement custom security rules. +CDK can be used within an Amplify project to add custom resources and configurations beyond what Amplify supports out of the box. For example, a developer could use CDK to hook up a Redis cache, implement custom security rules, deploy containers on Fargate, or use any other AWS service. -The infrastructure defined via CDK code is deployed along with the Amplify project. This gives developers the simplicity of Amplify, combined with the flexibility of CDK for situations where they need more customization. +The infrastructure defined via CDK code is deployed along with the Amplify project backend. This gives developers the simplicity of Amplify, combined with the flexibility of CDK for situations where they need more customization. - + AWS CDK apps are composed of building blocks known as [Constructs](https://docs.aws.amazon.com/cdk/v2/guide/constructs.html), which are composed together to form [stacks](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html) and [apps](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html). You can learn more in the [Concepts - AWS Cloud Development Kit (AWS CDK) v2](https://docs.aws.amazon.com/cdk/v2/guide/core_concepts.html) documentation. -With the Amplify Code-first DX, you can add existing or custom CDK [Constructs](https://docs.aws.amazon.com/cdk/v2/guide/constructs.html) to the [backend](https://next-docs.amplify.aws/gen2/how-amplify-works/concepts/#backend) of your Amplify project. +With the Amplify Code-first DX, you can add existing or custom CDK [Constructs](https://docs.aws.amazon.com/cdk/v2/guide/constructs.html) to the [backend](/gen2/how-amplify-works/concepts/#backend) of your Amplify project. ## Adding an existing CDK Construct @@ -231,7 +237,7 @@ const sendEmail = async (message: Message) => { }; ``` -The `CustomNotifications` CDK construct can then be added to the Amplify `backend` one or more times, with different props for each instance. +The `CustomNotifications` CDK construct can then be added to the Amplify `backend` one or more times, with different properties for each instance. ```ts title="amplify/backend.ts" // amplify/backend.ts diff --git a/src/pages/gen2/build-a-backend/add-aws-services/overriding-resources/index.mdx b/src/pages/gen2/build-a-backend/add-aws-services/overriding-resources/index.mdx index 681493776b2..3069f8c5c6c 100644 --- a/src/pages/gen2/build-a-backend/add-aws-services/overriding-resources/index.mdx +++ b/src/pages/gen2/build-a-backend/add-aws-services/overriding-resources/index.mdx @@ -1,7 +1,6 @@ export const meta = { title: 'Overriding resources', - description: - 'Learn how to override resources.' + description: 'Learn how to override resources.' }; export function getStaticProps(context) { @@ -13,40 +12,103 @@ export function getStaticProps(context) { } -When defining resources you can access some underlying AWS CDK construct props to modify resource configurations. + -## Customize Cognito UserPool email verification settings +Using overrides may cause you to create a backend that the Amplify libraries or client config is unable to interpret properly. Always test changes in a staging environment. -```ts title="amplify/auth/resource.ts" -import { defineAuth } from "@aws-amplify/backend"; + -export const auth = defineAuth({ - loginWith: { - email: { - verificationEmailStyle: "CODE", - verificationEmailBody: (code: string) => - `Welcome! Your verification code is ${code}.`, - verificationEmailSubject: "Welcome! Here is your verification code", - }, - }, +When defining resources you can access some underlying [AWS Cloud Development Kit (CDK)](https://docs.aws.amazon.com/cdk/latest/guide/home.html) construct properties to modify resource configurations. This allows you to customize backend resources beyond what is offered via the `define*` functions. + +Overrides are defined in the `amplify/backend.ts` file after the `defineBackend` call has been made. + +```ts title="amplify/backend.ts" +// amplify/backend.ts +import { defineBackend } from '@aws-amplify/backend'; +import { auth } from './auth/resource'; +import { data } from './data/resource'; + +const backend = defineBackend({ + auth, + data +}); + +// overrides go here +``` + +The `backend` object exposes a `resources` property with objects for each of the components passed into the `defineBackend` function. Each of these resource objects exposes underlying L1 and L2 CDK Constructs that you can modify. + +For example, here is how you can access the Cognito UserPool that is created by `defineAuth` and set a custom removal policy on the resource. + +```ts title="amplify/backend.ts" +// amplify/backend.ts +import { defineBackend } from '@aws-amplify/backend'; +import { auth } from './auth/resource'; +import { UserPool } from 'aws-cdk-lib/aws-cognito'; +import { RemovalPolicy } from 'aws-cdk-lib'; + +const backend = defineBackend({ + auth }); + +const userPool = backend.resources.auth.resources.userPool as UserPool; +userPool.applyRemovalPolicy(RemovalPolicy.RETAIN_ON_UPDATE_OR_DELETE); ``` -Alternatively you can mutate the synthesized CDK constructs directly after setting them on your `backend`: +Most L1 and L2 CDK Constructs that are used by the `define*` functions are accessible in this way. + +## Example - Grant access permissions between resources + + + +**Under active development**: We are actively working to improve the experience of granting one resource access to another. For the time being, overrides can be used to achieve this. -## Override Cognito UserPool password policies + + +Consider the case that we want to grant a function created by `defineFunction` access to call the Cognito UserPool created by `defineAuth`. This can be accomplished with the following overrides. ```ts title="amplify/backend.ts" -import { Backend } from '@aws-amplify/backend'; +// amplify/backend.ts +import { defineBackend } from '@aws-amplify/backend'; import { auth } from './auth/resource'; +import { data } from './data/resource'; +import { demoFunction } from './functions/demo-function/resource'; +import { UserPool } from 'aws-cdk-lib/aws-cognito'; +import { Function } from 'aws-cdk-lib/aws-lambda'; -const backend = new Backend({ +const backend = defineBackend({ auth, + data, + demoFunction +}); + +const userPool = backend.resources.auth.resources.userPool as UserPool; +const lambdaFunction = backend.resources.demoFunction.resources + .lambda as Function; + +// grant the lambdaFunction read access to users +userPool.grant(lambdaFunction, 'cognito:GetUser', 'cognito:ListUsers'); + +// pass the Lambda the UserPool ID so that the Lambda can use it to make SDK calls +lambdaFunction.addEnvironment('USER_POOL_ID', userPool.userPoolId); +``` + +## Example - Mutate synthesized CloudFormation + +It's possible to reach all the way down to the raw CloudFormation to mutate properties using `addPropertyOverride` on a CDK Construct. To edit the password policies of the Cognito UserPool in `defineAuth`, you can use the following code. + +```ts +// amplify/backend.ts +import { defineBackend } from '@aws-amplify/backend'; +import { auth } from './auth/resource'; + +const backend = defineBackend({ + auth }); // override userpool password policies backend.resources.auth.resources.cfnResources.cfnUserPool.addPropertyOverride( - "Policies", + 'Policies', { PasswordPolicy: { MinimumLength: 10, @@ -54,41 +116,44 @@ backend.resources.auth.resources.cfnResources.cfnUserPool.addPropertyOverride( RequireNumbers: true, RequireSymbols: true, RequireUppercase: true, - TemporaryPasswordValidityDays: 20, - }, + TemporaryPasswordValidityDays: 20 + } } ); ``` +Note the usage of `auth.resources.cfnResources`. This property exposes [L1 CDK Constructs](https://docs.aws.amazon.com/cdk/v2/guide/constructs.html#constructs_l1_using). These are constructs that map 1:1 with the underlying CloudFormation properties. -Below are additional example scenarios where you may want to override resources. - +The `auth.resources.cfnResources.cfnUserPool` property in the above example directly maps to the [AWS::Cognito::UserPool CloudFormation resource](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-userpool.html). -## Add tags to resources +This is different than `auth.resources.userPool` in the first example which is an [L2 CDK Construct](https://docs.aws.amazon.com/cdk/v2/guide/constructs.html#constructs_using). These are constructs that provide a convenient interface around several related L1 constructs. -### Amplify Data's underlying GraphQL API +## Example - Add tags to resources ```ts title="amplify/backend.ts" -import { defineBackend } from "@aws-amplify/backend"; -import { auth } from "./auth/resource.js"; -import { data } from "./data/resource.js"; +// amplify/backend.ts +import { defineBackend } from '@aws-amplify/backend'; +import { auth } from './auth/resource'; +import { data } from './data/resource'; const backend = defineBackend({ auth, - data, + data }); backend.resources.data.resources.cfnResources.cfnGraphqlApi.addPropertyOverride( - "Tags", + 'Tags', [ { - Key: "graphqlapi-tag-1", - Value: "graphql-tag-value-1", + Key: 'graphqlapi-tag-1', + Value: 'graphql-tag-value-1' }, { - Key: "graphqlapi-tag-2", - Value: "graphql-tag-value-2", - }, + Key: 'graphqlapi-tag-2', + Value: 'graphql-tag-value-2' + } ] ); ``` + +For even more customization of your backend, see [custom resources](/gen2/build-a-backend/add-aws-services/custom-resources) diff --git a/src/pages/gen2/start/quickstart/index.mdx b/src/pages/gen2/start/quickstart/index.mdx index b4349c3f8bf..a9427e5de73 100644 --- a/src/pages/gen2/start/quickstart/index.mdx +++ b/src/pages/gen2/start/quickstart/index.mdx @@ -369,7 +369,7 @@ export default function HomePage() { } ``` -Once you save the file and navigate back to `http://localhost:3000`, you should see an empty list of to-dos. +Once you save the file and navigate back to `http://localhost:3000`, you should see a blank page for now because you have only an empty list of to-dos. ### Create a new to-do item diff --git a/src/styles/banner.scss b/src/styles/banner.scss index ea097e0613b..d133ef79f19 100644 --- a/src/styles/banner.scss +++ b/src/styles/banner.scss @@ -9,6 +9,7 @@ &__inner { display: flex; flex-direction: column; + align-items: flex-start; } &__heading { font-weight: 700; @@ -18,12 +19,10 @@ color: var(--amplify-colors-purple-100); } &__button { - margin: 0 auto; background-color: var(--amplify-colors-purple-10); color: var(--amplify-colors-purple-80); border-color: var(--amplify-colors-purple-20); flex: 0 0 auto; - align-self: center; } } @@ -33,14 +32,3 @@ border: 1px solid var(--amplify-colors-teal-40); } } - -@container (min-width: 700px) { - .message-banner { - &__inner { - flex-direction: row; - } - &__button { - margin: auto 0; - } - } -}