generated from NHSDigital/nhs-notify-repository-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CCM-5100: Amplify + Cognito Authentication PoC
* Log in form * Example federation with Auth0 OIDC IDP * Terraform modules for deploying Cognito and Amplify * Terraform module for deploying Amplify branch and associated Cognito client app config * Server and client-side auth * Redirect handling on successful auth
- Loading branch information
Showing
84 changed files
with
22,224 additions
and
1,107 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# These are the settings for the dev user pool | ||
USER_POOL_ID=eu-west-2_fhHtnXS3G | ||
USER_POOL_CLIENT_ID=<client ID> | ||
HOSTED_LOGIN_DOMAIN=nhsnotify-iam-dev-auth-userpool.auth.eu-west-2.amazoncognito.com | ||
|
||
NOTIFY_STAGE=nonprod | ||
NOTIFY_ENVIRONMENT=dev | ||
AWS_APP=d1axbs26ewhyx4 | ||
AWS_BRANCH=main | ||
|
||
# Customise the branch or repository to deploy from an alternative source | ||
#TF_VAR_branch=miho6/CCM-5100-authn-poc | ||
#TF_VAR_repository=https://github.com/m-houston/nhs-notify-iam | ||
|
||
# Use a GitHub Personal Access Token to deploy a new Amplify integration (connect to a GitHub repo) | ||
TF_VAR_github_pat=<github_pat_xxxx> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
version: 1 | ||
backend: | ||
phases: | ||
build: | ||
commands: | ||
- npm ci --cache .npm --prefer-offline | ||
- npx ampx pipeline-deploy --branch $AWS_BRANCH --app-id $AWS_APP_ID | ||
frontend: | ||
phases: | ||
build: | ||
commands: | ||
- npm run build | ||
artifacts: | ||
baseDirectory: .next | ||
files: | ||
- '**/*' | ||
cache: | ||
paths: | ||
- .next/cache/**/* | ||
- .npm/**/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { DeepPartialAmplifyGeneratedConfigs } from '@aws-amplify/plugin-types'; | ||
import { ClientConfig } from '@aws-amplify/client-config'; | ||
|
||
const userPoolId = process.env.USER_POOL_ID!; | ||
const userPoolClientId = process.env.USER_POOL_CLIENT_ID!; | ||
const hostedLoginDomain = process.env.HOSTED_LOGIN_DOMAIN!; | ||
|
||
const appId = process.env.AWS_APP_ID!; | ||
const stage = process.env.NOTIFY_STAGE!; | ||
const subdomain = process.env.NOTIFY_SUBDOMAIN!; | ||
const domainName = process.env.NOTIFY_DOMAIN_NAME!; | ||
|
||
export const authConfig: DeepPartialAmplifyGeneratedConfigs<ClientConfig> = { | ||
auth: { | ||
aws_region: 'eu-west-2', | ||
user_pool_id: userPoolId, | ||
user_pool_client_id: userPoolClientId, | ||
oauth: { | ||
'identity_providers': [], | ||
'domain': hostedLoginDomain, | ||
'scopes': [ | ||
'openid', | ||
'email', | ||
'profile', | ||
'phone', | ||
'aws.cognito.signin.user.admin' | ||
], | ||
'redirect_sign_in_uri': [ | ||
`https://${subdomain}.${appId}.amplifyapp.com/auth/`, | ||
`https://${subdomain}.${domainName}/auth/`, | ||
...(stage === 'nonprod' ? ['http://localhost:3000/auth/']: []) | ||
], | ||
'redirect_sign_out_uri': [ | ||
`https://${subdomain}.${appId}.amplifyapp.com/`, | ||
`https://${subdomain}.${domainName}/`, | ||
...(stage === 'nonprod' ? ['http://localhost:3000/']: []) | ||
], | ||
'response_type': 'code' | ||
}, | ||
username_attributes: ['email'], | ||
standard_required_attributes: ['email'], | ||
user_verification_types: ['email'], | ||
unauthenticated_identities_enabled: false, | ||
password_policy: { | ||
min_length: 8, | ||
require_lowercase: true, | ||
require_uppercase: true, | ||
require_numbers: true, | ||
require_symbols: true, | ||
} | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { defineBackend } from '@aws-amplify/backend'; | ||
import { authConfig } from './auth/resource'; | ||
|
||
const backend = defineBackend({}); | ||
backend.addOutput(authConfig); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"type": "module" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "es2022", | ||
"module": "es2022", | ||
"moduleResolution": "bundler", | ||
"resolveJsonModule": true, | ||
"esModuleInterop": true, | ||
"forceConsistentCasingInFileNames": true, | ||
"strict": true, | ||
"skipLibCheck": true, | ||
"paths": { | ||
"$amplify/*": [ | ||
"../.amplify/generated/*" | ||
] | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
'use client'; | ||
|
||
import React from 'react'; | ||
import { Authenticator } from '@aws-amplify/ui-react'; | ||
import '@aws-amplify/ui-react/styles.css'; | ||
import { Col, Container, Footer, Header, Row } from 'nhsuk-react-components'; | ||
|
||
import ConfigureAmplifyClientSide from '../components/ConfigureAmplify'; | ||
import LoginStatus from '../components/LoginStatus'; | ||
|
||
import 'nhsuk-frontend/dist/nhsuk.css'; | ||
import './styles.css'; | ||
|
||
export default function RootLayout({ children }: { children: React.ReactNode }) { | ||
return ( | ||
<html lang="en"> | ||
<body> | ||
<Authenticator.Provider> | ||
<ConfigureAmplifyClientSide /> | ||
<Header serviceName="Notify"> | ||
<Header.Container> | ||
<Header.Logo href="/" /> | ||
<Header.Content> | ||
<LoginStatus /> | ||
</Header.Content> | ||
</Header.Container> | ||
<Header.Nav> | ||
{/*<Header.NavItem href="/conditions">*/} | ||
{/* Health A-Z*/} | ||
{/*</Header.NavItem>*/} | ||
<Header.NavItem home href="/"> | ||
Home | ||
</Header.NavItem> | ||
<Header.NavDropdownMenu /> | ||
</Header.Nav> | ||
</Header> | ||
<Container> | ||
<main className="nhsuk-main-wrapper" id="maincontent" role="main"> | ||
<Row> | ||
<Col width="full"> | ||
{children} | ||
</Col> | ||
</Row> | ||
</main> | ||
</Container> | ||
<Footer> | ||
<Footer.List> | ||
<Footer.ListItem href="https://www.nhs.uk/nhs-sites/"> | ||
NHS sites | ||
</Footer.ListItem> | ||
<Footer.ListItem href="https://www.nhs.uk/about-us/"> | ||
About us | ||
</Footer.ListItem> | ||
<Footer.ListItem href="https://www.nhs.uk/contact-us/"> | ||
Contact us | ||
</Footer.ListItem> | ||
<Footer.ListItem href="https://www.nhs.uk/about-us/sitemap/"> | ||
Sitemap | ||
</Footer.ListItem> | ||
<Footer.ListItem href="https://www.nhs.uk/our-policies/"> | ||
Our policies | ||
</Footer.ListItem> | ||
</Footer.List> | ||
<Footer.Copyright> | ||
© Crown copyright | ||
</Footer.Copyright> | ||
</Footer> | ||
</Authenticator.Provider> | ||
</body> | ||
</html> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
'use client'; | ||
|
||
import React, { useEffect, useState } from 'react'; | ||
import { Hub } from '@aws-amplify/core'; | ||
import Login from '../components/Login'; | ||
|
||
export default function Page({ searchParams }: { | ||
searchParams: { [key: string]: string | string[] | undefined } | ||
}) { | ||
|
||
const [redirect, setRedirect] = useState<string | undefined>(); | ||
|
||
useEffect(() => { | ||
return Hub.listen('auth', ({ payload }) => { | ||
switch (payload.event) { | ||
case 'customOAuthState': | ||
try { | ||
const { redirectPath } = JSON.parse(payload.data); | ||
setRedirect(redirectPath); | ||
} catch (err) { | ||
console.error(err); | ||
setRedirect('Invalid redirect path'); | ||
} | ||
break; | ||
} | ||
}); | ||
}, []); | ||
|
||
let redirectPath = redirect || [searchParams.redirect].flat().pop() || '/'; | ||
if (redirectPath === '/auth') redirectPath = '/'; | ||
if (redirectPath && !redirectPath.match(/^\/[a-z/]*$/)) { | ||
return <h2>Invalid redirect path</h2>; | ||
} | ||
|
||
return <Login redirectPath={redirectPath} /> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import React from 'react'; | ||
import { AuthGetCurrentUserServer } from '../../utils/amplify-utils'; | ||
import Logout from '../../components/Logout'; | ||
import { redirect } from 'next/navigation'; | ||
|
||
export default async function Page() { | ||
|
||
const { currentUser, attributes } = await AuthGetCurrentUserServer() ?? {}; | ||
if (!currentUser) { | ||
redirect('/'); | ||
} | ||
|
||
return <> | ||
<h1>Sign out</h1> | ||
<p>You are currently logged in as <strong>{attributes?.email}</strong></p> | ||
<Logout /> | ||
</> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import React from 'react'; | ||
import { AuthGetCurrentUserServer } from '../../utils/amplify-utils'; | ||
|
||
export default async function Page({ searchParams }: { | ||
searchParams: { [key: string]: string | string[] | undefined } | ||
}) { | ||
|
||
const { currentUser, attributes } = await AuthGetCurrentUserServer() ?? {}; | ||
const redirectPath = [searchParams.redirect].flat().pop() || '/'; | ||
|
||
return <> | ||
<h1>Hello {currentUser?.username}</h1> | ||
<h2>Login details</h2> | ||
<pre>{JSON.stringify(currentUser?.signInDetails, null, ' ')}</pre> | ||
<h2>Attributes</h2> | ||
<pre>{JSON.stringify(attributes, null, ' ')}</pre> | ||
<h2>Redirect details</h2> | ||
<pre>{JSON.stringify({ redirectPath })}</pre> | ||
</> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
.nhsuk-header__content { | ||
flex-grow: 100; | ||
text-align: right; | ||
} | ||
|
||
div.nhsuk-header__content > li.nhsuk-header__navigation-item { | ||
list-style: none; | ||
} | ||
|
||
div.nhsuk-header__content > li.nhsuk-header__navigation-item > a { | ||
padding: 0; | ||
display: inline-block; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
'use client'; | ||
|
||
import { initAmplify } from '../utils/amplify-init'; | ||
|
||
initAmplify(); | ||
|
||
export default function ConfigureAmplifyClientSide() { | ||
return null; | ||
} |
Oops, something went wrong.