diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 4bc3e60d1b8..e1ea17fb3d4 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -104,6 +104,7 @@ /src/themes @aws-amplify/documentation-team /src/utils @aws-amplify/documentation-team /tasks @aws-amplify/documentation-team +.github @aws-amplify/documentation-team #Protected Content /src/protected @reesscot @srquinn21 @Milan-Shah @swaminator diff --git a/.github/workflows/check_for_console_errors.yml b/.github/workflows/check_for_console_errors.yml new file mode 100644 index 00000000000..e3852ba97a0 --- /dev/null +++ b/.github/workflows/check_for_console_errors.yml @@ -0,0 +1,38 @@ +name: CheckConsoleErrors +on: + pull_request: + branches: [main] + types: [opened, synchronize] +permissions: + contents: read +jobs: + CheckConsoleErrors: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.2 https://github.com/actions/checkout/commit/b4ffde65f46336ab88eb53be808477a3936bae11 + - name: Setup Node.js 20.x + uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 https://github.com/actions/setup-node/commit/e33196f7422957bea03ed53f6fbb155025ffc7b8 + with: + node-version: 20.x + - name: Install Dependencies + run: yarn + - name: Run Build + run: yarn build:release + env: + NODE_OPTIONS: --max_old_space_size=4096 + - name: Run Server + run: | + python -m http.server 3000 -d ${{ vars.BUILD_DIR }} & + sleep 5 + - name: Run Console Errors + id: consoleErrors + uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6.4.1 https://github.com/actions/github-script/commit/d7906e4ad0b1822421a7e6a35d5ca353c962f410 + with: + result-encoding: string + script: | + const { consoleErrors } = require('./tasks/console-errors.js'); + return await consoleErrors(); + - name: Fail if console errors have been found + if: ${{ steps.consoleErrors.outputs.result }} + run: exit 1 diff --git a/cspell.json b/cspell.json index b97dae7ded7..69817bdd7eb 100644 --- a/cspell.json +++ b/cspell.json @@ -1520,7 +1520,7 @@ "privatesaccess", "menudetaileditors", "editorgroupaccess", - "publicauthreadonly", + "authreadonly", "envs", "Onetoone", "onetomany", diff --git a/package.json b/package.json index 73ee7d22885..7cb97565ea8 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,8 @@ "@adobe/css-tools": "4.3.2", "follow-redirects": "^1.15.6", "ip": "2.0.1", - "sharp": "0.32.6" + "sharp": "0.32.6", + "ejs": "3.1.10" }, "scripts": { "clean": "rm -rf node_modules yarn.lock", diff --git a/public/images/console/7_publicauthreadonly.png b/public/images/console/7_authreadonly.png similarity index 100% rename from public/images/console/7_publicauthreadonly.png rename to public/images/console/7_authreadonly.png diff --git a/src/components/BlockSwitcher/__tests__/BlockSwitcher.test.tsx b/src/components/BlockSwitcher/__tests__/BlockSwitcher.test.tsx index 7c9989f7d91..eae43ec719c 100644 --- a/src/components/BlockSwitcher/__tests__/BlockSwitcher.test.tsx +++ b/src/components/BlockSwitcher/__tests__/BlockSwitcher.test.tsx @@ -21,12 +21,12 @@ describe('BlockSwitcher', () => { const blockSwitcher = await screen.findByText(blockAContent); expect(blockSwitcher).toBeInTheDocument(); }); - + it('should have more than one Block', async () => { render(component); expect(component.props.children.length).toBeGreaterThan(1); }); - + it('should show the first Block as default', async () => { render(component); const tabs = await screen.getAllByRole('tab'); @@ -39,7 +39,7 @@ describe('BlockSwitcher', () => { expect(panels[1]).not.toHaveClass('amplify-tabs__panel--active'); expect(panels[2]).not.toHaveClass('amplify-tabs__panel--active'); }); - + it('should load all Blocks to the DOM', async () => { render(component); const blockA = await screen.findByText(blockAContent); @@ -49,7 +49,7 @@ describe('BlockSwitcher', () => { expect(blockB).toBeInTheDocument(); expect(blockC).toBeInTheDocument(); }); - + it('should switch tabs upon click', async () => { render(component); const tabs = await screen.getAllByRole('tab'); diff --git a/src/pages/[platform]/build-a-backend/auth/customize-auth-lifecycle/custom-auth-flows/index.mdx b/src/pages/[platform]/build-a-backend/auth/customize-auth-lifecycle/custom-auth-flows/index.mdx index bba14684a30..5dadf1e6cd6 100644 --- a/src/pages/[platform]/build-a-backend/auth/customize-auth-lifecycle/custom-auth-flows/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/customize-auth-lifecycle/custom-auth-flows/index.mdx @@ -6,14 +6,8 @@ export const meta = { 'Use Amazon Cognito Auth plugin to sign in a user into Amazon Cognito User Pool using user defined custom flow', platforms: [ 'android', - // 'angular', 'flutter', - // 'javascript', - // 'nextjs', - // 'react', - // 'react-native', 'swift', - // 'vue' ], }; @@ -41,7 +35,7 @@ An application with Amplify libraries integrated and a minimum target of any of - **watchOS 9.0**, using **Xcode 14.3** or later. - **visionOS 1.0**, using **Xcode 15 beta 2** or later. (Preview support - see below for more details.) -For a full example, please follow the [project setup walkthrough](/[platform]/start/project-setup/prerequisites/). +For a full example, please follow the [project setup walkthrough](/[platform]/start/quickstart/). @@ -66,7 +60,7 @@ For more information on adding capabilities to your application, see [Xcode Capa The custom auth flow can be [configured manually](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-challenge.html). -If you have already configured custom auth, you can use the custom auth flow by changing the `authenticationFlowType` value in your [Amplify configuration](/[platform]/build-a-backend/auth/existing-resources/) to `CUSTOM_AUTH`. +If you have already configured custom auth, you can use the custom auth flow by changing the `authenticationFlowType` value in your Amplify configuration to `CUSTOM_AUTH`. For more information on authentication flow types, you can check out the [Cognito documentation](https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-authentication-flow.html). ## Register a user @@ -244,7 +238,7 @@ Since this is a custom authentication flow with a challenge, the result of the s ## Confirm sign in with custom challenge -Get the custom challenge (`1234` in this case) from the user and pass it to the `confirmSignin()` api. +To get a custom challenge from the user, create an appropriate UI for the user to submit the required value, and pass that value into the `confirmSignin()` API. @@ -294,9 +288,9 @@ Confirm sign in succeeded ### Lambda Trigger Setup -AWS Amplify now supports creating functions as part of its new backend experience. For more information on the Functions and how to start with them check out [Functions documentation](/[platform]/build-a-backend/functions/). In addition, more information on available triggers can be found in the [Cognito documentation](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-challenge.html). +AWS Amplify now supports creating functions as part of its new backend experience. For more information on the Functions and how to start with them check out [Functions documentation](/[platform]/build-a-backend/functions/). In addition, more information on available triggers can be found in the [Cognito documentation](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html). -### Custom Auth Flow with SRP +### Custom Auth Flow with Secure Remote Password (SRP) Cognito User Pool allows to start the custom authentication flow with SRP as the first step. If you would like to use this flow, setup Define Auth Lambda trigger to handle SRP_A as the first challenge as shown below: @@ -337,64 +331,6 @@ let signInResult = try await Amplify.Auth.signIn( options: .init(pluginOptions: options)) ``` -### CAPTCHA-based authentication - -Here is the sample for creating a CAPTCHA challenge with a Lambda Trigger. - -The `Create Auth Challenge Lambda Trigger` creates a CAPTCHA as a challenge to the user. The URL for the CAPTCHA image and the expected answer is added to the private challenge parameters: - -```javascript -export const handler = async (event) => { - if (!event.request.session || event.request.session.length === 0) { - event.response.publicChallengeParameters = { - captchaUrl: , - }; - event.response.privateChallengeParameters = { - answer: , - }; - event.response.challengeMetadata = "CAPTCHA_CHALLENGE"; - } - return event; -}; -``` - -This `Define Auth Challenge Lambda Trigger` defines a custom challenge: - -```javascript -export const handler = async (event) => { - if (!event.request.session || event.request.session.length === 0) { - // If we don't have a session or it is empty then send a CUSTOM_CHALLENGE - event.response.challengeName = "CUSTOM_CHALLENGE"; - event.response.failAuthentication = false; - event.response.issueTokens = false; - } else if (event.request.session.length === 1 && event.request.session[0].challengeResult === true) { - // If we passed the CUSTOM_CHALLENGE then issue token - event.response.failAuthentication = false; - event.response.issueTokens = true; - } else { - // Something is wrong. Fail authentication - event.response.failAuthentication = true; - event.response.issueTokens = false; - } - - return event; -}; -``` - -The `Verify Auth Challenge Response Lambda Trigger` is used to verify a challenge answer: - -```javascript -export const handler = async (event, context) => { - if (event.request.privateChallengeParameters.answer === event.request.challengeAnswer) { - event.response.answerCorrect = true; - } else { - event.response.answerCorrect = false; - } - - return event; -}; -``` - The Auth category can be configured to perform a [custom authentication flow](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-challenge.html) defined by you. The following guide shows how to setup a simple passwordless authentication flow. @@ -402,13 +338,13 @@ The Auth category can be configured to perform a [custom authentication flow](ht ## Prerequisites * An Android application targeting at least Android SDK API level 24 with Amplify libraries integrated - * For a full example of creating Android project, please follow the [project setup walkthrough](/[platform]/start/project-setup/create-application/) + * For a full example of creating Android project, please follow the [project setup walkthrough](/[platform]/start/quickstart/) ## Configure Auth The custom auth flow can be [configured manually](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-challenge.html). -If you have already configured custom auth, you can use the custom auth flow by changing the `authenticationFlowType` value in your [Amplify configuration](/[platform]/build-a-backend/auth/existing-resources/) to `CUSTOM_AUTH`. +If you have already configured custom auth, you can use the custom auth flow by changing the `authenticationFlowType` value in your Amplify configuration to `CUSTOM_AUTH`. For more information on authentication flow types, you can check out the [Cognito documentation](https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-authentication-flow.html). ## Register a user @@ -683,9 +619,9 @@ Confirm sign in succeeded ### Lambda Trigger Setup -AWS Amplify now supports creating functions as part of the AWS Amplify. For more information on the Functions and how to start with them check out [Functions documentation](/[platform]/build-a-backend/functions/). In addition, more information on available triggers can be found in the [Cognito documentation](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-challenge.html). +AWS Amplify now supports creating functions as part of the AWS Amplify. For more information on the Functions and how to start with them check out [Functions documentation](/[platform]/build-a-backend/functions/). In addition, more information on available triggers can be found in the [Cognito documentation](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html). -### Custom Auth Flow with SRP +### Custom Auth Flow with Secure Remote Password (SRP) Cognito User Pool allows to start the custom authentication flow with SRP as the first step. If you would like to use this flow, setup Define Auth Lambda trigger to handle SRP_A as the first challenge as shown below: @@ -793,64 +729,6 @@ RxAmplify.Auth.signIn("username", "password", options) -### CAPTCHA-based authentication - -Here is the sample for creating a CAPTCHA challenge with a Lambda Trigger. - -The `Create Auth Challenge Lambda Trigger` creates a CAPTCHA as a challenge to the user. The URL for the CAPTCHA image and the expected answer are added to the private challenge parameters: - -```javascript -export const handler = async (event) => { - if (!event.request.session || event.request.session.length === 0) { - event.response.publicChallengeParameters = { - captchaUrl: , - }; - event.response.privateChallengeParameters = { - answer: , - }; - event.response.challengeMetadata = "CAPTCHA_CHALLENGE"; - } - return event; -}; -``` - -This `Define Auth Challenge Lambda Trigger` defines a custom challenge: - -```javascript -export const handler = async (event) => { - if (!event.request.session || event.request.session.length === 0) { - // If we don't have a session or it is empty then send a CUSTOM_CHALLENGE - event.response.challengeName = "CUSTOM_CHALLENGE"; - event.response.failAuthentication = false; - event.response.issueTokens = false; - } else if (event.request.session.length === 1 && event.request.session[0].challengeResult === true) { - // If we passed the CUSTOM_CHALLENGE then issue token - event.response.failAuthentication = false; - event.response.issueTokens = true; - } else { - // Something is wrong. Fail authentication - event.response.failAuthentication = true; - event.response.issueTokens = false; - } - - return event; -}; -``` - -The `Verify Auth Challenge Response Lambda Trigger` is used to verify a challenge answer: - -```javascript -export const handler = async (event, context) => { - if (event.request.privateChallengeParameters.answer === event.request.challengeAnswer) { - event.response.answerCorrect = true; - } else { - event.response.answerCorrect = false; - } - - return event; -}; -``` - @@ -859,13 +737,13 @@ The Auth category can be configured to perform a [custom authentication flow](ht ## Prerequisites A Flutter application targeting Flutter SDK >= 3.3.0 with Amplify libraries integrated. -Amplify requires a minimum target platform for iOS (13.0), Android (API level 24), and macOS (10.15). Additional setup is required for some target platforms. Please see the [platform setup](/[platform]/start/project-setup/platform-setup/) guide for more details on platform specific setup. +Amplify requires a minimum target platform for iOS (13.0), Android (API level 24), and macOS (10.15). Additional setup is required for some target platforms. Please see the [platform setup](/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/#platform-setup) for more details on platform specific setup. ## Configure Auth The custom auth flow can be [configured manually](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-challenge.html). -If you have already configured custom auth, you can use the custom auth flow by changing the `authenticationFlowType` value in your [Amplify configuration](/[platform]/build-a-backend/auth/existing-resources/) to `CUSTOM_AUTH`. +If you have already configured custom auth, you can use the custom auth flow by changing the `authenticationFlowType` value in your Amplify configuration to `CUSTOM_AUTH`. For more information on authentication flow types, you can check out the [Cognito documentation](https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-authentication-flow.html). ## Register a user @@ -946,7 +824,7 @@ user has already signed in and a valid session is active. You must first call ## Confirm sign in with custom challenge -Get the custom challenge (`1234` in this case) from the user and pass it to the `confirmSignin()` api. +To get a custom challenge from the user, create an appropriate UI for the user to submit the required value, and pass that value into the `confirmSignin()` API. ```dart Future confirmSignIn(String generatedNumber) async { @@ -977,7 +855,7 @@ Exception: `NotAuthorizedException` with a message `Invalid session for the user The example in this documentation demonstrates the passwordless custom authentication flow. However, it is also possible to require that users supply a valid password as part of the custom authentication flow. -To require a valid password, you can alter the `DefineAuthChallenge` code to handle a `PASSWORD_VERIFIER` step: +To require a valid password, you can alter the [DefineAuthChallenge](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-define-auth-challenge.html) code to handle a `PASSWORD_VERIFIER` step: ```js exports.handler = async (event) => { diff --git a/src/pages/[platform]/build-a-backend/auth/set-up-auth/index.mdx b/src/pages/[platform]/build-a-backend/auth/set-up-auth/index.mdx index 232b6d4dddf..6274837684d 100644 --- a/src/pages/[platform]/build-a-backend/auth/set-up-auth/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/set-up-auth/index.mdx @@ -92,7 +92,7 @@ npx ampx sandbox -After a successful deployment, this command also generates a configuration file (`amplify_outputs.json`) to enable your frontend app to connect to your backend resources. The values you configure in your backend authentication resource are set in the generated configuration file to automatically configure the frontend [`Authenticator connected component`](https://ui.docs.amplify.aws/react/connected-components/authenticator). +After a successful deployment, this command also generates an outputs file (`amplify_outputs.json`) to enable your frontend app to connect to your backend resources. The values you configure in your backend authentication resource are set in the generated outputs file to automatically configure the frontend [`Authenticator connected component`](https://ui.docs.amplify.aws/react/connected-components/authenticator). ## Connect your application code to your auth resource diff --git a/src/pages/[platform]/build-a-backend/data/set-up-data/index.mdx b/src/pages/[platform]/build-a-backend/data/set-up-data/index.mdx index f0af72a15da..307d1958169 100644 --- a/src/pages/[platform]/build-a-backend/data/set-up-data/index.mdx +++ b/src/pages/[platform]/build-a-backend/data/set-up-data/index.mdx @@ -113,11 +113,11 @@ npx ampx sandbox --outputs-format dart --outputs-out-dir lib ## Connect your application code to the data backend -Once the cloud sandbox is up and running, it will also create an `amplifyconfiguration.json` file, which includes the relevant connection information to your data backend, like your API endpoint URL and API key. +Once the cloud sandbox is up and running, it will also create an `amplify_outputs.json` file, which includes the relevant connection information to your data backend, like your API endpoint URL and API key. To connect your frontend code to your backend, you need to: -1. configure the Amplify library with the Amplify client configuration file +1. configure the Amplify library with the Amplify client configuration file (`amplify_outputs.json`) 2. generate a new API client from the Amplify library 3. make an API request with end-to-end type-safety @@ -133,9 +133,9 @@ In your app's entry point, typically **main.tsx** for React apps created using V ```tsx title="src/main.tsx" import { Amplify } from 'aws-amplify'; -import config from '../amplifyconfiguration.json'; +import outputs from '../amplify_outputs.json'; -Amplify.configure(config); +Amplify.configure(outputs); ``` diff --git a/src/pages/[platform]/build-a-backend/server-side-rendering/index.mdx b/src/pages/[platform]/build-a-backend/server-side-rendering/index.mdx index 8d83a5d21dd..56f3e58bae5 100644 --- a/src/pages/[platform]/build-a-backend/server-side-rendering/index.mdx +++ b/src/pages/[platform]/build-a-backend/server-side-rendering/index.mdx @@ -46,16 +46,16 @@ npm add aws-amplify @aws-amplify/adapter-nextjs You will need to create a `runWithAmplifyServerContextRunner` function to use Amplify APIs on the server-side of your Next.js app. -You can create an `amplifyServerUtils.ts` file under a `utils` folder in your codebase. In this file, you will import the Amplify configuration object from the `amplifyconfiguration.json` file that is generated by the Amplify CLI, and use the `createServerRunner` function to create the `runWithAmplifyServerContextRunner` function. +You can create an `amplifyServerUtils.ts` file under a `utils` folder in your codebase. In this file, you will import the Amplify backend outputs from the `amplify_outputs.json` file that is generated by the Amplify CLI, and use the `createServerRunner` function to create the `runWithAmplifyServerContextRunner` function. For example, the `utils/amplifyServerUtils.ts` file may contain the following content: ```typescript import { createServerRunner } from '@aws-amplify/adapter-nextjs'; -import config from '@/amplifyconfiguration.json'; +import outputs from '@/amplify_outputs.json'; export const { runWithAmplifyServerContext } = createServerRunner({ - config + outputs }); ``` @@ -78,10 +78,10 @@ When you use the Amplify library on the client-side of your Next.js app, you wil ```typescript 'use client'; -import config from '@/amplifyconfiguration.json'; +import outputs from '@/amplify_outputs.json'; import { Amplify } from 'aws-amplify'; -Amplify.configure(config, { +Amplify.configure(outputs, { ssr: true // required when using Amplify with Next.js }); @@ -110,9 +110,9 @@ If you're using the Next.js App Router, you can create a client component to con 'use client'; import { Amplify } from 'aws-amplify'; -import config from '../amplifyconfiguration.json'; +import outputs from '../amplify_outputs.json'; -Amplify.configure(config, { ssr: true }); +Amplify.configure(outputs, { ssr: true }); export default function ConfigureAmplifyClientSide() { return null; diff --git a/src/pages/[platform]/build-a-backend/server-side-rendering/nextjs-app-router-server-components/index.mdx b/src/pages/[platform]/build-a-backend/server-side-rendering/nextjs-app-router-server-components/index.mdx index 86bb3e049c4..b225f35fdc2 100644 --- a/src/pages/[platform]/build-a-backend/server-side-rendering/nextjs-app-router-server-components/index.mdx +++ b/src/pages/[platform]/build-a-backend/server-side-rendering/nextjs-app-router-server-components/index.mdx @@ -61,9 +61,9 @@ Next, create a `components` folder in the root of your project and copy the cont import { Amplify } from "aws-amplify"; -import config from "@/amplifyconfiguration.json"; +import outputs from "@/amplify_outputs.json"; -Amplify.configure(config, { ssr: true }); +Amplify.configure(outputs, { ssr: true }); export default function ConfigureAmplifyClientSide() { return null; @@ -123,10 +123,10 @@ import { generateServerClientUsingCookies } from "@aws-amplify/adapter-nextjs/ap import { getCurrentUser } from "aws-amplify/auth/server"; import { type Schema } from "@/amplify/data/resource"; -import config from "@/amplifyconfiguration.json"; +import outputs from "@/amplify_outputs.json"; export const { runWithAmplifyServerContext } = createServerRunner({ - config, + outputs, }); export const cookiesClient = generateServerClientUsingCookies({ diff --git a/src/pages/[platform]/build-ui/formbuilder/lifecycle/index.mdx b/src/pages/[platform]/build-ui/formbuilder/lifecycle/index.mdx index bc977dffb03..3eb1a8be997 100644 --- a/src/pages/[platform]/build-ui/formbuilder/lifecycle/index.mdx +++ b/src/pages/[platform]/build-ui/formbuilder/lifecycle/index.mdx @@ -58,7 +58,7 @@ Hook into the form's lifecycle events to customize user input before submission, ## Get form data as your user inputs data - onChange -In some cases, you want to get the form data in real-time as the user is filling the form. The `onChange` event provides you the form data in the `fields` parameter. We recommend you to use `onChange` if you opted to [hide all form action buttons](/gen1/[platform]/build-ui/formbuilder/call-to-action/#toggle-visibility-for-submit-cancel-clear-and-reset-buttons) (Submit, Cancel, Clear, Reset). +In some cases, you want to get the form data in real-time as the user is filling the form. The `onChange` event provides you the form data in the `fields` parameter. ```jsx import { useState } from 'react' @@ -75,7 +75,7 @@ function App() { ## Extend validation rules in code - onValidate -With the `onValidate` event, you can extend the validation rules in code. Learn more about [How to add validation rules](/gen1/[platform]/build-ui/formbuilder/validations/). +With the `onValidate` event, you can extend the validation rules in code. Learn more about [How to add validation rules](/[platform]/build-ui/formbuilder/validations/). ## Handle form data submissions - onSubmit diff --git a/src/pages/[platform]/build-ui/formbuilder/special-inputs/index.mdx b/src/pages/[platform]/build-ui/formbuilder/special-inputs/index.mdx index 04691236c22..10648a52901 100644 --- a/src/pages/[platform]/build-ui/formbuilder/special-inputs/index.mdx +++ b/src/pages/[platform]/build-ui/formbuilder/special-inputs/index.mdx @@ -28,12 +28,12 @@ export function getStaticProps(context) { ## Storage Manager -[**Storage Manager**](https://ui.docs.amplify.aws/react/connected-components/storage/storagemanager) fields allow your forms to accept file uploads, which are stored in an Amazon S3 bucket connected to your Amplify app. After uploading, that file's S3 key is stored in your data model, allowing for systematic retrieval using the [Amplify JS library](/gen1/[platform]/build-a-backend/storage/download/). +[**Storage Manager**](https://ui.docs.amplify.aws/react/connected-components/storage/storagemanager) fields allow your forms to accept file uploads, which are stored in an Amazon S3 bucket connected to your Amplify app. After uploading, that file's S3 key is stored in your data model, allowing for systematic retrieval using the [Amplify JS library](/[platform]/build-a-backend/storage/download-files/). ### Prerequisites -In order to use the Storage Manager field, your Amplify app must have an Amplify app with [Authentication](react/build-a-backend/auth/set-up-auth/) and [Storage](react/build-a-backend/storage/define-storage/) enabled. +In order to use the Storage Manager field, your Amplify app must have an Amplify app with [Authentication](/[platform]/build-a-backend/auth/set-up-auth/) and [Storage](/[platform]/build-a-backend/storage/set-up-storage/) enabled. ### How it works diff --git a/src/pages/[platform]/deploy-and-host/fullstack-branching/cross-account-deployments/index.mdx b/src/pages/[platform]/deploy-and-host/fullstack-branching/cross-account-deployments/index.mdx index 96a2d2cfede..68254b42a6a 100644 --- a/src/pages/[platform]/deploy-and-host/fullstack-branching/cross-account-deployments/index.mdx +++ b/src/pages/[platform]/deploy-and-host/fullstack-branching/cross-account-deployments/index.mdx @@ -53,7 +53,7 @@ Please refer to this Amazon CodeCatalyst [guide](https://docs.aws.amazon.com/cod ### Step 3: Update build specification -Add the `npx ampx generate outputs --branch $AWS_BRANCH --app-id $AWS_APP_ID` command to the build spec and comment out the `npx ampx pipeline-deploy --branch $AWS_BRANCH --app-id $AWS_APP_ID` command. `ampx pipeline-deploy` runs a script to deploy backend updates, while `amplify generate config` fetches the latest `amplifyconfiguration.json` for the specified environment. +Add the `npx amplify generate config --branch $AWS_BRANCH --app-id $AWS_APP_ID` command to the build spec and comment out the `npx amplify pipeline-deploy --branch $AWS_BRANCH --app-id $AWS_APP_ID` command. `amplify pipeline-deploy` runs a script to deploy backend updates, while `amplify generate config` fetches the latest `amplify_outputs.json` for the specified environment. ![Screenshot of Build image settings section in AWS Amplify Gen 2 console, with details about the app build specification](images/gen2/cross-account-deployments/pipeline10.png) @@ -183,4 +183,4 @@ Next, you can review the result of the workflow run from the **Runs** tab: ![Screenshot of CodeCatalyst console showing the Workflows section, focusing on the Runs tab](images/gen2/cross-account-deployments/pipeline11.png) -Done! You have successfully set up a custom cross-account pipeline to deploy your frontend and backend for apps built using Amplify Gen 2. To summarize, this custom pipeline will enable you to deploy your backend initially with your `staging` environment using `ampx pipeline-deploy` in the CodeCatalyst workflow and `amplify generate config` will generate the `amplifyconfiguration.json` file for the `main` branch. Amplify Hosting will not deploy backend resources as part of the build and instead will use the deployed backend resources from the `main` branch. Once the staging environment deploys successfully, a similar process will be followed to deploy your `production` environment in a different AWS account. +Done! You have successfully set up a custom cross-account pipeline to deploy your frontend and backend for apps built using Amplify Gen 2. To summarize, this custom pipeline will enable you to deploy your backend initially with your `staging` environment using `amplify pipeline-deploy` in the CodeCatalyst workflow and `amplify generate config` will generate the `amplify_outputs.json` file for the `main` branch. Amplify Hosting will not deploy backend resources as part of the build and instead will use the deployed backend resources from the `main` branch. Once the staging environment deploys successfully, a similar process will be followed to deploy your `production` environment in a different AWS account. diff --git a/src/pages/[platform]/deploy-and-host/fullstack-branching/custom-pipelines/index.mdx b/src/pages/[platform]/deploy-and-host/fullstack-branching/custom-pipelines/index.mdx index fee4774aa8f..e65f045d97e 100644 --- a/src/pages/[platform]/deploy-and-host/fullstack-branching/custom-pipelines/index.mdx +++ b/src/pages/[platform]/deploy-and-host/fullstack-branching/custom-pipelines/index.mdx @@ -43,7 +43,7 @@ You can set up your backend deployments using the following steps: -3. Update the Amplify build-spec to add `npx ampx generate outputs --branch $AWS_BRANCH --app-id $AWS_APP_ID` and comment out the `pipeline-deploy` script. `ampx pipeline-deploy` runs a script to deploy backend updates, while `amplify generate config` fetches the latest `amplifyconfiguration.json` for the specified environment. +3. Update the Amplify build-spec to add `npx amplify generate config --branch $AWS_BRANCH --app-id $AWS_APP_ID` and comment out the `pipeline-deploy` script. `amplify pipeline-deploy` runs a script to deploy backend updates, while `amplify generate config` fetches the latest `amplify_outputs.json` for the specified environment. ![custom-ci](/images/gen2/fullstack-branching/custom-ci.png) @@ -114,4 +114,4 @@ aws amplify create-webhook --app-id AMPLIFY-APPID --branch-name main --region R -H "Content-Type:application/json"; fi ``` -4. This should trigger a build in your Amplify app. Amplify CI will build and first generate the `amplifyconfiguration.json` for the branch and then build, deploy, and host the frontend. +4. This should trigger a build in your Amplify app. Amplify CI will build and first generate the `amplify_outputs.json` for the branch and then build, deploy, and host the frontend. diff --git a/src/pages/[platform]/deploy-and-host/fullstack-branching/mono-and-multi-repos/index.mdx b/src/pages/[platform]/deploy-and-host/fullstack-branching/mono-and-multi-repos/index.mdx index 7922a04d84d..dd0b8ed6729 100644 --- a/src/pages/[platform]/deploy-and-host/fullstack-branching/mono-and-multi-repos/index.mdx +++ b/src/pages/[platform]/deploy-and-host/fullstack-branching/mono-and-multi-repos/index.mdx @@ -65,11 +65,11 @@ npm add @aws-amplify/backend-cli aws-amplify @aws-amplify/ui-react npx ampx generate outputs --branch main --app-id BACKEND-APPID ``` -This will generate the `amplifyconfiguration.json` file that contains all the information about your backend at the root of your project. +This will generate the `amplify_outputs.json` file that contains all the information about your backend at the root of your project. Screenshot of project folder contents with amplifyconfiguration.json file highlighted @@ -79,13 +79,13 @@ This will generate the `amplifyconfiguration.json` file that contains all the in // pages/_app.tsx import { withAuthenticator } from '@aws-amplify/ui-react'; import { Amplify } from 'aws-amplify'; -import config from '@/amplifyconfiguration.json'; +import outputs from '@/amplify_outputs.json'; import '@aws-amplify/ui-react/styles.css'; import '@/styles/globals.css'; import type { AppProps } from 'next/app'; -// configure the Amplify client library with the configuration generated by `ampx sandbox` -Amplify.configure(config); +// configure the Amplify client library with the configuration generated by `amplify sandbox` +Amplify.configure(outputs); function App({ Component, pageProps }: AppProps) { return ; diff --git a/src/pages/[platform]/deploy-and-host/fullstack-branching/share-resources/index.mdx b/src/pages/[platform]/deploy-and-host/fullstack-branching/share-resources/index.mdx index c4d872f8e63..45d6a6841d2 100644 --- a/src/pages/[platform]/deploy-and-host/fullstack-branching/share-resources/index.mdx +++ b/src/pages/[platform]/deploy-and-host/fullstack-branching/share-resources/index.mdx @@ -37,7 +37,7 @@ You can update your app build settings to share resources across branches. From ![The build specification YAML file on the Build settings page in Amplify console.](/images/gen2/fullstack-branching/build-settings.png) -Update the build settings for the `backend` phase to run `npx ampx generate outputs --branch dev app-id $AWS_APP_ID` to generate the `amplifyconfiguration.json` file for all branches other than `main` or `dev`. After this update, any new deployed branches will not deploy backend resources as part of the build and instead will use the deployed backend resources from the `dev` branch. +Update the build settings for the `backend` phase to run `npx amplify generate config --branch dev app-id $AWS_APP_ID` to generate the `amplify_outputs.json` file for all branches other than `main` or `dev`. After this update, any new deployed branches will not deploy backend resources as part of the build and instead will use the deployed backend resources from the `dev` branch. ```yaml title="amplify.yml" version: 1 diff --git a/src/pages/[platform]/reference/cli-commands/index.mdx b/src/pages/[platform]/reference/cli-commands/index.mdx index 7ef866523b6..23eaaaf61dc 100644 --- a/src/pages/[platform]/reference/cli-commands/index.mdx +++ b/src/pages/[platform]/reference/cli-commands/index.mdx @@ -225,7 +225,7 @@ npx ampx generate outputs --stack amplify-nextamplifygen2-josef-sandbox-ca85e108 #### Use with mobile applications -Similar to `sandbox`, you can specify an alternate configuration file format by using `--format`: +Similar to `sandbox`, you can specify an alternate outputs file format by using `--format`: ```bash title="Terminal" showLineNumbers={false} npx ampx generate outputs --stack amplify-nextamplifygen2-josef-sandbox-ca85e1081b diff --git a/src/pages/gen1/[platform]/build-a-backend/storage/configure-access/index.mdx b/src/pages/gen1/[platform]/build-a-backend/storage/configure-access/index.mdx index e42414f412d..92d95900ab0 100644 --- a/src/pages/gen1/[platform]/build-a-backend/storage/configure-access/index.mdx +++ b/src/pages/gen1/[platform]/build-a-backend/storage/configure-access/index.mdx @@ -44,7 +44,7 @@ import common_configureaccess from '/src/fragments/lib/storage/native_common/con We recommend using the new [Amplify Gen2](https://docs.amplify.aws/gen2/build-a-backend/storage/) experience when defining file access permissions as it offers a more flexible approach to customize access to files. -Note: `accessLevel` parameter is deprecated and maybe removed in next major version. +Note: `accessLevel` parameter is deprecated and may be removed in the next major version. Storage module can manage files with three different access levels; `guest`, `protected` and `private`. The Amplify CLI configures three different access levels on the storage bucket: guest, protected and private. When you run `amplify add storage`, the CLI will configure appropriate IAM policies on the bucket using a Cognito identity pool Role. You will have the option of adding CRUD (Create/Update, Read and Delete) based permissions as well, so that Authenticated and Guest users will be granted limited permissions within these levels. diff --git a/src/pages/gen1/[platform]/build-a-backend/storage/list/index.mdx b/src/pages/gen1/[platform]/build-a-backend/storage/list/index.mdx index 8039f3658d6..737f01bec5e 100644 --- a/src/pages/gen1/[platform]/build-a-backend/storage/list/index.mdx +++ b/src/pages/gen1/[platform]/build-a-backend/storage/list/index.mdx @@ -250,4 +250,8 @@ const loadNextPage = async () => { Note: The range of pageSize can be from 0 - 1000. +## List with no prefix (Deprecated) + +The usage of the `list` API without a specified prefix `await list()` or with an empty string as the prefix `await list({ prefix: "" })` is now deprecated and may be removed in the next major version. + diff --git a/src/pages/gen1/[platform]/build-a-backend/storage/path/index.mdx b/src/pages/gen1/[platform]/build-a-backend/storage/path/index.mdx index 23f9c4627a8..e99205a0874 100644 --- a/src/pages/gen1/[platform]/build-a-backend/storage/path/index.mdx +++ b/src/pages/gen1/[platform]/build-a-backend/storage/path/index.mdx @@ -42,7 +42,8 @@ export function getStaticProps(context) { You can now use the `path` parameter in the API to access any path within your S3 bucket. This provides more flexibility than the predefined `protected`, `private`, or `guest` folder access levels, allowing you to create and manage a storage structure tailored to your needs. -Note : `path` parameter can not be empty or start with a '/' (leading slash) +Note: `path` parameter can not be empty or start with a '/' (leading slash) + The sections below explain how to use existing `guest`, `protected`, and `private` resources with path-based APIs. ## Using Guest accessLevel diff --git a/src/pages/gen1/[platform]/tools/console/authz/permissions/index.mdx b/src/pages/gen1/[platform]/tools/console/authz/permissions/index.mdx index 55ffd5832bf..28c1372be93 100644 --- a/src/pages/gen1/[platform]/tools/console/authz/permissions/index.mdx +++ b/src/pages/gen1/[platform]/tools/console/authz/permissions/index.mdx @@ -71,4 +71,4 @@ If you want your data model to be publicly accessible, switch to API_KEY or IAM 1. Using the *Books* data model that you created in the [Create a data model example](/gen1/[platform]/tools/console/data/data-model/#Create-a-data-model-example), set the authorization mode to **API Key**. 2. In the **Model** pane on the right, expand the **Anyone** window. Choose **Read** to specify that any signed in user has read access to the data in the *Book* model. -![](/images/console/7_publicauthreadonly.png) +![](/images/console/7_authreadonly.png) diff --git a/tasks/console-errors.js b/tasks/console-errors.js new file mode 100644 index 00000000000..cdc750fe460 --- /dev/null +++ b/tasks/console-errors.js @@ -0,0 +1,109 @@ +const puppeteer = require('puppeteer'); // eslint-disable-line +const { getSitemapUrls } = require('./get-sitemap-links'); // eslint-disable-line + +// Here we are excluding shortbread errors because these are domain specific and are expected to fail in a local environment +const excludedErrors = [ + { + type: 'Shortbread', + errorText: + "Shortbread failed to set user's cookie preference because the domain name that was passed" + } +]; + +const excludedScripts = [ + 'prod.assets.shortbread.aws', + 'prod.tools.shortbread.aws', + 'prod.tools.shortbread.aws.dev', + 'aa0.awsstatic.com', + 'alpha.d2c.marketing.aws.dev', + 'vs-alpha.aws.amazon.com' +]; + +const LOCALHOST = 'http://localhost:3000'; + +const checkPage = async (url) => { + const errorsFound = []; + const browser = await puppeteer.launch({ headless: 'new' }); + + const page = await browser.newPage(); + + await page.setRequestInterception(true); + + page + .on('pageerror', (message) => { + const errorText = message.message; + const excluded = excludedErrors.some((excludedError) => { + return errorText.includes(excludedError.errorText); + }); + + if (!excluded) { + errorsFound.push({ + page: url, + message: errorText + }); + } + }) + .on('console', (message) => { + if (message.type().toLowerCase() === 'error') { + const errorText = message.text(); + const callingScript = message.location().url; + const excludedFromError = excludedErrors.some((excludedError) => { + return errorText.includes(excludedError.errorText); + }); + const excludedFromScript = excludedScripts.some((excludedScript) => { + return callingScript.includes(excludedScript); + }); + const excluded = excludedFromError || excludedFromScript; + + if (!excluded) { + errorsFound.push({ + page: url, + message: errorText, + stackTrace: message.stackTrace() + }); + } + } + }) + + .on('request', (interceptedRequest) => { + const excludedFromScript = excludedScripts.some((excludedScript) => { + return interceptedRequest.url().includes(excludedScript); + }); + if (excludedFromScript) { + interceptedRequest.abort(); + } else interceptedRequest.continue(); + }); + + await page.goto(url, { waitUntil: 'domcontentloaded' }); + + await browser.close(); + + return errorsFound; +}; + +const consoleErrors = async (domain) => { + const pagesToCheck = await getSitemapUrls(domain); + let errorMessage = ''; + for (let i = 0; i < pagesToCheck.length; i++) { + const url = pagesToCheck[i]; + console.log(`checking page ${url}`); + const errorsFound = await checkPage(url); + errorsFound.forEach((error) => { + errorMessage += `${error.message} found on ${error.page}\n`; + }); + } + if (errorMessage != '') { + console.log( + `--------- Console errors have been found and need to be resolved in order to merge. ------- + ------- Please note that these errors could be on pages that were not edited in this PR. ---------` + ); + console.log(errorMessage); + } + return errorMessage; +}; + +module.exports = { + consoleErrors: async (domain = LOCALHOST) => { + return await consoleErrors(domain); + } +}; diff --git a/tasks/get-sitemap-links.js b/tasks/get-sitemap-links.js new file mode 100644 index 00000000000..8e40ac783a2 --- /dev/null +++ b/tasks/get-sitemap-links.js @@ -0,0 +1,42 @@ +const puppeteer = require('puppeteer'); // eslint-disable-line + +const DOMAIN = 'https://docs.amplify.aws'; +const SITEMAP_URL = 'https://docs.amplify.aws/sitemap.xml'; + +const getSitemapUrls = async (localDomain) => { + let browser = await puppeteer.launch({ headless: 'new' }); + + const page = await browser.newPage(); + + let siteMap = localDomain ? `${localDomain}/sitemap.xml` : SITEMAP_URL; + let response = await page.goto(siteMap); + + const siteMapUrls = []; + + if (response && response.status() && response.status() === 200) { + const urlTags = await page.evaluateHandle(() => { + return document.getElementsByTagName('loc'); + }); + const numOfLinks = await page.evaluate((e) => e.length, urlTags); + for (let i = 0; i < numOfLinks; i++) { + let url = await page.evaluate( + (urlTags, i) => urlTags[i].innerHTML, + urlTags, + i + ); + if (localDomain) { + // Currently the sitemap is always generated with the prod docs domain so we need to replace this with localhost + url = url.replace(DOMAIN, localDomain); + } + siteMapUrls.push(url); + } + } + browser.close(); + return siteMapUrls; +}; + +module.exports = { + getSitemapUrls: async (domain) => { + return await getSitemapUrls(domain); + } +}; diff --git a/yarn.lock b/yarn.lock index 2dec273099d..33e00175b74 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5105,10 +5105,10 @@ eastasianwidth@^0.2.0: resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== -ejs@^3.1.7: - version "3.1.9" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.9.tgz#03c9e8777fe12686a9effcef22303ca3d8eeb361" - integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== +ejs@3.1.10, ejs@^3.1.7: + version "3.1.10" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b" + integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA== dependencies: jake "^10.8.5" @@ -5170,11 +5170,6 @@ enquirer@^2.3.6: ansi-colors "^4.1.1" strip-ansi "^6.0.1" -entities@^4.2.0, entities@^4.4.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" - integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== - env-paths@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"