Remove auth, add basic lunch runc reation!

This commit is contained in:
2020-05-25 22:16:50 -05:00
parent 223790e22d
commit 8bd5c7e5c3
13 changed files with 140 additions and 563 deletions

View File

@@ -1,5 +1,4 @@
type Todo @model {
type Run @model {
id: ID!
name: String!
description: String
}

View File

@@ -1,367 +0,0 @@
AWSTemplateFormatVersion: 2010-09-09
Parameters:
env:
Type: String
authRoleArn:
Type: String
unauthRoleArn:
Type: String
identityPoolName:
Type: String
allowUnauthenticatedIdentities:
Type: String
resourceNameTruncated:
Type: String
userPoolName:
Type: String
autoVerifiedAttributes:
Type: CommaDelimitedList
mfaConfiguration:
Type: String
mfaTypes:
Type: CommaDelimitedList
smsAuthenticationMessage:
Type: String
smsVerificationMessage:
Type: String
emailVerificationSubject:
Type: String
emailVerificationMessage:
Type: String
defaultPasswordPolicy:
Type: String
passwordPolicyMinLength:
Type: Number
passwordPolicyCharacters:
Type: CommaDelimitedList
requiredAttributes:
Type: CommaDelimitedList
userpoolClientGenerateSecret:
Type: String
userpoolClientRefreshTokenValidity:
Type: Number
userpoolClientWriteAttributes:
Type: CommaDelimitedList
userpoolClientReadAttributes:
Type: CommaDelimitedList
userpoolClientLambdaRole:
Type: String
userpoolClientSetAttributes:
Type: String
sharedId:
Type: String
resourceName:
Type: String
authSelections:
Type: String
useDefault:
Type: String
userPoolGroupList:
Type: CommaDelimitedList
dependsOn:
Type: CommaDelimitedList
Conditions:
ShouldNotCreateEnvResources: !Equals [ !Ref env, NONE ]
Resources:
# BEGIN SNS ROLE RESOURCE
SNSRole:
# Created to allow the UserPool SMS Config to publish via the Simple Notification Service during MFA Process
Type: AWS::IAM::Role
Properties:
RoleName: !If [ShouldNotCreateEnvResources, 'lunchra5e025e4_sns-role', !Join ['',[ 'sns', 'a5e025e4', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]]
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: ""
Effect: "Allow"
Principal:
Service: "cognito-idp.amazonaws.com"
Action:
- "sts:AssumeRole"
Condition:
StringEquals:
sts:ExternalId: lunchra5e025e4_role_external_id
Policies:
-
PolicyName: lunchra5e025e4-sns-policy
PolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: "Allow"
Action:
- "sns:Publish"
Resource: "*"
# BEGIN USER POOL RESOURCES
UserPool:
# Created upon user selection
# Depends on SNS Role for Arn if MFA is enabled
Type: AWS::Cognito::UserPool
UpdateReplacePolicy: Retain
Properties:
UserPoolName: !If [ShouldNotCreateEnvResources, !Ref userPoolName, !Join ['',[!Ref userPoolName, '-', !Ref env]]]
Schema:
-
Name: email
Required: true
Mutable: true
AutoVerifiedAttributes: !Ref autoVerifiedAttributes
EmailVerificationMessage: !Ref emailVerificationMessage
EmailVerificationSubject: !Ref emailVerificationSubject
Policies:
PasswordPolicy:
MinimumLength: !Ref passwordPolicyMinLength
RequireLowercase: false
RequireNumbers: false
RequireSymbols: false
RequireUppercase: false
MfaConfiguration: !Ref mfaConfiguration
SmsVerificationMessage: !Ref smsVerificationMessage
SmsConfiguration:
SnsCallerArn: !GetAtt SNSRole.Arn
ExternalId: lunchra5e025e4_role_external_id
UserPoolClientWeb:
# Created provide application access to user pool
# Depends on UserPool for ID reference
Type: "AWS::Cognito::UserPoolClient"
Properties:
ClientName: lunchra5e025e4_app_clientWeb
RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity
UserPoolId: !Ref UserPool
DependsOn: UserPool
UserPoolClient:
# Created provide application access to user pool
# Depends on UserPool for ID reference
Type: "AWS::Cognito::UserPoolClient"
Properties:
ClientName: lunchra5e025e4_app_client
GenerateSecret: !Ref userpoolClientGenerateSecret
RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity
UserPoolId: !Ref UserPool
DependsOn: UserPool
# BEGIN USER POOL LAMBDA RESOURCES
UserPoolClientRole:
# Created to execute Lambda which gets userpool app client config values
Type: 'AWS::IAM::Role'
Properties:
RoleName: !If [ShouldNotCreateEnvResources, !Ref userpoolClientLambdaRole, !Join ['',['upClientLambdaRole', 'a5e025e4', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]]
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
DependsOn: UserPoolClient
UserPoolClientLambda:
# Lambda which gets userpool app client config values
# Depends on UserPool for id
# Depends on UserPoolClientRole for role ARN
Type: 'AWS::Lambda::Function'
Properties:
Code:
ZipFile: !Join
- |+
- - 'const response = require(''cfn-response'');'
- 'const aws = require(''aws-sdk'');'
- 'const identity = new aws.CognitoIdentityServiceProvider();'
- 'exports.handler = (event, context, callback) => {'
- ' if (event.RequestType == ''Delete'') { '
- ' response.send(event, context, response.SUCCESS, {})'
- ' }'
- ' if (event.RequestType == ''Update'' || event.RequestType == ''Create'') {'
- ' const params = {'
- ' ClientId: event.ResourceProperties.clientId,'
- ' UserPoolId: event.ResourceProperties.userpoolId'
- ' };'
- ' identity.describeUserPoolClient(params).promise()'
- ' .then((res) => {'
- ' response.send(event, context, response.SUCCESS, {''appSecret'': res.UserPoolClient.ClientSecret});'
- ' })'
- ' .catch((err) => {'
- ' response.send(event, context, response.FAILED, {err});'
- ' });'
- ' }'
- '};'
Handler: index.handler
Runtime: nodejs10.x
Timeout: '300'
Role: !GetAtt
- UserPoolClientRole
- Arn
DependsOn: UserPoolClientRole
UserPoolClientLambdaPolicy:
# Sets userpool policy for the role that executes the Userpool Client Lambda
# Depends on UserPool for Arn
# Marked as depending on UserPoolClientRole for easier to understand CFN sequencing
Type: 'AWS::IAM::Policy'
Properties:
PolicyName: lunchra5e025e4_userpoolclient_lambda_iam_policy
Roles:
- !Ref UserPoolClientRole
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- 'cognito-idp:DescribeUserPoolClient'
Resource: !GetAtt UserPool.Arn
DependsOn: UserPoolClientLambda
UserPoolClientLogPolicy:
# Sets log policy for the role that executes the Userpool Client Lambda
# Depends on UserPool for Arn
# Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing
Type: 'AWS::IAM::Policy'
Properties:
PolicyName: lunchra5e025e4_userpoolclient_lambda_log_policy
Roles:
- !Ref UserPoolClientRole
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
Resource: !Sub
- arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:*
- { region: !Ref "AWS::Region", account: !Ref "AWS::AccountId", lambda: !Ref UserPoolClientLambda}
DependsOn: UserPoolClientLambdaPolicy
UserPoolClientInputs:
# Values passed to Userpool client Lambda
# Depends on UserPool for Id
# Depends on UserPoolClient for Id
# Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing
Type: 'Custom::LambdaCallout'
Properties:
ServiceToken: !GetAtt UserPoolClientLambda.Arn
clientId: !Ref UserPoolClient
userpoolId: !Ref UserPool
DependsOn: UserPoolClientLogPolicy
# BEGIN IDENTITY POOL RESOURCES
IdentityPool:
# Always created
Type: AWS::Cognito::IdentityPool
Properties:
IdentityPoolName: !If [ShouldNotCreateEnvResources, 'lunchruna5e025e4_identitypool_a5e025e4', !Join ['',['lunchruna5e025e4_identitypool_a5e025e4', '__', !Ref env]]]
CognitoIdentityProviders:
- ClientId: !Ref UserPoolClient
ProviderName: !Sub
- cognito-idp.${region}.amazonaws.com/${client}
- { region: !Ref "AWS::Region", client: !Ref UserPool}
- ClientId: !Ref UserPoolClientWeb
ProviderName: !Sub
- cognito-idp.${region}.amazonaws.com/${client}
- { region: !Ref "AWS::Region", client: !Ref UserPool}
AllowUnauthenticatedIdentities: !Ref allowUnauthenticatedIdentities
DependsOn: UserPoolClientInputs
IdentityPoolRoleMap:
# Created to map Auth and Unauth roles to the identity pool
# Depends on Identity Pool for ID ref
Type: AWS::Cognito::IdentityPoolRoleAttachment
Properties:
IdentityPoolId: !Ref IdentityPool
Roles:
unauthenticated: !Ref unauthRoleArn
authenticated: !Ref authRoleArn
DependsOn: IdentityPool
Outputs :
IdentityPoolId:
Value: !Ref 'IdentityPool'
Description: Id for the identity pool
IdentityPoolName:
Value: !GetAtt IdentityPool.Name
UserPoolId:
Value: !Ref 'UserPool'
Description: Id for the user pool
UserPoolName:
Value: !Ref userPoolName
AppClientIDWeb:
Value: !Ref 'UserPoolClientWeb'
Description: The user pool app client id for web
AppClientID:
Value: !Ref 'UserPoolClient'
Description: The user pool app client id
AppClientSecret:
Value: !GetAtt UserPoolClientInputs.appSecret

View File

@@ -1,51 +0,0 @@
{
"identityPoolName": "lunchruna5e025e4_identitypool_a5e025e4",
"allowUnauthenticatedIdentities": false,
"resourceNameTruncated": "lunchra5e025e4",
"userPoolName": "lunchruna5e025e4_userpool_a5e025e4",
"autoVerifiedAttributes": [
"email"
],
"mfaConfiguration": "OFF",
"mfaTypes": [
"SMS Text Message"
],
"smsAuthenticationMessage": "Your authentication code is {####}",
"smsVerificationMessage": "Your verification code is {####}",
"emailVerificationSubject": "Your verification code",
"emailVerificationMessage": "Your verification code is {####}",
"defaultPasswordPolicy": false,
"passwordPolicyMinLength": 8,
"passwordPolicyCharacters": [],
"requiredAttributes": [
"email"
],
"userpoolClientGenerateSecret": true,
"userpoolClientRefreshTokenValidity": 30,
"userpoolClientWriteAttributes": [
"email"
],
"userpoolClientReadAttributes": [
"email"
],
"userpoolClientLambdaRole": "lunchra5e025e4_userpoolclient_lambda_role",
"userpoolClientSetAttributes": false,
"sharedId": "a5e025e4",
"resourceName": "lunchruna5e025e4",
"authSelections": "identityPoolAndUserPool",
"authRoleArn": {
"Fn::GetAtt": [
"AuthRole",
"Arn"
]
},
"unauthRoleArn": {
"Fn::GetAtt": [
"UnauthRole",
"Arn"
]
},
"useDefault": "default",
"userPoolGroupList": [],
"dependsOn": []
}

View File

@@ -1,35 +1,28 @@
{
"api": {
"lunchrun": {
"service": "AppSync",
"providerPlugin": "awscloudformation",
"output": {
"authConfig": {
"additionalAuthenticationProviders": [],
"defaultAuthentication": {
"authenticationType": "API_KEY",
"apiKeyConfig": {
"description": "lunchrunapikey",
"apiKeyExpirationDays": 7
}
}
}
}
}
},
"auth": {
"lunchruna5e025e4": {
"service": "Cognito",
"providerPlugin": "awscloudformation",
"dependsOn": [],
"customAuth": false
}
},
"hosting": {
"amplifyhosting": {
"service": "amplifyhosting",
"providerPlugin": "awscloudformation",
"type": "manual"
}
}
"api": {
"lunchrun": {
"service": "AppSync",
"providerPlugin": "awscloudformation",
"output": {
"authConfig": {
"additionalAuthenticationProviders": [],
"defaultAuthentication": {
"authenticationType": "API_KEY",
"apiKeyConfig": {
"description": "lunchrunapikey",
"apiKeyExpirationDays": 7
}
}
}
}
}
},
"auth": {},
"hosting": {
"amplifyhosting": {
"service": "amplifyhosting",
"providerPlugin": "awscloudformation",
"type": "manual"
}
}
}

View File

@@ -12,9 +12,6 @@
"AmplifyAppId": "d69tbu39wvryc"
},
"categories": {
"auth": {
"lunchruna5e025e4": {}
},
"hosting": {
"amplifyhosting": {
"appId": "d69tbu39wvryc",

View File

@@ -24,7 +24,7 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
<title>Lunch Run!</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>

View File

@@ -1,6 +1,6 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"short_name": "Lunch Run!",
"name": "Create group lunch runs!",
"icons": [
{
"src": "favicon.ico",

View File

@@ -1,38 +0,0 @@
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

View File

@@ -1,79 +1,40 @@
/* src/App.js */
import React, { useEffect, useState } from 'react'
import React, { useState } from 'react'
import { API, graphqlOperation } from 'aws-amplify'
import { createTodo } from './graphql/mutations'
import { listTodos } from './graphql/queries'
import { withAuthenticator } from '@aws-amplify/ui-react'
import { createRun } from './graphql/mutations'
const initialState = { name: '', description: '' }
const initialState = { name: '' }
const App = () => {
const [formState, setFormState] = useState(initialState)
const [todos, setTodos] = useState([])
useEffect(() => {
fetchTodos()
}, [])
function setInput(key, value) {
setFormState({ ...formState, [key]: value })
}
async function fetchTodos() {
async function addRun() {
try {
const todoData = await API.graphql(graphqlOperation(listTodos))
const todos = todoData.data.listTodos.items
setTodos(todos)
} catch (err) { console.log('error fetching todos') }
}
async function addTodo() {
try {
if (!formState.name || !formState.description) return
const todo = { ...formState }
setTodos([...todos, todo])
if (!formState.name) return;
const run = { ...formState }
setFormState(initialState)
await API.graphql(graphqlOperation(createTodo, {input: todo}))
} catch (err) {
await API.graphql(graphqlOperation(createRun, { input: run }))
}
catch (err) {
console.log('error creating todo:', err)
}
}
return (
<div style={styles.container}>
<h2>Amplify Todos</h2>
<div>
<h2>Start a run</h2>
<input
onChange={event => setInput('name', event.target.value)}
style={styles.input}
value={formState.name}
value={formState.name}
placeholder="Name"
/>
<input
onChange={event => setInput('description', event.target.value)}
style={styles.input}
value={formState.description}
placeholder="Description"
/>
<button style={styles.button} onClick={addTodo}>Create Todo</button>
{
todos.map((todo, index) => (
<div key={todo.id ? todo.id : index} style={styles.todo}>
<p style={styles.todoName}>{todo.name}</p>
<p style={styles.todoDescription}>{todo.description}</p>
</div>
))
}
<button onClick={addRun}>Run!</button>
</div>
)
}
const styles = {
container: { width: 400, margin: '0 auto', display: 'flex', flex: 1, flexDirection: 'column', justifyContent: 'center', padding: 20 },
todo: { marginBottom: 15 },
input: { border: 'none', backgroundColor: '#ddd', marginBottom: 10, padding: 8, fontSize: 18 },
todoName: { fontSize: 20, fontWeight: 'bold' },
todoDescription: { marginBottom: 0 },
button: { backgroundColor: 'black', color: 'white', outline: 'none', fontSize: 18, padding: '12px 0px' }
}
export default withAuthenticator(App)
export default App;

View File

@@ -43,3 +43,42 @@ export const deleteTodo = /* GraphQL */ `
}
}
`;
export const createRun = /* GraphQL */ `
mutation CreateRun(
$input: CreateRunInput!
$condition: ModelRunConditionInput
) {
createRun(input: $input, condition: $condition) {
id
name
createdAt
updatedAt
}
}
`;
export const updateRun = /* GraphQL */ `
mutation UpdateRun(
$input: UpdateRunInput!
$condition: ModelRunConditionInput
) {
updateRun(input: $input, condition: $condition) {
id
name
createdAt
updatedAt
}
}
`;
export const deleteRun = /* GraphQL */ `
mutation DeleteRun(
$input: DeleteRunInput!
$condition: ModelRunConditionInput
) {
deleteRun(input: $input, condition: $condition) {
id
name
createdAt
updatedAt
}
}
`;

View File

@@ -30,3 +30,30 @@ export const listTodos = /* GraphQL */ `
}
}
`;
export const getRun = /* GraphQL */ `
query GetRun($id: ID!) {
getRun(id: $id) {
id
name
createdAt
updatedAt
}
}
`;
export const listRuns = /* GraphQL */ `
query ListRuns(
$filter: ModelRunFilterInput
$limit: Int
$nextToken: String
) {
listRuns(filter: $filter, limit: $limit, nextToken: $nextToken) {
items {
id
name
createdAt
updatedAt
}
nextToken
}
}
`;

View File

@@ -34,3 +34,33 @@ export const onDeleteTodo = /* GraphQL */ `
}
}
`;
export const onCreateRun = /* GraphQL */ `
subscription OnCreateRun {
onCreateRun {
id
name
createdAt
updatedAt
}
}
`;
export const onUpdateRun = /* GraphQL */ `
subscription OnUpdateRun {
onUpdateRun {
id
name
createdAt
updatedAt
}
}
`;
export const onDeleteRun = /* GraphQL */ `
subscription OnDeleteRun {
onDeleteRun {
id
name
createdAt
updatedAt
}
}
`;

View File

@@ -1,13 +0,0 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}