├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── congressional-updates.yml │ ├── greetings.yml │ ├── netlify-deploy.yml │ ├── netlify-push-to-pr.yml │ └── web-app.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── _config.yml ├── congressional-updates └── congressional-scraper │ ├── .gitignore │ ├── Congress.js │ ├── WisconsinLegis.js │ ├── handler.js │ ├── package-lock.json │ ├── readme.md │ └── serverless.yml ├── docs ├── _config.yml └── index.md └── web-app ├── .gitignore ├── .graphqlconfig.yml ├── README.md ├── amplify ├── .config │ └── project-config.json ├── backend │ ├── api │ │ └── serviceproviders │ │ │ ├── parameters.json │ │ │ ├── schema.graphql │ │ │ ├── stacks │ │ │ └── CustomResources.json │ │ │ └── transform.conf.json │ ├── auth │ │ └── webappe28ff9ce │ │ │ ├── parameters.json │ │ │ └── webappe28ff9ce-cloudformation-template.yml │ ├── backend-config.json │ └── function │ │ ├── webappe28ff9ceCreateAuthChallenge │ │ ├── amplify.state │ │ ├── function-parameters.json │ │ ├── parameters.json │ │ ├── src │ │ │ ├── captcha-create-challenge.js │ │ │ ├── event.json │ │ │ ├── index.js │ │ │ ├── package-lock.json │ │ │ └── package.json │ │ └── webappe28ff9ceCreateAuthChallenge-cloudformation-template.json │ │ ├── webappe28ff9ceDefineAuthChallenge │ │ ├── amplify.state │ │ ├── function-parameters.json │ │ ├── parameters.json │ │ ├── src │ │ │ ├── captcha-define-challenge.js │ │ │ ├── event.json │ │ │ ├── index.js │ │ │ ├── package-lock.json │ │ │ └── package.json │ │ └── webappe28ff9ceDefineAuthChallenge-cloudformation-template.json │ │ └── webappe28ff9ceVerifyAuthChallengeResponse │ │ ├── amplify.state │ │ ├── function-parameters.json │ │ ├── parameters.json │ │ ├── src │ │ ├── captcha-verify.js │ │ ├── event.json │ │ ├── index.js │ │ ├── package-lock.json │ │ └── package.json │ │ └── webappe28ff9ceVerifyAuthChallengeResponse-cloudformation-template.json └── team-provider-info.json ├── package-lock.json ├── package.json ├── public ├── _redirects ├── favicon.ico ├── favicon_temp.ico ├── images │ ├── b.png │ ├── bg-main.jpg │ ├── c.png │ ├── d.png │ ├── help.png │ ├── informed.png │ └── organised.png ├── index.html ├── logo192.png ├── logo512.png ├── manifest.json └── robots.txt └── src ├── assets ├── STAKEHOLDER_JSON.json ├── commandToRun.sh ├── normalizeAWSJSON.py ├── sh0.json ├── sh1-20.json ├── sh101-114.json ├── sh21-40.json ├── sh41-60.json ├── sh61-80.json ├── sh81-100.json ├── shFULL.json └── shFULLNormalized.json ├── components ├── AboutPage │ └── index.js ├── Account │ └── index.js ├── App │ └── index.js ├── CalendarPage │ ├── ExistingCalendarEntryModal.js │ ├── NewCalendarEntryModal.js │ ├── calendarUtilities.js │ └── index.js ├── Common │ └── Address.js ├── Footer │ ├── Footer.css │ └── index.js ├── LandingPage │ ├── LandingPage.css │ └── index.js ├── Navigation │ ├── index.js │ └── navigation.css ├── PrivacyPolicyPage │ └── index.js ├── ServicesPage │ ├── Service.js │ └── index.js ├── SignInPage │ └── index.js ├── SignUpPage │ └── index.js ├── SupportCircles │ └── index.js └── TermsAndConditionsPage │ └── index.js ├── config.js ├── constants ├── navlinks.js ├── routes.js └── services.js ├── graphql ├── mutations.js ├── queries.js ├── schema.json └── subscriptions.js ├── hooks └── useInput.js ├── index.css ├── index.js ├── replace.pl └── serviceWorker.js /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] - none yet 4 | patreon: PaulRinaldi 5 | open_collective: paul-rinaldi 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: paul-rinaldi 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/congressional-updates.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Congressional Scraper Node.js CI 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | paths: 10 | - 'congressional-updates/**' 11 | pull_request: 12 | branches: [ master ] 13 | paths: 14 | - 'congressional-updates/**' 15 | 16 | jobs: 17 | build: 18 | 19 | runs-on: ubuntu-latest 20 | 21 | strategy: 22 | matrix: 23 | node-version: [10.x, 12.x] 24 | 25 | steps: 26 | - uses: actions/checkout@v2 27 | - name: Use Node.js ${{ matrix.node-version }} 28 | uses: actions/setup-node@v1 29 | with: 30 | node-version: ${{ matrix.node-version }} 31 | - run: npm ci 32 | working-directory: congressional-updates/congressional-scraper 33 | - run: npm run build --if-present 34 | working-directory: congressional-updates/congressional-scraper 35 | - run: npm test 36 | working-directory: congressional-updates/congressional-scraper 37 | -------------------------------------------------------------------------------- /.github/workflows/greetings.yml: -------------------------------------------------------------------------------- 1 | name: Greetings 2 | 3 | on: [pull_request, issues] 4 | 5 | jobs: 6 | greeting: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/first-interaction@v1 10 | with: 11 | repo-token: ${{ secrets.GITHUB_TOKEN }} 12 | issue-message: 'Welcome! Thank you for your help in solving mass incarceration problems!'' first issue' 13 | pr-message: 'Your first PR, fantastic! Contributors will review it soon (~0-2 business days)!'' first pr' 14 | -------------------------------------------------------------------------------- /.github/workflows/netlify-deploy.yml: -------------------------------------------------------------------------------- 1 | name: Netlify CI/CD 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - opened 7 | - synchronize 8 | paths: 9 | - "web-app/**" 10 | release: 11 | types: 12 | - created 13 | paths: 14 | - "web-app/**" 15 | push: 16 | branches: [master, dev] 17 | paths: 18 | - "web-app/**" 19 | 20 | jobs: 21 | # This job will: 22 | # * deploy a production build every time there is a release created on the master branch 23 | # * comment that commit with the deploy URL 24 | publishOnMasterRelease: 25 | name: Publish Release to Netlify 26 | runs-on: ubuntu-latest 27 | if: github.event_name == 'release' && github.event.action == 'created' 28 | steps: 29 | - name: Checkout repository 30 | uses: actions/checkout@v1 31 | 32 | - name: Replace Secrets 33 | env: 34 | CI: false 35 | AWS_APP_ID: ${{ secrets.AWS_APP_ID }} 36 | AWS_BACKEND_ENV_NAME: ${{ secrets.AWS_BACKEND_ENV_NAME }} 37 | FIREBASE_API_KEY: ${{ secrets.FIREBASE_API_KEY }} 38 | FIREBASE_APP_ID: ${{ secrets.FIREBASE_APP_ID }} 39 | FIREBASE_AUTH_DOMAIN: ${{ secrets.FIREBASE_AUTH_DOMAIN }} 40 | FIREBASE_DB_URL: ${{ secrets.FIREBASE_DB_URL }} 41 | FIREBASE_MESSAGING_SENDER_ID: ${{ secrets.FIREBASE_MESSAGING_SENDER_ID }} 42 | FIREBASE_PROJECT_ID: ${{ secrets.FIREBASE_PROJECT_ID }} 43 | FIREBASE_STORAGE_BUCKET: ${{ secrets.FIREBASE_STORAGE_BUCKET }} 44 | MEASUREMENT_ID: ${{ secrets.MEASUREMENT_ID }} 45 | REACT_APP_GOOGLE_MAPS_API_KEY: ${{ secrets.REACT_APP_GOOGLE_MAPS_API_KEY }} 46 | REACT_APP_GOOGLE_GEOCODING: ${{ secrets.REACT_APP_GOOGLE_GEOCODING }} 47 | #AWSCLOUDFORMATIONCONFIG: "{\"configLevel\":\"project\",\"useProfile\":true,\"profileName\":\"default\"}" 48 | #NOTIFICATIONSCONFIG: "{\"Pinpoint\":{\"SMS\":{\"Enabled\":true},\"Email\":{\"Enabled\":true,\"FromAddress\":\"xxx@amzon.com\",\"Identity\":\"identityArn\",\"RoleArn\":\"roleArn\"}, \"APNS\":{\"Enabled\":true,\"DefaultAuthenticationMethod\":\"Certificate\",\"P12FilePath\":\"p12filePath\",\"Password\":\"p12FilePasswordIfAny\"},\"FCM\":{\"Enabled\":true,\"ApiKey\":\"fcmapikey\"}}}" 49 | #AMPLIFY: "{\"appId\":\"$AWS_APP_ID\", \"envName\":\"$AWS_BACKEND_ENV_NAME\"}" 50 | #PROVIDERS: "{\"awscloudformation\":$AWSCLOUDFORMATIONCONFIG}" 51 | #CATEGORIES: "{\"notifications\":$NOTIFICATIONSCONFIG}" 52 | run: | 53 | echo 54 | sed -Ei "s,FIREBASE_APP_ID,${FIREBASE_APP_ID}," web-app/src/config.js 55 | sed -Ei "s,FIREBASE_API_KEY,${FIREBASE_API_KEY}," web-app/src/config.js 56 | sed -Ei "s,FIREBASE_AUTH_DOMAIN,${FIREBASE_AUTH_DOMAIN}," web-app/src/config.js 57 | sed -Ei "s,FIREBASE_DB_URL,${FIREBASE_DB_URL}," web-app/src/config.js 58 | sed -Ei "s,FIREBASE_MESSAGING_SENDER_ID,${FIREBASE_MESSAGING_SENDER_ID}," web-app/src/config.js 59 | sed -Ei "s,FIREBASE_PROJECT_ID,${FIREBASE_PROJECT_ID}," web-app/src/config.js 60 | sed -Ei "s,FIREBASE_STORAGE_BUCKET,${FIREBASE_STORAGE_BUCKET}," web-app/src/config.js 61 | sed -Ei "s,MEASUREMENT_ID,${MEASUREMENT_ID}," web-app/src/config.js 62 | sed -Ei "s,REACT_APP_GOOGLE_MAPS_API_KEY,${REACT_APP_GOOGLE_MAPS_API_KEY}," web-app/src/config.js 63 | sed -Ei "s,REACT_APP_GOOGLE_GEOCODING,${REACT_APP_GOOGLE_GEOCODING}," web-app/src/config.js 64 | 65 | - name: Deploy production to Netlify 66 | uses: South-Paw/action-netlify-deploy@v1.0.4 67 | with: 68 | github-token: ${{ secrets.GITHUB_TOKEN }} 69 | netlify-auth-token: ${{ secrets.NETLIFY_AUTH_TOKEN }} 70 | netlify-site-id: ${{ secrets.NETLIFY_SITE_ID }} 71 | build-dir: './build' 72 | 73 | # This job will: 74 | # * deploy a production build every time there is a push created on the master branch 75 | # * comment that commit with the deploy URL 76 | publishOnMasterPush: 77 | name: Publish Production to Netlify 78 | runs-on: ubuntu-latest 79 | if: github.event_name == 'push' && github.ref == 'refs/heads/master' 80 | steps: 81 | - name: Checkout repository 82 | uses: actions/checkout@v1 83 | 84 | - name: Replace Secrets 85 | env: 86 | CI: false 87 | AWS_APP_ID: ${{ secrets.AWS_APP_ID }} 88 | AWS_BACKEND_ENV_NAME: ${{ secrets.AWS_BACKEND_ENV_NAME }} 89 | FIREBASE_API_KEY: ${{ secrets.FIREBASE_API_KEY }} 90 | FIREBASE_APP_ID: ${{ secrets.FIREBASE_APP_ID }} 91 | FIREBASE_AUTH_DOMAIN: ${{ secrets.FIREBASE_AUTH_DOMAIN }} 92 | FIREBASE_DB_URL: ${{ secrets.FIREBASE_DB_URL }} 93 | FIREBASE_MESSAGING_SENDER_ID: ${{ secrets.FIREBASE_MESSAGING_SENDER_ID }} 94 | FIREBASE_PROJECT_ID: ${{ secrets.FIREBASE_PROJECT_ID }} 95 | FIREBASE_STORAGE_BUCKET: ${{ secrets.FIREBASE_STORAGE_BUCKET }} 96 | MEASUREMENT_ID: ${{ secrets.MEASUREMENT_ID }} 97 | REACT_APP_GOOGLE_MAPS_API_KEY: ${{ secrets.REACT_APP_GOOGLE_MAPS_API_KEY }} 98 | REACT_APP_GOOGLE_GEOCODING: ${{ secrets.REACT_APP_GOOGLE_GEOCODING }} 99 | #AWSCLOUDFORMATIONCONFIG: "{\"configLevel\":\"project\",\"useProfile\":true,\"profileName\":\"default\"}" 100 | #NOTIFICATIONSCONFIG: "{\"Pinpoint\":{\"SMS\":{\"Enabled\":true},\"Email\":{\"Enabled\":true,\"FromAddress\":\"xxx@amzon.com\",\"Identity\":\"identityArn\",\"RoleArn\":\"roleArn\"}, \"APNS\":{\"Enabled\":true,\"DefaultAuthenticationMethod\":\"Certificate\",\"P12FilePath\":\"p12filePath\",\"Password\":\"p12FilePasswordIfAny\"},\"FCM\":{\"Enabled\":true,\"ApiKey\":\"fcmapikey\"}}}" 101 | #AMPLIFY: "{\"appId\":\"$AWS_APP_ID\", \"envName\":\"$AWS_BACKEND_ENV_NAME\"}" 102 | #PROVIDERS: "{\"awscloudformation\":$AWSCLOUDFORMATIONCONFIG}" 103 | #CATEGORIES: "{\"notifications\":$NOTIFICATIONSCONFIG}" 104 | run: | 105 | echo 106 | sed -Ei "s,FIREBASE_APP_ID,${FIREBASE_APP_ID}," web-app/src/config.js 107 | sed -Ei "s,FIREBASE_API_KEY,${FIREBASE_API_KEY}," web-app/src/config.js 108 | sed -Ei "s,FIREBASE_AUTH_DOMAIN,${FIREBASE_AUTH_DOMAIN}," web-app/src/config.js 109 | sed -Ei "s,FIREBASE_DB_URL,${FIREBASE_DB_URL}," web-app/src/config.js 110 | sed -Ei "s,FIREBASE_MESSAGING_SENDER_ID,${FIREBASE_MESSAGING_SENDER_ID}," web-app/src/config.js 111 | sed -Ei "s,FIREBASE_PROJECT_ID,${FIREBASE_PROJECT_ID}," web-app/src/config.js 112 | sed -Ei "s,FIREBASE_STORAGE_BUCKET,${FIREBASE_STORAGE_BUCKET}," web-app/src/config.js 113 | sed -Ei "s,MEASUREMENT_ID,${MEASUREMENT_ID}," web-app/src/config.js 114 | sed -Ei "s,REACT_APP_GOOGLE_MAPS_API_KEY,${REACT_APP_GOOGLE_MAPS_API_KEY}," web-app/src/config.js 115 | sed -Ei "s,REACT_APP_GOOGLE_GEOCODING,${REACT_APP_GOOGLE_GEOCODING}," web-app/src/config.js 116 | 117 | - name: Deploy production to Netlify 118 | uses: South-Paw/action-netlify-deploy@v1.0.4 119 | with: 120 | github-token: ${{ secrets.GITHUB_TOKEN }} 121 | netlify-auth-token: ${{ secrets.NETLIFY_AUTH_TOKEN }} 122 | netlify-site-id: ${{ secrets.NETLIFY_SITE_ID }} 123 | build-dir: './build' 124 | -------------------------------------------------------------------------------- /.github/workflows/netlify-push-to-pr.yml: -------------------------------------------------------------------------------- 1 | name: Netlify CI/CD for PRs 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | paths: 7 | - "web-app/**" 8 | pull_request: 9 | branches: [master] 10 | paths: 11 | - "web-app/**" 12 | 13 | jobs: 14 | # This job will: 15 | # * deploy a draft every time there is a pull request created or pushed to that is on the master or dev branch 16 | # * comment on that pull request with the deploy URL 17 | deployPRDraft: 18 | name: Deploy draft PR to Netlify 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: Checkout repository 22 | uses: actions/checkout@v1 23 | 24 | - name: Replace Secrets 25 | env: 26 | CI: false 27 | AWS_APP_ID: ${{ secrets.AWS_APP_ID }} 28 | AWS_BACKEND_ENV_NAME: ${{ secrets.AWS_BACKEND_ENV_NAME }} 29 | FIREBASE_API_KEY: ${{ secrets.FIREBASE_API_KEY }} 30 | FIREBASE_APP_ID: ${{ secrets.FIREBASE_APP_ID }} 31 | FIREBASE_AUTH_DOMAIN: ${{ secrets.FIREBASE_AUTH_DOMAIN }} 32 | FIREBASE_DB_URL: ${{ secrets.FIREBASE_DB_URL }} 33 | FIREBASE_MESSAGING_SENDER_ID: ${{ secrets.FIREBASE_MESSAGING_SENDER_ID }} 34 | FIREBASE_PROJECT_ID: ${{ secrets.FIREBASE_PROJECT_ID }} 35 | FIREBASE_STORAGE_BUCKET: ${{ secrets.FIREBASE_STORAGE_BUCKET }} 36 | MEASUREMENT_ID: ${{ secrets.MEASUREMENT_ID }} 37 | REACT_APP_GOOGLE_MAPS_API_KEY: ${{ secrets.REACT_APP_GOOGLE_MAPS_API_KEY }} 38 | REACT_APP_GOOGLE_GEOCODING: ${{ secrets.REACT_APP_GOOGLE_GEOCODING }} 39 | #AWSCLOUDFORMATIONCONFIG: "{\"configLevel\":\"project\",\"useProfile\":true,\"profileName\":\"default\"}" 40 | #NOTIFICATIONSCONFIG: "{\"Pinpoint\":{\"SMS\":{\"Enabled\":true},\"Email\":{\"Enabled\":true,\"FromAddress\":\"xxx@amzon.com\",\"Identity\":\"identityArn\",\"RoleArn\":\"roleArn\"}, \"APNS\":{\"Enabled\":true,\"DefaultAuthenticationMethod\":\"Certificate\",\"P12FilePath\":\"p12filePath\",\"Password\":\"p12FilePasswordIfAny\"},\"FCM\":{\"Enabled\":true,\"ApiKey\":\"fcmapikey\"}}}" 41 | #AMPLIFY: "{\"appId\":\"$AWS_APP_ID\", \"envName\":\"$AWS_BACKEND_ENV_NAME\"}" 42 | #PROVIDERS: "{\"awscloudformation\":$AWSCLOUDFORMATIONCONFIG}" 43 | #CATEGORIES: "{\"notifications\":$NOTIFICATIONSCONFIG}" 44 | run: | 45 | echo 46 | sed -Ei "s,FIREBASE_APP_ID,${FIREBASE_APP_ID}," web-app/src/config.js 47 | sed -Ei "s,FIREBASE_API_KEY,${FIREBASE_API_KEY}," web-app/src/config.js 48 | sed -Ei "s,FIREBASE_AUTH_DOMAIN,${FIREBASE_AUTH_DOMAIN}," web-app/src/config.js 49 | sed -Ei "s,FIREBASE_DB_URL,${FIREBASE_DB_URL}," web-app/src/config.js 50 | sed -Ei "s,FIREBASE_MESSAGING_SENDER_ID,${FIREBASE_MESSAGING_SENDER_ID}," web-app/src/config.js 51 | sed -Ei "s,FIREBASE_PROJECT_ID,${FIREBASE_PROJECT_ID}," web-app/src/config.js 52 | sed -Ei "s,FIREBASE_STORAGE_BUCKET,${FIREBASE_STORAGE_BUCKET}," web-app/src/config.js 53 | sed -Ei "s,MEASUREMENT_ID,${MEASUREMENT_ID}," web-app/src/config.js 54 | sed -Ei "s,REACT_APP_GOOGLE_MAPS_API_KEY,${REACT_APP_GOOGLE_MAPS_API_KEY}," web-app/src/config.js 55 | sed -Ei "s,REACT_APP_GOOGLE_GEOCODING,${REACT_APP_GOOGLE_GEOCODING}," web-app/src/config.js 56 | 57 | - name: Build 58 | run: | 59 | cd web-app 60 | npm install 61 | npm test 62 | CI=false npm run build 63 | ls 64 | 65 | - name: Deploy draft to Netlify 66 | uses: South-Paw/action-netlify-deploy@v1.0.4 67 | with: 68 | github-token: ${{ secrets.GITHUB_TOKEN }} 69 | netlify-auth-token: ${{ secrets.NETLIFY_AUTH_TOKEN }} 70 | netlify-site-id: ${{ secrets.NETLIFY_SITE_ID }} 71 | build-dir: 'web-app/build' 72 | draft: true 73 | comment-on-pull-request: true -------------------------------------------------------------------------------- /.github/workflows/web-app.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Amplify Web App CI/CD 5 | 6 | on: 7 | push: 8 | branches: [master] 9 | paths: 10 | - "web-app/**" 11 | pull_request: 12 | branches: [master] 13 | paths: 14 | - "web-app/**" 15 | 16 | jobs: 17 | build: 18 | runs-on: ubuntu-latest 19 | 20 | strategy: 21 | matrix: 22 | node-version: [14.x] # 10.x, 12.x, 23 | 24 | steps: 25 | - uses: actions/checkout@v2 26 | 27 | - name: use node.js ${{ matrix.node-version }} 28 | uses: actions/setup-node@v1 29 | with: 30 | node-version: ${{ matrix.node-version }} 31 | 32 | - name: Replace Secrets 33 | env: 34 | CI: false 35 | AWS_APP_ID: ${{ secrets.AWS_APP_ID }} 36 | AWS_BACKEND_ENV_NAME: ${{ secrets.AWS_BACKEND_ENV_NAME }} 37 | FIREBASE_API_KEY: ${{ secrets.FIREBASE_API_KEY }} 38 | FIREBASE_APP_ID: ${{ secrets.FIREBASE_APP_ID }} 39 | FIREBASE_AUTH_DOMAIN: ${{ secrets.FIREBASE_AUTH_DOMAIN }} 40 | FIREBASE_DB_URL: ${{ secrets.FIREBASE_DB_URL }} 41 | FIREBASE_MESSAGING_SENDER_ID: ${{ secrets.FIREBASE_MESSAGING_SENDER_ID }} 42 | FIREBASE_PROJECT_ID: ${{ secrets.FIREBASE_PROJECT_ID }} 43 | FIREBASE_STORAGE_BUCKET: ${{ secrets.FIREBASE_STORAGE_BUCKET }} 44 | MEASUREMENT_ID: ${{ secrets.MEASUREMENT_ID }} 45 | REACT_APP_GOOGLE_MAPS_API_KEY: ${{ secrets.REACT_APP_GOOGLE_MAPS_API_KEY }} 46 | REACT_APP_GOOGLE_GEOCODING: ${{ secrets.REACT_APP_GOOGLE_GEOCODING }} 47 | #AWSCLOUDFORMATIONCONFIG: "{\"configLevel\":\"project\",\"useProfile\":true,\"profileName\":\"default\"}" 48 | #NOTIFICATIONSCONFIG: "{\"Pinpoint\":{\"SMS\":{\"Enabled\":true},\"Email\":{\"Enabled\":true,\"FromAddress\":\"xxx@amzon.com\",\"Identity\":\"identityArn\",\"RoleArn\":\"roleArn\"}, \"APNS\":{\"Enabled\":true,\"DefaultAuthenticationMethod\":\"Certificate\",\"P12FilePath\":\"p12filePath\",\"Password\":\"p12FilePasswordIfAny\"},\"FCM\":{\"Enabled\":true,\"ApiKey\":\"fcmapikey\"}}}" 49 | #AMPLIFY: "{\"appId\":\"$AWS_APP_ID\", \"envName\":\"$AWS_BACKEND_ENV_NAME\"}" 50 | #PROVIDERS: "{\"awscloudformation\":$AWSCLOUDFORMATIONCONFIG}" 51 | #CATEGORIES: "{\"notifications\":$NOTIFICATIONSCONFIG}" 52 | run: | 53 | echo 54 | sed -Ei "s,FIREBASE_APP_ID,${FIREBASE_APP_ID}," web-app/src/config.js 55 | sed -Ei "s,FIREBASE_API_KEY,${FIREBASE_API_KEY}," web-app/src/config.js 56 | sed -Ei "s,FIREBASE_AUTH_DOMAIN,${FIREBASE_AUTH_DOMAIN}," web-app/src/config.js 57 | sed -Ei "s,FIREBASE_DB_URL,${FIREBASE_DB_URL}," web-app/src/config.js 58 | sed -Ei "s,FIREBASE_MESSAGING_SENDER_ID,${FIREBASE_MESSAGING_SENDER_ID}," web-app/src/config.js 59 | sed -Ei "s,FIREBASE_PROJECT_ID,${FIREBASE_PROJECT_ID}," web-app/src/config.js 60 | sed -Ei "s,FIREBASE_STORAGE_BUCKET,${FIREBASE_STORAGE_BUCKET}," web-app/src/config.js 61 | sed -Ei "s,MEASUREMENT_ID,${MEASUREMENT_ID}," web-app/src/config.js 62 | sed -Ei "s,REACT_APP_GOOGLE_MAPS_API_KEY,${REACT_APP_GOOGLE_MAPS_API_KEY}," web-app/src/config.js 63 | sed -Ei "s,REACT_APP_GOOGLE_GEOCODING,${REACT_APP_GOOGLE_GEOCODING}," web-app/src/config.js 64 | 65 | #- name: configure amplify 66 | # uses: ambientlight/amplify-cli-action@0.2.1 67 | # with: 68 | # amplify_command: configure 69 | # amplify_env: master 70 | # env: 71 | # AWS_ACCESS_KEY_ID: ${{ secrets.SERVICE_PROVIDER_READ_ACCESS_KEY_ID }} 72 | # AWS_SECRET_ACCESS_KEY: ${{ secrets.SERVICE_PROVIDER_READ_SECRET_ACCESS_KEY }} 73 | # AWS_REGION: us-east-1 74 | 75 | - name: install, build and test 76 | run: | 77 | npm install 78 | npm test 79 | CI=false npm run build --if-present 80 | env: 81 | CI: false 82 | working-directory: web-app 83 | 84 | - name: deploy 85 | uses: ambientlight/amplify-cli-action@0.2.1 86 | with: 87 | amplify_command: publish 88 | amplify_env: prod 89 | env: 90 | CI: false 91 | AWS_ACCESS_KEY_ID: ${{ secrets.SERVICE_PROVIDER_READ_ACCESS_KEY_ID }} 92 | AWS_SECRET_ACCESS_KEY: ${{ secrets.SERVICE_PROVIDER_READ_SECRET_ACCESS_KEY }} 93 | AWS_REGION: us-east-1 94 | FIREBASE_API_KEY: ${{ secrets.FIREBASE_API_KEY }} 95 | FIREBASE_APP_ID: ${{ secrets.FIREBASE_APP_ID }} 96 | FIREBASE_AUTH_DOMAIN: ${{ secrets.FIREBASE_AUTH_DOMAIN }} 97 | FIREBASE_DB_URL: ${{ secrets.FIREBASE_DB_URL }} 98 | FIREBASE_MESSAGING_SENDER_ID: ${{ secrets.FIREBASE_MESSAGING_SENDER_ID }} 99 | FIREBASE_PROJECT_ID: ${{ secrets.FIREBASE_PROJECT_ID }} 100 | FIREBASE_STORAGE_BUCKET: ${{ secrets.FIREBASE_STORAGE_BUCKET }} 101 | MEASUREMENT_ID: ${{ secrets.MEASUREMENT_ID }} 102 | REACT_APP_GOOGLE_MAPS_API_KEY: ${{ secrets.REACT_APP_GOOGLE_MAPS_API_KEY }} 103 | REACT_APP_GOOGLE_GEOCODING: ${{ secrets.REACT_APP_GOOGLE_GEOCODING }} 104 | #- run: amplify init --appId "$AWS_APP_ID" --envName "$AWS_BACKEND_ENV_NAME" --yes 105 | #- run: amplify init --amplify $AMPLIFY --providers $PROVIDERS -categories $CATEGORIES --yes 106 | #- run: npm ci 107 | # working-directory: web-app 108 | #- run: npm run build --if-present 109 | # working-directory: web-app 110 | #- run: npm test 111 | # working-directory: web-app 112 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | web-app/node_modules/ 3 | .DS_Store 4 | .env 5 | design 6 | 7 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 8 | 9 | # dependencies 10 | /node_modules 11 | /.pnp 12 | .pnp.js 13 | 14 | # testing 15 | /coverage 16 | 17 | # production 18 | /build 19 | 20 | # misc 21 | .DS_Store 22 | .env.local 23 | .env.development.local 24 | .env.test.local 25 | .env.production.local 26 | 27 | npm-debug.log* 28 | yarn-debug.log* 29 | yarn-error.log* 30 | 31 | #amplify 32 | amplify/\#current-cloud-backend 33 | amplify/.config/local-* 34 | amplify/mock-data 35 | amplify/backend/amplify-meta.json 36 | amplify/backend/awscloudformation 37 | build/ 38 | dist/ 39 | node_modules/ 40 | aws-exports.js 41 | awsconfiguration.json 42 | amplifyconfiguration.json 43 | amplify-build-config.json 44 | amplify-gradle-config.json 45 | amplifytools.xcconfig -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Please find an issue that suits you in the current milestone, assign yourself, fork the repository, and generate a PR when you have completed the issue or if you would like help. 2 | 3 | Below is a code-visual description of our software scrum process. 4 | ``` 5 | do { 6 | do { 7 | Fork -> Code -> PR -> Review -> Test 8 | } while (FeaturesOfSprint == Incomplete) 9 | Show users (soft release) 10 | features#-- 11 | } while (features# > 0) 12 | Launch() 13 | ``` 14 | 15 | If you would like to read project background before contributing feel free to learn more about the human centered design research that informed the feature requests. 16 | User Research and be found [here](https://docs.google.com/document/d/1T5tx78YrjtgtUsQMM7hu6QfJPlwbWESn3ZhBSLw504o/edit#heading=h.y6qihjxpo44m) 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DECARCERATION-PLATFORM 2 | [![Netlify Status](https://api.netlify.com/api/v1/badges/7b0aa6fb-1ff1-447c-a408-c3c9b1d7012e/deploy-status)](https://app.netlify.com/sites/widp/deploys) 3 | 4 | # We launched. 5 | * [https://wisdp.com/](https://wisdp.com/) 6 | 7 | # Live Deployed Previews 8 | * [https://widp.netlify.app/](https://widp.netlify.app/) 9 | 10 | # Description 11 | This project (1) equips service providers with the tools they need to have a positive network effect and build and maintain awesome impact within and across communities, AND (2) to equip post incarcerated individuals with a single tool that guides their reentry journey so they can lead lives of purpose and positivity in their communities and families. 12 | 13 | We believe that many reentry organizations nationally could have a more transformative impact on mass incarceration if they are provided with more incentives, reminders, and notices to collaborate as well as if they had fewer gates to reach the individuals they wish to help. We also believe many people formerly incarcerated can and will lead law-abiding lives if their reentry journeys were filled with less hurdles, more positivity, and clearer tasks. Therefore, we seek to create a platform that meets those needs. 14 | 15 | We envision this tool to someday be launchable and customizable by any Code for America team in any state in the Unites States of America. 16 | 17 | ## Sites we've set up a profile on 18 | Democracy Lab - [DP](https://www.democracylab.org/index/?section=AboutProject&id=637) 19 | 20 | # Installation 21 | This project uses NPM and was started with create-react-app. 22 | 23 | Once cloned, running a ```npm install``` in ```web-app/``` followed by ```npm start``` will start and open a development version of the website app in your browser (by your localhost). 24 | 25 | # Usage 26 | Navigation can be done by appending routes to the end of the url in browser currently, those routes are defined in ```web-app/src/routes.js```. 27 | Currently implemented routes: 28 | * /signup 29 | * /signin 30 | * /calendar 31 | * /home 32 | * /services 33 | * /privacypolicy 34 | * /termsandconditions 35 | 36 | Screenshots will be included in the next sprint. 37 | 38 | # Contributing 39 | See [./CONTRIBUTING.md](https://github.com/codeformilwaukee/DECARCERATION-PLATFORM/blob/master/CONTRIBUTING.md) 40 | 41 | # Credits 42 | These contributors have submitted PRs and stayed in touch week after week 43 | 44 | * @[kaftand](https://github.com/kaftand) - **David Kaftand** 45 | * @[paul-rinaldi](https://github.com/paul-rinaldi) - **Paul Rinaldi** 46 | 47 | These contributors were instrumental in our initial progress (as early as September 2019) 48 | 49 | * @[kaftan](https://github.com/kaftand) - **David Kaftand** 50 | * @[flurmbo](https://github.com/flurmbo) - **Phil Marshall** 51 | * @[paul-rinaldi](https://github.com/paul-rinaldi) - **Paul Rinaldi** 52 | * @[romkedehaan](https://github.com/romkedehaan) - **Romke De Haan** 53 | * @[aycrazy](https://github.com/aycrazy) - **Andrew Yaspan** 54 | 55 | New contributors who helped recently 56 | 57 | * @[gordoncaister](https://github.com/gordoncaister) - **Gordon Caister** 58 | * @[knutsoned](https://github.com/knutsoned) - **Ed Knutson** 59 | * @[hdenisenko](https://github.com/hdenisenko) 60 | * @[rohanrk](https://github.com/rohanrk) - **Rohan** 61 | * @[rs6713](https://github.com/rs6713) - **Becks Simpson** 62 | 63 | 64 | Thank you all for your dedication and applied passion! 65 | 66 | # License 67 | GNU GENERAL PUBLIC LICENSE 68 | Details [here](https://github.com/codeformilwaukee/DECARCERATION-PLATFORM/blob/master/LICENSE) 69 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /congressional-updates/congressional-scraper/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /congressional-updates/congressional-scraper/Congress.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | let api_key = 'pQkmBsvQcgUC5xRkEhodAOUToRddgtoaEqd82yrL'; 3 | const AWS = require('aws-sdk'); 4 | const axios = require('axios').default 5 | 6 | module.exports.wisconsinRssScraper = async event => { 7 | const rootUrl = "https://api.govinfo.gov/collections/"; 8 | const startDate = new Date(); 9 | const startDateStr = dateformat(startDate, "yyyy-mm-dd'T'hh:MM:ss'Z'"); 10 | const allBillsUrl = rootUrl + startDateStr + "?offset=0&pageSize=999&api_key=" + api_key; 11 | const billList = await axios.get(allBillsUrl); 12 | const allPackages = billList.data.packages; 13 | allPackages.map( 14 | function (package) { 15 | var billData = await axios.get(package.packageLink) 16 | billData.data. 17 | } 18 | 19 | ) 20 | // https://api.govinfo.gov/collections/BILLS/2019-08-28T20%3A18%3A10Z?offset=0&pageSize=9999&api_key=pQkmBsvQcgUC5xRkEhodAOUToRddgtoaEqd82yrL 21 | // let parsedOut = await ax. 22 | 23 | // Create the DynamoDB service object 24 | var ddb = new AWS.DynamoDB( 25 | {apiVersion: '2012-08-10', 26 | region: 'us-east-1'}); 27 | const relevantEntries = parsedOut.items.filter(isRelatedToCrime) 28 | // Call DynamoDB to add the item to the table 29 | for (var iEntry = 0; iEntry < relevantEntries.length; iEntry++) 30 | { 31 | var params = { 32 | TableName: 'WisconsinHouseTable', 33 | Item: { 34 | 'Title' : {S : relevantEntries[iEntry].title}, 35 | 'Content' : {S : relevantEntries[iEntry].content}, 36 | 'Link' : {S : relevantEntries[iEntry].link} 37 | } 38 | }; 39 | const out = await ddb.putItem(params, function(err, data) { 40 | if (err) { 41 | console.log("Error", err); 42 | } else { 43 | console.log("Success", data); 44 | } 45 | }); 46 | await out.promise() 47 | } 48 | // Use this code if you don't use the http event with the LAMBDA-PROXY integration 49 | // return { message: 'Go Serverless v1.0! Your function executed successfully!', event }; 50 | }; -------------------------------------------------------------------------------- /congressional-updates/congressional-scraper/WisconsinLegis.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | let Parser = require('rss-parser'); 3 | let parser = new Parser(); 4 | const AWS = require('aws-sdk'); 5 | function isRelatedToCrime(parsedItem) { 6 | const tags = 7 | [ 8 | /crime/gi, 9 | /judge/gi, 10 | /judicial/gi, 11 | /prison/gi, 12 | /jail/gi, 13 | /court/gi, 14 | /incarserat/gi, 15 | /law\senforcement/gi, 16 | /police/gi, 17 | /sentenc/gi, 18 | ] 19 | for (var iTag = 0; iTag < tags.length; iTag++){ 20 | if (parsedItem.content.match(tags[iTag])) { 21 | return true 22 | } 23 | } 24 | return false 25 | } 26 | module.exports.wisconsinRssScraper = async event => { 27 | let parsedOut = await parser.parseURL("https://docs.legis.wisconsin.gov/feed/custom/introducedtext") 28 | // Create the DynamoDB service object 29 | var ddb = new AWS.DynamoDB( 30 | {apiVersion: '2012-08-10', 31 | region: 'us-east-1'}); 32 | const relevantEntries = parsedOut.items.filter(isRelatedToCrime) 33 | // Call DynamoDB to add the item to the table 34 | for (var iEntry = 0; iEntry < relevantEntries.length; iEntry++) 35 | { 36 | var params = { 37 | TableName: 'WisconsinHouseTable', 38 | Item: { 39 | 'Title' : {S : relevantEntries[iEntry].title}, 40 | 'Content' : {S : relevantEntries[iEntry].content}, 41 | 'Link' : {S : relevantEntries[iEntry].link}, 42 | } 43 | }; 44 | const out = await ddb.putItem(params, function(err, data) { 45 | if (err) { 46 | console.log("Error", err); 47 | } else { 48 | console.log("Success", data); 49 | } 50 | }); 51 | await out.promise() 52 | } 53 | // Use this code if you don't use the http event with the LAMBDA-PROXY integration 54 | // return { message: 'Go Serverless v1.0! Your function executed successfully!', event }; 55 | }; 56 | -------------------------------------------------------------------------------- /congressional-updates/congressional-scraper/handler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.hello = async event => { 4 | return { 5 | statusCode: 200, 6 | body: JSON.stringify( 7 | { 8 | message: 'Go Serverless v1.0! Your function executed successfully!', 9 | input: event, 10 | }, 11 | null, 12 | 2 13 | ), 14 | }; 15 | 16 | // Use this code if you don't use the http event with the LAMBDA-PROXY integration 17 | // return { message: 'Go Serverless v1.0! Your function executed successfully!', event }; 18 | }; 19 | -------------------------------------------------------------------------------- /congressional-updates/congressional-scraper/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "lockfileVersion": 1 3 | } 4 | -------------------------------------------------------------------------------- /congressional-updates/congressional-scraper/readme.md: -------------------------------------------------------------------------------- 1 | **Congressional Scraper** 2 | 3 | `npm install` 4 | 5 | `serverless deploy` 6 | 7 | 8 | 9 | **Description** 10 | 11 | The congressional scraper pulls senate bills and assembly bills into a DynamoDB. -------------------------------------------------------------------------------- /congressional-updates/congressional-scraper/serverless.yml: -------------------------------------------------------------------------------- 1 | # Welcome to Serverless! 2 | # 3 | # This file is the main config file for your service. 4 | # It's very minimal at this point and uses default values. 5 | # You can always add more config options for more control. 6 | # We've included some commented out config examples here. 7 | # Just uncomment any of them to get that config option. 8 | # 9 | # For full config options, check the docs: 10 | # docs.serverless.com 11 | # 12 | # Happy Coding! 13 | 14 | service: Legislation 15 | #app: your-app-name 16 | #tenant: your-tenant-name 17 | 18 | # You can pin your service to only deploy with a specific Serverless version 19 | # Check out our docs for more details 20 | # frameworkVersion: "=X.X.X" 21 | 22 | provider: 23 | name: aws 24 | runtime: nodejs10.x 25 | environment: 26 | DYNAMODB_TABLE: ${self:service}-${opt:stage, self:provider.stage} 27 | iamRoleStatements: 28 | - Effect: Allow 29 | Action: 30 | - dynamodb:Query 31 | - dynamodb:Scan 32 | - dynamodb:GetItem 33 | - dynamodb:PutItem 34 | - dynamodb:UpdateItem 35 | - dynamodb:DeleteItem 36 | Resource: "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/WisconsinHouseTable" 37 | # you can overwrite defaults here 38 | # stage: dev 39 | # region: us-east-1 40 | 41 | # you can add statements to the Lambda function's IAM Role here 42 | # iamRoleStatements: 43 | # - Effect: "Allow" 44 | # Action: 45 | # - "s3:ListBucket" 46 | # Resource: { "Fn::Join" : ["", ["arn:aws:s3:::", { "Ref" : "ServerlessDeploymentBucket" } ] ] } 47 | # - Effect: "Allow" 48 | # Action: 49 | # - "s3:PutObject" 50 | # Resource: 51 | # Fn::Join: 52 | # - "" 53 | # - - "arn:aws:s3:::" 54 | # - "Ref" : "ServerlessDeploymentBucket" 55 | # - "/*" 56 | 57 | # you can define service wide environment variables here 58 | # environment: 59 | # variable1: value1 60 | 61 | # you can add packaging information here 62 | #package: 63 | # include: 64 | # - include-me.js 65 | # - include-me-dir/** 66 | # exclude: 67 | # - exclude-me.js 68 | # - exclude-me-dir/** 69 | 70 | functions: 71 | wisconsin_legislative_scraper: 72 | handler: WisconsinLegis.wisconsinRssScraper 73 | events: 74 | - schedule: rate(12 hours) 75 | # - websocket: $connect 76 | # - s3: ${env:BUCKET} 77 | # - schedule: rate(10 minutes) 78 | # - sns: greeter-topic 79 | # - stream: arn:aws:dynamodb:region:XXXXXX:table/foo/stream/1970-01-01T00:00:00.000 80 | # - alexaSkill: amzn1.ask.skill.xx-xx-xx-xx 81 | # - alexaSmartHome: amzn1.ask.skill.xx-xx-xx-xx 82 | # - iot: 83 | # sql: "SELECT * FROM 'some_topic'" 84 | # - cloudwatchEvent: 85 | # event: 86 | # source: 87 | # - "aws.ec2" 88 | # detail-type: 89 | # - "EC2 Instance State-change Notification" 90 | # detail: 91 | # state: 92 | # - pending 93 | # - cloudwatchLog: '/aws/lambda/hello' 94 | # - cognitoUserPool: 95 | # pool: MyUserPool 96 | # trigger: PreSignUp 97 | # - alb: 98 | # listenerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:listener/app/my-load-balancer/50dc6c495c0c9188/ 99 | # priority: 1 100 | # conditions: 101 | # host: example.com 102 | # path: /hello 103 | 104 | # Define function environment variables here 105 | # environment: 106 | # variable2: value2 107 | 108 | # you can add CloudFormation resource templates here 109 | resources: 110 | Resources: 111 | ItemsTable: 112 | Type: AWS::DynamoDB::Table 113 | Properties: 114 | TableName: "WisconsinHouseTable" 115 | AttributeDefinitions: 116 | - AttributeName: "Title" 117 | AttributeType: "S" 118 | KeySchema: 119 | - AttributeName: "Title" 120 | KeyType: "HASH" 121 | ProvisionedThroughput: 122 | ReadCapacityUnits: 2 123 | WriteCapacityUnits: 2 124 | # Outputs: 125 | # NewOutput: 126 | # Description: "Description for the output" 127 | # Value: "Some output value" 128 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | ## Welcome to GitHub Pages 2 | 3 | You can use the [editor on GitHub](https://github.com/codeformilwaukee/DECARCERATION-PLATFORM/edit/master/docs/index.md) to maintain and preview the content for your website in Markdown files. 4 | 5 | Whenever you commit to this repository, GitHub Pages will run [Jekyll](https://jekyllrb.com/) to rebuild the pages in your site, from the content in your Markdown files. 6 | 7 | ### Markdown 8 | 9 | Markdown is a lightweight and easy-to-use syntax for styling your writing. It includes conventions for 10 | 11 | ```markdown 12 | Syntax highlighted code block 13 | 14 | # Header 1 15 | ## Header 2 16 | ### Header 3 17 | 18 | - Bulleted 19 | - List 20 | 21 | 1. Numbered 22 | 2. List 23 | 24 | **Bold** and _Italic_ and `Code` text 25 | 26 | [Link](url) and ![Image](src) 27 | ``` 28 | 29 | For more details see [GitHub Flavored Markdown](https://guides.github.com/features/mastering-markdown/). 30 | 31 | ### Jekyll Themes 32 | 33 | Your Pages site will use the layout and styles from the Jekyll theme you have selected in your [repository settings](https://github.com/codeformilwaukee/DECARCERATION-PLATFORM/settings). The name of this theme is saved in the Jekyll `_config.yml` configuration file. 34 | 35 | ### Support or Contact 36 | 37 | Having trouble with Pages? Check out our [documentation](https://docs.github.com/categories/github-pages-basics/) or [contact support](https://github.com/contact) and we’ll help you sort it out. 38 | -------------------------------------------------------------------------------- /web-app/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | #amplify 26 | amplify/\#current-cloud-backend 27 | amplify/.config/local-* 28 | amplify/mock-data 29 | amplify/backend/amplify-meta.json 30 | amplify/backend/awscloudformation 31 | build/ 32 | dist/ 33 | node_modules/ 34 | aws-exports.js 35 | awsconfiguration.json 36 | amplifyconfiguration.json 37 | amplify-build-config.json 38 | amplify-gradle-config.json 39 | amplifytools.xcconfig -------------------------------------------------------------------------------- /web-app/.graphqlconfig.yml: -------------------------------------------------------------------------------- 1 | projects: 2 | serviceproviders: 3 | schemaPath: src/graphql/schema.json 4 | includes: 5 | - src/graphql/**/*.js 6 | excludes: 7 | - ./amplify/** 8 | extensions: 9 | amplify: 10 | codeGenTarget: javascript 11 | generatedFileName: '' 12 | docsFilePath: src/graphql 13 | extensions: 14 | amplify: 15 | version: 3 16 | -------------------------------------------------------------------------------- /web-app/README.md: -------------------------------------------------------------------------------- 1 | ![](https://github.com/codeformilwaukee/DECARCERATION-PLATFORM/workflows/.github/workflows/web-app.yml/badge.svg) 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `npm start` 10 | 11 | Runs the app in the development mode.
12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 13 | 14 | The page will reload if you make edits.
15 | You will also see any lint errors in the console. 16 | 17 | ### `npm test` 18 | 19 | Launches the test runner in the interactive watch mode.
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `npm build` 23 | 24 | Builds the app for production to the `build` folder.
25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.
28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `npm eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 35 | 36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 39 | 40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | 48 | ### Code Splitting 49 | 50 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting 51 | 52 | ### Analyzing the Bundle Size 53 | 54 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size 55 | 56 | ### Making a Progressive Web App 57 | 58 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app 59 | 60 | ### Advanced Configuration 61 | 62 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration 63 | 64 | ### Deployment 65 | 66 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment 67 | 68 | ### `yarn build` fails to minify 69 | 70 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify 71 | -------------------------------------------------------------------------------- /web-app/amplify/.config/project-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "projectName": "webapp", 3 | "version": "3.0", 4 | "frontend": "javascript", 5 | "javascript": { 6 | "framework": "react", 7 | "config": { 8 | "SourceDir": "src", 9 | "DistributionDir": "build", 10 | "BuildCommand": "npm build", 11 | "StartCommand": "npm start" 12 | } 13 | }, 14 | "providers": [ 15 | "awscloudformation" 16 | ] 17 | } -------------------------------------------------------------------------------- /web-app/amplify/backend/api/serviceproviders/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "AppSyncApiName": "serviceproviders", 3 | "DynamoDBBillingMode": "PAY_PER_REQUEST", 4 | "DynamoDBEnableServerSideEncryption": "false" 5 | } -------------------------------------------------------------------------------- /web-app/amplify/backend/api/serviceproviders/schema.graphql: -------------------------------------------------------------------------------- 1 | type Todo @model { 2 | id: ID! 3 | name: String! 4 | description: String 5 | } 6 | 7 | enum TypeOfOrg { 8 | NON_FOR_PROFIT 9 | FOR_PROFIT 10 | GOVT_ORG 11 | } 12 | 13 | type ServiceProvider @model { 14 | id: ID! 15 | name: String! 16 | typeOfOrg: String 17 | programmingAndServices: String 18 | description: String 19 | tag1: String 20 | tag2: String 21 | tag3: String 22 | tag4: String 23 | tag5: String 24 | primaryAddress: String 25 | primaryAddressName: String 26 | secondaryAddress: String 27 | secondaryAddressName: String 28 | primaryPhone: String 29 | primaryPhoneName: String 30 | secondaryPhone: String 31 | secondaryPhoneName: String 32 | fax: String 33 | email: String 34 | website: String 35 | attribution: String 36 | } 37 | 38 | -------------------------------------------------------------------------------- /web-app/amplify/backend/api/serviceproviders/stacks/CustomResources.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "An auto-generated nested stack.", 4 | "Metadata": {}, 5 | "Parameters": { 6 | "AppSyncApiId": { 7 | "Type": "String", 8 | "Description": "The id of the AppSync API associated with this project." 9 | }, 10 | "AppSyncApiName": { 11 | "Type": "String", 12 | "Description": "The name of the AppSync API", 13 | "Default": "AppSyncSimpleTransform" 14 | }, 15 | "env": { 16 | "Type": "String", 17 | "Description": "The environment name. e.g. Dev, Test, or Production", 18 | "Default": "NONE" 19 | }, 20 | "S3DeploymentBucket": { 21 | "Type": "String", 22 | "Description": "The S3 bucket containing all deployment assets for the project." 23 | }, 24 | "S3DeploymentRootKey": { 25 | "Type": "String", 26 | "Description": "An S3 key relative to the S3DeploymentBucket that points to the root\nof the deployment directory." 27 | } 28 | }, 29 | "Resources": { 30 | "EmptyResource": { 31 | "Type": "Custom::EmptyResource", 32 | "Condition": "AlwaysFalse" 33 | } 34 | }, 35 | "Conditions": { 36 | "HasEnvironmentParameter": { 37 | "Fn::Not": [ 38 | { 39 | "Fn::Equals": [ 40 | { 41 | "Ref": "env" 42 | }, 43 | "NONE" 44 | ] 45 | } 46 | ] 47 | }, 48 | "AlwaysFalse": { 49 | "Fn::Equals": [ 50 | "true", 51 | "false" 52 | ] 53 | } 54 | }, 55 | "Outputs": { 56 | "EmptyOutput": { 57 | "Description": "An empty output. You may delete this if you have at least one resource above.", 58 | "Value": "" 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /web-app/amplify/backend/api/serviceproviders/transform.conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 5, 3 | "ElasticsearchWarning": true 4 | } -------------------------------------------------------------------------------- /web-app/amplify/backend/auth/webappe28ff9ce/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "identityPoolName": "webappe28ff9ce_identitypool_e28ff9ce", 3 | "allowUnauthenticatedIdentities": false, 4 | "resourceNameTruncated": "webappe28ff9ce", 5 | "userPoolName": "webappe28ff9ce_userpool_e28ff9ce", 6 | "autoVerifiedAttributes": [ 7 | "email" 8 | ], 9 | "mfaConfiguration": "OFF", 10 | "mfaTypes": [ 11 | "SMS Text Message" 12 | ], 13 | "smsAuthenticationMessage": "Your authentication code is {####}", 14 | "smsVerificationMessage": "Your verification code is {####}", 15 | "emailVerificationSubject": "Your verification code", 16 | "emailVerificationMessage": "Your verification code is {####}", 17 | "defaultPasswordPolicy": false, 18 | "passwordPolicyMinLength": 8, 19 | "passwordPolicyCharacters": [], 20 | "requiredAttributes": [ 21 | "email", 22 | "name" 23 | ], 24 | "userpoolClientGenerateSecret": true, 25 | "userpoolClientRefreshTokenValidity": 30, 26 | "userpoolClientWriteAttributes": [ 27 | "email" 28 | ], 29 | "userpoolClientReadAttributes": [ 30 | "email" 31 | ], 32 | "userpoolClientLambdaRole": "webappe28ff9ce_userpoolclient_lambda_role", 33 | "userpoolClientSetAttributes": false, 34 | "sharedId": "e28ff9ce", 35 | "resourceName": "webappe28ff9ce", 36 | "authSelections": "identityPoolAndUserPool", 37 | "authRoleArn": { 38 | "Fn::GetAtt": [ 39 | "AuthRole", 40 | "Arn" 41 | ] 42 | }, 43 | "unauthRoleArn": { 44 | "Fn::GetAtt": [ 45 | "UnauthRole", 46 | "Arn" 47 | ] 48 | }, 49 | "useDefault": "default", 50 | "usernameAttributes": [ 51 | "email" 52 | ], 53 | "triggers": "{\"DefineAuthChallenge\":[\"captcha-define-challenge\"],\"CreateAuthChallenge\":[\"captcha-create-challenge\"],\"VerifyAuthChallengeResponse\":[\"captcha-verify\"]}", 54 | "userPoolGroupList": [], 55 | "parentStack": { 56 | "Ref": "AWS::StackId" 57 | }, 58 | "permissions": [], 59 | "dependsOn": [ 60 | { 61 | "category": "function", 62 | "resourceName": "webappe28ff9ceDefineAuthChallenge", 63 | "triggerProvider": "Cognito", 64 | "attributes": [ 65 | "Arn", 66 | "Name" 67 | ] 68 | }, 69 | { 70 | "category": "function", 71 | "resourceName": "webappe28ff9ceCreateAuthChallenge", 72 | "triggerProvider": "Cognito", 73 | "attributes": [ 74 | "Arn", 75 | "Name" 76 | ] 77 | }, 78 | { 79 | "category": "function", 80 | "resourceName": "webappe28ff9ceVerifyAuthChallengeResponse", 81 | "triggerProvider": "Cognito", 82 | "attributes": [ 83 | "Arn", 84 | "Name" 85 | ] 86 | } 87 | ] 88 | } -------------------------------------------------------------------------------- /web-app/amplify/backend/auth/webappe28ff9ce/webappe28ff9ce-cloudformation-template.yml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: 2010-09-09 2 | 3 | Parameters: 4 | env: 5 | Type: String 6 | authRoleArn: 7 | Type: String 8 | unauthRoleArn: 9 | Type: String 10 | 11 | 12 | 13 | 14 | functionwebappe28ff9ceDefineAuthChallengeArn: 15 | Type: String 16 | Default: functionwebappe28ff9ceDefineAuthChallengeArn 17 | 18 | functionwebappe28ff9ceDefineAuthChallengeName: 19 | Type: String 20 | Default: functionwebappe28ff9ceDefineAuthChallengeName 21 | 22 | 23 | 24 | functionwebappe28ff9ceCreateAuthChallengeArn: 25 | Type: String 26 | Default: functionwebappe28ff9ceCreateAuthChallengeArn 27 | 28 | functionwebappe28ff9ceCreateAuthChallengeName: 29 | Type: String 30 | Default: functionwebappe28ff9ceCreateAuthChallengeName 31 | 32 | 33 | 34 | functionwebappe28ff9ceVerifyAuthChallengeResponseArn: 35 | Type: String 36 | Default: functionwebappe28ff9ceVerifyAuthChallengeResponseArn 37 | 38 | functionwebappe28ff9ceVerifyAuthChallengeResponseName: 39 | Type: String 40 | Default: functionwebappe28ff9ceVerifyAuthChallengeResponseName 41 | 42 | 43 | 44 | 45 | 46 | identityPoolName: 47 | Type: String 48 | 49 | allowUnauthenticatedIdentities: 50 | Type: String 51 | 52 | resourceNameTruncated: 53 | Type: String 54 | 55 | userPoolName: 56 | Type: String 57 | 58 | autoVerifiedAttributes: 59 | Type: CommaDelimitedList 60 | 61 | mfaConfiguration: 62 | Type: String 63 | 64 | mfaTypes: 65 | Type: CommaDelimitedList 66 | 67 | smsAuthenticationMessage: 68 | Type: String 69 | 70 | smsVerificationMessage: 71 | Type: String 72 | 73 | emailVerificationSubject: 74 | Type: String 75 | 76 | emailVerificationMessage: 77 | Type: String 78 | 79 | defaultPasswordPolicy: 80 | Type: String 81 | 82 | passwordPolicyMinLength: 83 | Type: Number 84 | 85 | passwordPolicyCharacters: 86 | Type: CommaDelimitedList 87 | 88 | requiredAttributes: 89 | Type: CommaDelimitedList 90 | 91 | userpoolClientGenerateSecret: 92 | Type: String 93 | 94 | userpoolClientRefreshTokenValidity: 95 | Type: Number 96 | 97 | userpoolClientWriteAttributes: 98 | Type: CommaDelimitedList 99 | 100 | userpoolClientReadAttributes: 101 | Type: CommaDelimitedList 102 | 103 | userpoolClientLambdaRole: 104 | Type: String 105 | 106 | userpoolClientSetAttributes: 107 | Type: String 108 | 109 | sharedId: 110 | Type: String 111 | 112 | resourceName: 113 | Type: String 114 | 115 | authSelections: 116 | Type: String 117 | 118 | useDefault: 119 | Type: String 120 | 121 | usernameAttributes: 122 | Type: CommaDelimitedList 123 | 124 | triggers: 125 | Type: String 126 | 127 | userPoolGroupList: 128 | Type: CommaDelimitedList 129 | 130 | parentStack: 131 | Type: String 132 | 133 | permissions: 134 | Type: CommaDelimitedList 135 | 136 | dependsOn: 137 | Type: CommaDelimitedList 138 | 139 | Conditions: 140 | ShouldNotCreateEnvResources: !Equals [ !Ref env, NONE ] 141 | 142 | Resources: 143 | 144 | 145 | # BEGIN SNS ROLE RESOURCE 146 | SNSRole: 147 | # Created to allow the UserPool SMS Config to publish via the Simple Notification Service during MFA Process 148 | Type: AWS::IAM::Role 149 | Properties: 150 | RoleName: !If [ShouldNotCreateEnvResources, 'webappe28ff9ce_sns-role', !Join ['',[ 'sns', 'e28ff9ce', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]] 151 | AssumeRolePolicyDocument: 152 | Version: "2012-10-17" 153 | Statement: 154 | - Sid: "" 155 | Effect: "Allow" 156 | Principal: 157 | Service: "cognito-idp.amazonaws.com" 158 | Action: 159 | - "sts:AssumeRole" 160 | Condition: 161 | StringEquals: 162 | sts:ExternalId: webappe28ff9ce_role_external_id 163 | Policies: 164 | - 165 | PolicyName: webappe28ff9ce-sns-policy 166 | PolicyDocument: 167 | Version: "2012-10-17" 168 | Statement: 169 | - 170 | Effect: "Allow" 171 | Action: 172 | - "sns:Publish" 173 | Resource: "*" 174 | # BEGIN USER POOL RESOURCES 175 | UserPool: 176 | # Created upon user selection 177 | # Depends on SNS Role for Arn if MFA is enabled 178 | Type: AWS::Cognito::UserPool 179 | UpdateReplacePolicy: Retain 180 | Properties: 181 | UserPoolName: !If [ShouldNotCreateEnvResources, !Ref userPoolName, !Join ['',[!Ref userPoolName, '-', !Ref env]]] 182 | 183 | Schema: 184 | 185 | - 186 | Name: email 187 | Required: true 188 | Mutable: true 189 | 190 | - 191 | Name: name 192 | Required: true 193 | Mutable: true 194 | 195 | 196 | 197 | LambdaConfig: 198 | 199 | CreateAuthChallenge: !Ref functionwebappe28ff9ceCreateAuthChallengeArn 200 | 201 | 202 | 203 | DefineAuthChallenge: !Ref functionwebappe28ff9ceDefineAuthChallengeArn 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | VerifyAuthChallengeResponse: !Ref functionwebappe28ff9ceVerifyAuthChallengeResponseArn 212 | 213 | 214 | 215 | AutoVerifiedAttributes: !Ref autoVerifiedAttributes 216 | 217 | 218 | EmailVerificationMessage: !Ref emailVerificationMessage 219 | EmailVerificationSubject: !Ref emailVerificationSubject 220 | 221 | Policies: 222 | PasswordPolicy: 223 | MinimumLength: !Ref passwordPolicyMinLength 224 | RequireLowercase: false 225 | RequireNumbers: false 226 | RequireSymbols: false 227 | RequireUppercase: false 228 | 229 | UsernameAttributes: !Ref usernameAttributes 230 | 231 | MfaConfiguration: !Ref mfaConfiguration 232 | SmsVerificationMessage: !Ref smsVerificationMessage 233 | SmsConfiguration: 234 | SnsCallerArn: !GetAtt SNSRole.Arn 235 | ExternalId: webappe28ff9ce_role_external_id 236 | 237 | 238 | 239 | UserPoolCreateAuthChallengeLambdaInvokePermission: 240 | Type: "AWS::Lambda::Permission" 241 | DependsOn: UserPool 242 | Properties: 243 | Action: "lambda:invokeFunction" 244 | Principal: "cognito-idp.amazonaws.com" 245 | FunctionName: !Ref functionwebappe28ff9ceCreateAuthChallengeName 246 | SourceArn: !GetAtt UserPool.Arn 247 | 248 | 249 | 250 | UserPoolDefineAuthChallengeLambdaInvokePermission: 251 | Type: "AWS::Lambda::Permission" 252 | DependsOn: UserPool 253 | Properties: 254 | Action: "lambda:invokeFunction" 255 | Principal: "cognito-idp.amazonaws.com" 256 | FunctionName: !Ref functionwebappe28ff9ceDefineAuthChallengeName 257 | SourceArn: !GetAtt UserPool.Arn 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | UserPoolVerifyAuthChallengeResponseLambdaInvokePermission: 266 | Type: "AWS::Lambda::Permission" 267 | DependsOn: UserPool 268 | Properties: 269 | Action: "lambda:invokeFunction" 270 | Principal: "cognito-idp.amazonaws.com" 271 | FunctionName: !Ref functionwebappe28ff9ceVerifyAuthChallengeResponseName 272 | SourceArn: !GetAtt UserPool.Arn 273 | 274 | # Updating lambda role with permissions to Cognito 275 | 276 | 277 | UserPoolClientWeb: 278 | # Created provide application access to user pool 279 | # Depends on UserPool for ID reference 280 | Type: "AWS::Cognito::UserPoolClient" 281 | Properties: 282 | ClientName: webappe28ff9ce_app_clientWeb 283 | 284 | RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity 285 | UserPoolId: !Ref UserPool 286 | DependsOn: UserPool 287 | UserPoolClient: 288 | # Created provide application access to user pool 289 | # Depends on UserPool for ID reference 290 | Type: "AWS::Cognito::UserPoolClient" 291 | Properties: 292 | ClientName: webappe28ff9ce_app_client 293 | 294 | GenerateSecret: !Ref userpoolClientGenerateSecret 295 | RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity 296 | UserPoolId: !Ref UserPool 297 | DependsOn: UserPool 298 | # BEGIN USER POOL LAMBDA RESOURCES 299 | UserPoolClientRole: 300 | # Created to execute Lambda which gets userpool app client config values 301 | Type: 'AWS::IAM::Role' 302 | Properties: 303 | RoleName: !If [ShouldNotCreateEnvResources, !Ref userpoolClientLambdaRole, !Join ['',['upClientLambdaRole', 'e28ff9ce', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]] 304 | AssumeRolePolicyDocument: 305 | Version: '2012-10-17' 306 | Statement: 307 | - Effect: Allow 308 | Principal: 309 | Service: 310 | - lambda.amazonaws.com 311 | Action: 312 | - 'sts:AssumeRole' 313 | DependsOn: UserPoolClient 314 | UserPoolClientLambda: 315 | # Lambda which gets userpool app client config values 316 | # Depends on UserPool for id 317 | # Depends on UserPoolClientRole for role ARN 318 | Type: 'AWS::Lambda::Function' 319 | Properties: 320 | Code: 321 | ZipFile: !Join 322 | - |+ 323 | - - 'const response = require(''cfn-response'');' 324 | - 'const aws = require(''aws-sdk'');' 325 | - 'const identity = new aws.CognitoIdentityServiceProvider();' 326 | - 'exports.handler = (event, context, callback) => {' 327 | - ' if (event.RequestType == ''Delete'') { ' 328 | - ' response.send(event, context, response.SUCCESS, {})' 329 | - ' }' 330 | - ' if (event.RequestType == ''Update'' || event.RequestType == ''Create'') {' 331 | - ' const params = {' 332 | - ' ClientId: event.ResourceProperties.clientId,' 333 | - ' UserPoolId: event.ResourceProperties.userpoolId' 334 | - ' };' 335 | - ' identity.describeUserPoolClient(params).promise()' 336 | - ' .then((res) => {' 337 | - ' response.send(event, context, response.SUCCESS, {''appSecret'': res.UserPoolClient.ClientSecret});' 338 | - ' })' 339 | - ' .catch((err) => {' 340 | - ' response.send(event, context, response.FAILED, {err});' 341 | - ' });' 342 | - ' }' 343 | - '};' 344 | Handler: index.handler 345 | Runtime: nodejs10.x 346 | Timeout: '300' 347 | Role: !GetAtt 348 | - UserPoolClientRole 349 | - Arn 350 | DependsOn: UserPoolClientRole 351 | UserPoolClientLambdaPolicy: 352 | # Sets userpool policy for the role that executes the Userpool Client Lambda 353 | # Depends on UserPool for Arn 354 | # Marked as depending on UserPoolClientRole for easier to understand CFN sequencing 355 | Type: 'AWS::IAM::Policy' 356 | Properties: 357 | PolicyName: webappe28ff9ce_userpoolclient_lambda_iam_policy 358 | Roles: 359 | - !Ref UserPoolClientRole 360 | PolicyDocument: 361 | Version: '2012-10-17' 362 | Statement: 363 | - Effect: Allow 364 | Action: 365 | - 'cognito-idp:DescribeUserPoolClient' 366 | Resource: !GetAtt UserPool.Arn 367 | DependsOn: UserPoolClientLambda 368 | UserPoolClientLogPolicy: 369 | # Sets log policy for the role that executes the Userpool Client Lambda 370 | # Depends on UserPool for Arn 371 | # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing 372 | Type: 'AWS::IAM::Policy' 373 | Properties: 374 | PolicyName: webappe28ff9ce_userpoolclient_lambda_log_policy 375 | Roles: 376 | - !Ref UserPoolClientRole 377 | PolicyDocument: 378 | Version: 2012-10-17 379 | Statement: 380 | - Effect: Allow 381 | Action: 382 | - 'logs:CreateLogGroup' 383 | - 'logs:CreateLogStream' 384 | - 'logs:PutLogEvents' 385 | Resource: !Sub 386 | - arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:* 387 | - { region: !Ref "AWS::Region", account: !Ref "AWS::AccountId", lambda: !Ref UserPoolClientLambda} 388 | DependsOn: UserPoolClientLambdaPolicy 389 | UserPoolClientInputs: 390 | # Values passed to Userpool client Lambda 391 | # Depends on UserPool for Id 392 | # Depends on UserPoolClient for Id 393 | # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing 394 | Type: 'Custom::LambdaCallout' 395 | Properties: 396 | ServiceToken: !GetAtt UserPoolClientLambda.Arn 397 | clientId: !Ref UserPoolClient 398 | userpoolId: !Ref UserPool 399 | DependsOn: UserPoolClientLogPolicy 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | # BEGIN IDENTITY POOL RESOURCES 408 | 409 | 410 | IdentityPool: 411 | # Always created 412 | Type: AWS::Cognito::IdentityPool 413 | Properties: 414 | IdentityPoolName: !If [ShouldNotCreateEnvResources, 'webappe28ff9ce_identitypool_e28ff9ce', !Join ['',['webappe28ff9ce_identitypool_e28ff9ce', '__', !Ref env]]] 415 | 416 | CognitoIdentityProviders: 417 | - ClientId: !Ref UserPoolClient 418 | ProviderName: !Sub 419 | - cognito-idp.${region}.amazonaws.com/${client} 420 | - { region: !Ref "AWS::Region", client: !Ref UserPool} 421 | - ClientId: !Ref UserPoolClientWeb 422 | ProviderName: !Sub 423 | - cognito-idp.${region}.amazonaws.com/${client} 424 | - { region: !Ref "AWS::Region", client: !Ref UserPool} 425 | 426 | AllowUnauthenticatedIdentities: !Ref allowUnauthenticatedIdentities 427 | 428 | 429 | DependsOn: UserPoolClientInputs 430 | 431 | 432 | IdentityPoolRoleMap: 433 | # Created to map Auth and Unauth roles to the identity pool 434 | # Depends on Identity Pool for ID ref 435 | Type: AWS::Cognito::IdentityPoolRoleAttachment 436 | Properties: 437 | IdentityPoolId: !Ref IdentityPool 438 | Roles: 439 | unauthenticated: !Ref unauthRoleArn 440 | authenticated: !Ref authRoleArn 441 | DependsOn: IdentityPool 442 | 443 | 444 | Outputs : 445 | 446 | IdentityPoolId: 447 | Value: !Ref 'IdentityPool' 448 | Description: Id for the identity pool 449 | IdentityPoolName: 450 | Value: !GetAtt IdentityPool.Name 451 | 452 | 453 | 454 | 455 | UserPoolId: 456 | Value: !Ref 'UserPool' 457 | Description: Id for the user pool 458 | UserPoolName: 459 | Value: !Ref userPoolName 460 | AppClientIDWeb: 461 | Value: !Ref 'UserPoolClientWeb' 462 | Description: The user pool app client id for web 463 | AppClientID: 464 | Value: !Ref 'UserPoolClient' 465 | Description: The user pool app client id 466 | AppClientSecret: 467 | Value: !GetAtt UserPoolClientInputs.appSecret 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | -------------------------------------------------------------------------------- /web-app/amplify/backend/backend-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "function": { 3 | "webappe28ff9ceDefineAuthChallenge": { 4 | "build": true, 5 | "providerPlugin": "awscloudformation", 6 | "service": "Lambda" 7 | }, 8 | "webappe28ff9ceCreateAuthChallenge": { 9 | "build": true, 10 | "providerPlugin": "awscloudformation", 11 | "service": "Lambda" 12 | }, 13 | "webappe28ff9ceVerifyAuthChallengeResponse": { 14 | "build": true, 15 | "providerPlugin": "awscloudformation", 16 | "service": "Lambda" 17 | } 18 | }, 19 | "auth": { 20 | "webappe28ff9ce": { 21 | "service": "Cognito", 22 | "providerPlugin": "awscloudformation", 23 | "dependsOn": [ 24 | { 25 | "category": "function", 26 | "resourceName": "webappe28ff9ceDefineAuthChallenge", 27 | "triggerProvider": "Cognito", 28 | "attributes": [ 29 | "Arn", 30 | "Name" 31 | ] 32 | }, 33 | { 34 | "category": "function", 35 | "resourceName": "webappe28ff9ceCreateAuthChallenge", 36 | "triggerProvider": "Cognito", 37 | "attributes": [ 38 | "Arn", 39 | "Name" 40 | ] 41 | }, 42 | { 43 | "category": "function", 44 | "resourceName": "webappe28ff9ceVerifyAuthChallengeResponse", 45 | "triggerProvider": "Cognito", 46 | "attributes": [ 47 | "Arn", 48 | "Name" 49 | ] 50 | } 51 | ], 52 | "customAuth": true 53 | } 54 | }, 55 | "api": { 56 | "serviceproviders": { 57 | "service": "AppSync", 58 | "providerPlugin": "awscloudformation", 59 | "output": { 60 | "authConfig": { 61 | "additionalAuthenticationProviders": [], 62 | "defaultAuthentication": { 63 | "authenticationType": "API_KEY", 64 | "apiKeyConfig": { 65 | "apiKeyExpirationDays": 128, 66 | "description": "secondTry" 67 | } 68 | } 69 | } 70 | } 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceCreateAuthChallenge/amplify.state: -------------------------------------------------------------------------------- 1 | { 2 | "pluginId": "amplify-nodejs-function-runtime-provider", 3 | "functionRuntime": "nodejs", 4 | "useLegacyBuild": true, 5 | "defaultEditorFile": "src/index.js" 6 | } -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceCreateAuthChallenge/function-parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "trigger": true, 3 | "modules": [ 4 | "captcha-create-challenge" 5 | ], 6 | "parentResource": "webappe28ff9ce", 7 | "functionName": "webappe28ff9ceCreateAuthChallenge", 8 | "resourceName": "webappe28ff9ceCreateAuthChallenge", 9 | "parentStack": "auth", 10 | "triggerEnvs": [], 11 | "triggerDir": "/usr/local/lib/node_modules/@aws-amplify/cli/node_modules/amplify-category-auth/provider-utils/awscloudformation/utils/../triggers/CreateAuthChallenge", 12 | "triggerTemplate": "CreateAuthChallenge.json.ejs", 13 | "roleName": "webappe28ff9ceCreateAuthChallenge", 14 | "skipEdit": true 15 | } -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceCreateAuthChallenge/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "modules": "captcha-create-challenge", 3 | "resourceName": "webappe28ff9ceCreateAuthChallenge" 4 | } -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceCreateAuthChallenge/src/captcha-create-challenge.js: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | 4 | exports.handler = (event, context) => { 5 | if (event.request.session.length === 2 && event.request.challengeName === 'CUSTOM_CHALLENGE') { 6 | event.response.publicChallengeParameters = { trigger: 'true' }; 7 | event.response.privateChallengeParameters = { answer: '' }; 8 | event.response.challengeMetadata = 'CAPTCHA_CHALLENGE'; 9 | } 10 | context.done(null, event); 11 | }; 12 | -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceCreateAuthChallenge/src/event.json: -------------------------------------------------------------------------------- 1 | { 2 | "key1": "value1", 3 | "key2": "value2", 4 | "key3": "value3" 5 | } -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceCreateAuthChallenge/src/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | this file will loop through all js modules which are uploaded to the lambda resource, 3 | provided that the file names (without extension) are included in the "MODULES" env variable. 4 | "MODULES" is a comma-delimmited string. 5 | */ 6 | 7 | exports.handler = (event, context, callback) => { 8 | const modules = process.env.MODULES.split(','); 9 | for (let i = 0; i < modules.length; i += 1) { 10 | const { handler } = require(`./${modules[i]}`); 11 | handler(event, context, callback); 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceCreateAuthChallenge/src/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webappe28ff9ceCreateAuthChallenge", 3 | "version": "2.0.0", 4 | "lockfileVersion": 1 5 | } 6 | -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceCreateAuthChallenge/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webappe28ff9ceCreateAuthChallenge", 3 | "version": "2.0.0", 4 | "description": "Lambda function generated by Amplify", 5 | "main": "index.js", 6 | "license": "Apache-2.0" 7 | } 8 | -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceCreateAuthChallenge/webappe28ff9ceCreateAuthChallenge-cloudformation-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "Lambda resource stack creation using Amplify CLI", 4 | "Parameters": { 5 | "CHALLENGEANSWER": { 6 | "Type": "String", 7 | "Default": "" 8 | }, 9 | "modules": { 10 | "Type": "String", 11 | "Default": "", 12 | "Description": "Comma-delimmited list of modules to be executed by a lambda trigger. Sent to resource as an env variable." 13 | }, 14 | "resourceName": { 15 | "Type": "String", 16 | "Default": "" 17 | }, 18 | "trigger": { 19 | "Type": "String", 20 | "Default": "true" 21 | }, 22 | "functionName": { 23 | "Type": "String", 24 | "Default": "" 25 | }, 26 | "roleName": { 27 | "Type": "String", 28 | "Default": "" 29 | }, 30 | "parentResource": { 31 | "Type": "String", 32 | "Default": "" 33 | }, 34 | "parentStack": { 35 | "Type": "String", 36 | "Default": "" 37 | }, 38 | "env": { 39 | "Type": "String" 40 | } 41 | }, 42 | "Conditions": { 43 | "ShouldNotCreateEnvResources": { 44 | "Fn::Equals": [ 45 | { 46 | "Ref": "env" 47 | }, 48 | "NONE" 49 | ] 50 | } 51 | }, 52 | "Resources": { 53 | "LambdaFunction": { 54 | "Type": "AWS::Lambda::Function", 55 | "Metadata": { 56 | "aws:asset:path": "./src", 57 | "aws:asset:property": "Code" 58 | }, 59 | "Properties": { 60 | "Handler": "index.handler", 61 | "FunctionName": { 62 | "Fn::If": [ 63 | "ShouldNotCreateEnvResources", 64 | "webappe28ff9ceCreateAuthChallenge", 65 | { 66 | "Fn::Join": [ 67 | "", 68 | [ 69 | "webappe28ff9ceCreateAuthChallenge", 70 | "-", 71 | { 72 | "Ref": "env" 73 | } 74 | ] 75 | ] 76 | } 77 | ] 78 | }, 79 | "Environment": { 80 | "Variables": { 81 | "ENV": { 82 | "Ref": "env" 83 | }, 84 | "MODULES": { 85 | "Ref": "modules" 86 | }, 87 | "REGION": { 88 | "Ref": "AWS::Region" 89 | }, 90 | "CHALLENGEANSWER": { 91 | "Ref": "CHALLENGEANSWER" 92 | } 93 | } 94 | }, 95 | "Role": { 96 | "Fn::GetAtt": [ 97 | "LambdaExecutionRole", 98 | "Arn" 99 | ] 100 | }, 101 | "Runtime": "nodejs10.x", 102 | "Timeout": "25", 103 | "Code": { 104 | "S3Bucket": "amplify-webapp-master-00055-deployment", 105 | "S3Key": "amplify-builds/webappe28ff9ceCreateAuthChallenge-5263726c765039526d42-build.zip" 106 | } 107 | } 108 | }, 109 | "LambdaExecutionRole": { 110 | "Type": "AWS::IAM::Role", 111 | "Properties": { 112 | "RoleName": { 113 | "Fn::If": [ 114 | "ShouldNotCreateEnvResources", 115 | "webappe28ff9ceCreateAuthChallenge", 116 | { 117 | "Fn::Join": [ 118 | "", 119 | [ 120 | "webappe28ff9ceCreateAuthChallenge", 121 | "-", 122 | { 123 | "Ref": "env" 124 | } 125 | ] 126 | ] 127 | } 128 | ] 129 | }, 130 | "AssumeRolePolicyDocument": { 131 | "Version": "2012-10-17", 132 | "Statement": [ 133 | { 134 | "Effect": "Allow", 135 | "Principal": { 136 | "Service": [ 137 | "lambda.amazonaws.com" 138 | ] 139 | }, 140 | "Action": [ 141 | "sts:AssumeRole" 142 | ] 143 | } 144 | ] 145 | } 146 | } 147 | }, 148 | "lambdaexecutionpolicy": { 149 | "DependsOn": [ 150 | "LambdaExecutionRole" 151 | ], 152 | "Type": "AWS::IAM::Policy", 153 | "Properties": { 154 | "PolicyName": "lambda-execution-policy", 155 | "Roles": [ 156 | { 157 | "Ref": "LambdaExecutionRole" 158 | } 159 | ], 160 | "PolicyDocument": { 161 | "Version": "2012-10-17", 162 | "Statement": [ 163 | { 164 | "Effect": "Allow", 165 | "Action": [ 166 | "logs:CreateLogGroup", 167 | "logs:CreateLogStream", 168 | "logs:PutLogEvents" 169 | ], 170 | "Resource": { 171 | "Fn::Sub": [ 172 | "arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:*", 173 | { 174 | "region": { 175 | "Ref": "AWS::Region" 176 | }, 177 | "account": { 178 | "Ref": "AWS::AccountId" 179 | }, 180 | "lambda": { 181 | "Ref": "LambdaFunction" 182 | } 183 | } 184 | ] 185 | } 186 | } 187 | ] 188 | } 189 | } 190 | } 191 | }, 192 | "Outputs": { 193 | "Name": { 194 | "Value": { 195 | "Ref": "LambdaFunction" 196 | } 197 | }, 198 | "Arn": { 199 | "Value": { 200 | "Fn::GetAtt": [ 201 | "LambdaFunction", 202 | "Arn" 203 | ] 204 | } 205 | }, 206 | "LambdaExecutionRole": { 207 | "Value": { 208 | "Ref": "LambdaExecutionRole" 209 | } 210 | }, 211 | "Region": { 212 | "Value": { 213 | "Ref": "AWS::Region" 214 | } 215 | } 216 | } 217 | } -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceDefineAuthChallenge/amplify.state: -------------------------------------------------------------------------------- 1 | { 2 | "pluginId": "amplify-nodejs-function-runtime-provider", 3 | "functionRuntime": "nodejs", 4 | "useLegacyBuild": true, 5 | "defaultEditorFile": "src/index.js" 6 | } -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceDefineAuthChallenge/function-parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "trigger": true, 3 | "modules": [ 4 | "captcha-define-challenge" 5 | ], 6 | "parentResource": "webappe28ff9ce", 7 | "functionName": "webappe28ff9ceDefineAuthChallenge", 8 | "resourceName": "webappe28ff9ceDefineAuthChallenge", 9 | "parentStack": "auth", 10 | "triggerEnvs": [], 11 | "triggerDir": "/usr/local/lib/node_modules/@aws-amplify/cli/node_modules/amplify-category-auth/provider-utils/awscloudformation/utils/../triggers/DefineAuthChallenge", 12 | "triggerTemplate": "DefineAuthChallenge.json.ejs", 13 | "roleName": "webappe28ff9ceDefineAuthChallenge", 14 | "skipEdit": true 15 | } -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceDefineAuthChallenge/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "modules": "captcha-define-challenge", 3 | "resourceName": "webappe28ff9ceDefineAuthChallenge" 4 | } -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceDefineAuthChallenge/src/captcha-define-challenge.js: -------------------------------------------------------------------------------- 1 | exports.handler = (event, context) => { 2 | if (event.request.session.length === 1 && event.request.session[0].challengeName === 'SRP_A') { 3 | event.response.issueTokens = false; 4 | event.response.failAuthentication = false; 5 | event.response.challengeName = 'PASSWORD_VERIFIER'; 6 | } else if ( 7 | event.request.session.length === 2 && 8 | event.request.session[1].challengeName === 'PASSWORD_VERIFIER' && 9 | event.request.session[1].challengeResult === true 10 | ) { 11 | event.response.issueTokens = false; 12 | event.response.failAuthentication = false; 13 | event.response.challengeName = 'CUSTOM_CHALLENGE'; 14 | } else if ( 15 | event.request.session.length === 3 && 16 | event.request.session[2].challengeName === 'CUSTOM_CHALLENGE' && 17 | event.request.session[2].challengeResult === true 18 | ) { 19 | event.response.issueTokens = true; 20 | event.response.failAuthentication = false; 21 | } else { 22 | event.response.issueTokens = false; 23 | event.response.failAuthentication = true; 24 | } 25 | context.done(null, event); 26 | }; 27 | -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceDefineAuthChallenge/src/event.json: -------------------------------------------------------------------------------- 1 | { 2 | "key1": "value1", 3 | "key2": "value2", 4 | "key3": "value3" 5 | } -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceDefineAuthChallenge/src/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | this file will loop through all js modules which are uploaded to the lambda resource, 3 | provided that the file names (without extension) are included in the "MODULES" env variable. 4 | "MODULES" is a comma-delimmited string. 5 | */ 6 | 7 | exports.handler = (event, context, callback) => { 8 | const modules = process.env.MODULES.split(','); 9 | for (let i = 0; i < modules.length; i += 1) { 10 | const { handler } = require(`./${modules[i]}`); 11 | handler(event, context, callback); 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceDefineAuthChallenge/src/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webappe28ff9ceDefineAuthChallenge", 3 | "version": "2.0.0", 4 | "lockfileVersion": 1 5 | } 6 | -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceDefineAuthChallenge/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webappe28ff9ceDefineAuthChallenge", 3 | "version": "2.0.0", 4 | "description": "Lambda function generated by Amplify", 5 | "main": "index.js", 6 | "license": "Apache-2.0" 7 | } 8 | -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceDefineAuthChallenge/webappe28ff9ceDefineAuthChallenge-cloudformation-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "Lambda resource stack creation using Amplify CLI", 4 | "Parameters": { 5 | "modules": { 6 | "Type": "String", 7 | "Default": "", 8 | "Description": "Comma-delimmited list of modules to be executed by a lambda trigger. Sent to resource as an env variable." 9 | }, 10 | "resourceName": { 11 | "Type": "String", 12 | "Default": "" 13 | }, 14 | "trigger": { 15 | "Type": "String", 16 | "Default": "true" 17 | }, 18 | "functionName": { 19 | "Type": "String", 20 | "Default": "" 21 | }, 22 | "roleName": { 23 | "Type": "String", 24 | "Default": "" 25 | }, 26 | "parentResource": { 27 | "Type": "String", 28 | "Default": "" 29 | }, 30 | "parentStack": { 31 | "Type": "String", 32 | "Default": "" 33 | }, 34 | "env": { 35 | "Type": "String" 36 | } 37 | }, 38 | "Conditions": { 39 | "ShouldNotCreateEnvResources": { 40 | "Fn::Equals": [ 41 | { 42 | "Ref": "env" 43 | }, 44 | "NONE" 45 | ] 46 | } 47 | }, 48 | "Resources": { 49 | "LambdaFunction": { 50 | "Type": "AWS::Lambda::Function", 51 | "Metadata": { 52 | "aws:asset:path": "./src", 53 | "aws:asset:property": "Code" 54 | }, 55 | "Properties": { 56 | "Handler": "index.handler", 57 | "FunctionName": { 58 | "Fn::If": [ 59 | "ShouldNotCreateEnvResources", 60 | "webappe28ff9ceDefineAuthChallenge", 61 | { 62 | "Fn::Join": [ 63 | "", 64 | [ 65 | "webappe28ff9ceDefineAuthChallenge", 66 | "-", 67 | { 68 | "Ref": "env" 69 | } 70 | ] 71 | ] 72 | } 73 | ] 74 | }, 75 | "Environment": { 76 | "Variables": { 77 | "ENV": { 78 | "Ref": "env" 79 | }, 80 | "MODULES": { 81 | "Ref": "modules" 82 | }, 83 | "REGION": { 84 | "Ref": "AWS::Region" 85 | } 86 | } 87 | }, 88 | "Role": { 89 | "Fn::GetAtt": [ 90 | "LambdaExecutionRole", 91 | "Arn" 92 | ] 93 | }, 94 | "Runtime": "nodejs10.x", 95 | "Timeout": "25", 96 | "Code": { 97 | "S3Bucket": "amplify-webapp-master-00055-deployment", 98 | "S3Key": "amplify-builds/webappe28ff9ceDefineAuthChallenge-4d367a78567450756e56-build.zip" 99 | } 100 | } 101 | }, 102 | "LambdaExecutionRole": { 103 | "Type": "AWS::IAM::Role", 104 | "Properties": { 105 | "RoleName": { 106 | "Fn::If": [ 107 | "ShouldNotCreateEnvResources", 108 | "webappe28ff9ceDefineAuthChallenge", 109 | { 110 | "Fn::Join": [ 111 | "", 112 | [ 113 | "webappe28ff9ceDefineAuthChallenge", 114 | "-", 115 | { 116 | "Ref": "env" 117 | } 118 | ] 119 | ] 120 | } 121 | ] 122 | }, 123 | "AssumeRolePolicyDocument": { 124 | "Version": "2012-10-17", 125 | "Statement": [ 126 | { 127 | "Effect": "Allow", 128 | "Principal": { 129 | "Service": [ 130 | "lambda.amazonaws.com" 131 | ] 132 | }, 133 | "Action": [ 134 | "sts:AssumeRole" 135 | ] 136 | } 137 | ] 138 | } 139 | } 140 | }, 141 | "lambdaexecutionpolicy": { 142 | "DependsOn": [ 143 | "LambdaExecutionRole" 144 | ], 145 | "Type": "AWS::IAM::Policy", 146 | "Properties": { 147 | "PolicyName": "lambda-execution-policy", 148 | "Roles": [ 149 | { 150 | "Ref": "LambdaExecutionRole" 151 | } 152 | ], 153 | "PolicyDocument": { 154 | "Version": "2012-10-17", 155 | "Statement": [ 156 | { 157 | "Effect": "Allow", 158 | "Action": [ 159 | "logs:CreateLogGroup", 160 | "logs:CreateLogStream", 161 | "logs:PutLogEvents" 162 | ], 163 | "Resource": { 164 | "Fn::Sub": [ 165 | "arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:*", 166 | { 167 | "region": { 168 | "Ref": "AWS::Region" 169 | }, 170 | "account": { 171 | "Ref": "AWS::AccountId" 172 | }, 173 | "lambda": { 174 | "Ref": "LambdaFunction" 175 | } 176 | } 177 | ] 178 | } 179 | } 180 | ] 181 | } 182 | } 183 | } 184 | }, 185 | "Outputs": { 186 | "Name": { 187 | "Value": { 188 | "Ref": "LambdaFunction" 189 | } 190 | }, 191 | "Arn": { 192 | "Value": { 193 | "Fn::GetAtt": [ 194 | "LambdaFunction", 195 | "Arn" 196 | ] 197 | } 198 | }, 199 | "LambdaExecutionRole": { 200 | "Value": { 201 | "Ref": "LambdaExecutionRole" 202 | } 203 | }, 204 | "Region": { 205 | "Value": { 206 | "Ref": "AWS::Region" 207 | } 208 | } 209 | } 210 | } -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceVerifyAuthChallengeResponse/amplify.state: -------------------------------------------------------------------------------- 1 | { 2 | "pluginId": "amplify-nodejs-function-runtime-provider", 3 | "functionRuntime": "nodejs", 4 | "useLegacyBuild": true, 5 | "defaultEditorFile": "src/index.js" 6 | } -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceVerifyAuthChallengeResponse/function-parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "trigger": true, 3 | "modules": [ 4 | "captcha-verify" 5 | ], 6 | "parentResource": "webappe28ff9ce", 7 | "functionName": "webappe28ff9ceVerifyAuthChallengeResponse", 8 | "resourceName": "webappe28ff9ceVerifyAuthChallengeResponse", 9 | "parentStack": "auth", 10 | "triggerEnvs": [], 11 | "triggerDir": "/usr/local/lib/node_modules/@aws-amplify/cli/node_modules/amplify-category-auth/provider-utils/awscloudformation/utils/../triggers/VerifyAuthChallengeResponse", 12 | "triggerTemplate": "VerifyAuthChallengeResponse.json.ejs", 13 | "roleName": "webappe28ff9ceVerifyAuthChallengeResponse", 14 | "skipEdit": true, 15 | "RECAPTCHASECRET": "6LcnCcAZAAAAAFXoywd24h5Q0B8zAs8mQPdZBnlj" 16 | } -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceVerifyAuthChallengeResponse/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "modules": "captcha-verify", 3 | "resourceName": "webappe28ff9ceVerifyAuthChallengeResponse" 4 | } -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceVerifyAuthChallengeResponse/src/captcha-verify.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | const axios = require('axios'); 3 | /* eslint-enable */ 4 | 5 | exports.handler = (event, context, callback) => { 6 | axios 7 | .post( 8 | `https://www.google.com/recaptcha/api/siteverify?secret=${process.env.RECAPTCHASECRET}&response=${event.request.challengeAnswer}`, 9 | {} 10 | ) 11 | .then(response => { 12 | if (response && response.data && response.data.success) { 13 | event.response.answerCorrect = true; 14 | callback(null, event); 15 | } else { 16 | event.response.answerCorrect = false; 17 | callback(new Error('captcha verification error'), event); 18 | } 19 | }) 20 | .catch(() => { 21 | event.response.answerCorrect = false; 22 | callback(new Error('captcha verification error'), event); 23 | }); 24 | }; 25 | -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceVerifyAuthChallengeResponse/src/event.json: -------------------------------------------------------------------------------- 1 | { 2 | "key1": "value1", 3 | "key2": "value2", 4 | "key3": "value3" 5 | } -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceVerifyAuthChallengeResponse/src/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | this file will loop through all js modules which are uploaded to the lambda resource, 3 | provided that the file names (without extension) are included in the "MODULES" env variable. 4 | "MODULES" is a comma-delimmited string. 5 | */ 6 | 7 | exports.handler = (event, context, callback) => { 8 | const modules = process.env.MODULES.split(','); 9 | for (let i = 0; i < modules.length; i += 1) { 10 | const { handler } = require(`./${modules[i]}`); 11 | handler(event, context, callback); 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceVerifyAuthChallengeResponse/src/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webappe28ff9ceVerifyAuthChallengeResponse", 3 | "version": "2.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "axios": { 8 | "version": "0.21.1", 9 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", 10 | "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", 11 | "requires": { 12 | "follow-redirects": "^1.10.0" 13 | } 14 | }, 15 | "follow-redirects": { 16 | "version": "1.13.1", 17 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz", 18 | "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==" 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceVerifyAuthChallengeResponse/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webappe28ff9ceVerifyAuthChallengeResponse", 3 | "version": "2.0.0", 4 | "description": "Lambda function generated by Amplify", 5 | "main": "index.js", 6 | "license": "Apache-2.0", 7 | "dependencies": { 8 | "axios": "latest" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /web-app/amplify/backend/function/webappe28ff9ceVerifyAuthChallengeResponse/webappe28ff9ceVerifyAuthChallengeResponse-cloudformation-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "Lambda resource stack creation using Amplify CLI", 4 | "Parameters": { 5 | "RECAPTCHASECRET": { 6 | "Type": "String", 7 | "Default": "" 8 | }, 9 | "modules": { 10 | "Type": "String", 11 | "Default": "", 12 | "Description": "Comma-delimmited list of modules to be executed by a lambda trigger. Sent to resource as an env variable." 13 | }, 14 | "resourceName": { 15 | "Type": "String", 16 | "Default": "" 17 | }, 18 | "trigger": { 19 | "Type": "String", 20 | "Default": "true" 21 | }, 22 | "functionName": { 23 | "Type": "String", 24 | "Default": "" 25 | }, 26 | "roleName": { 27 | "Type": "String", 28 | "Default": "" 29 | }, 30 | "parentResource": { 31 | "Type": "String", 32 | "Default": "" 33 | }, 34 | "parentStack": { 35 | "Type": "String", 36 | "Default": "" 37 | }, 38 | "env": { 39 | "Type": "String" 40 | } 41 | }, 42 | "Conditions": { 43 | "ShouldNotCreateEnvResources": { 44 | "Fn::Equals": [ 45 | { 46 | "Ref": "env" 47 | }, 48 | "NONE" 49 | ] 50 | } 51 | }, 52 | "Resources": { 53 | "LambdaFunction": { 54 | "Type": "AWS::Lambda::Function", 55 | "Metadata": { 56 | "aws:asset:path": "./src", 57 | "aws:asset:property": "Code" 58 | }, 59 | "Properties": { 60 | "Handler": "index.handler", 61 | "FunctionName": { 62 | "Fn::If": [ 63 | "ShouldNotCreateEnvResources", 64 | "webappe28ff9ceVerifyAuthChallengeResponse", 65 | { 66 | "Fn::Join": [ 67 | "", 68 | [ 69 | "webappe28ff9ceVerifyAuthChallengeResponse", 70 | "-", 71 | { 72 | "Ref": "env" 73 | } 74 | ] 75 | ] 76 | } 77 | ] 78 | }, 79 | "Environment": { 80 | "Variables": { 81 | "ENV": { 82 | "Ref": "env" 83 | }, 84 | "MODULES": { 85 | "Ref": "modules" 86 | }, 87 | "REGION": { 88 | "Ref": "AWS::Region" 89 | }, 90 | "RECAPTCHASECRET": { 91 | "Ref": "RECAPTCHASECRET" 92 | } 93 | } 94 | }, 95 | "Role": { 96 | "Fn::GetAtt": [ 97 | "LambdaExecutionRole", 98 | "Arn" 99 | ] 100 | }, 101 | "Runtime": "nodejs10.x", 102 | "Timeout": "25", 103 | "Code": { 104 | "S3Bucket": "amplify-webapp-master-00055-deployment", 105 | "S3Key": "amplify-builds/webappe28ff9ceVerifyAuthChallengeResponse-593563776e574d30486b-build.zip" 106 | } 107 | } 108 | }, 109 | "LambdaExecutionRole": { 110 | "Type": "AWS::IAM::Role", 111 | "Properties": { 112 | "RoleName": { 113 | "Fn::If": [ 114 | "ShouldNotCreateEnvResources", 115 | "webappe28ff9ceVerifyAuthChallengeResponse", 116 | { 117 | "Fn::Join": [ 118 | "", 119 | [ 120 | "webappe28ff9ceVerifyAuthChallengeResponse", 121 | "-", 122 | { 123 | "Ref": "env" 124 | } 125 | ] 126 | ] 127 | } 128 | ] 129 | }, 130 | "AssumeRolePolicyDocument": { 131 | "Version": "2012-10-17", 132 | "Statement": [ 133 | { 134 | "Effect": "Allow", 135 | "Principal": { 136 | "Service": [ 137 | "lambda.amazonaws.com" 138 | ] 139 | }, 140 | "Action": [ 141 | "sts:AssumeRole" 142 | ] 143 | } 144 | ] 145 | } 146 | } 147 | }, 148 | "lambdaexecutionpolicy": { 149 | "DependsOn": [ 150 | "LambdaExecutionRole" 151 | ], 152 | "Type": "AWS::IAM::Policy", 153 | "Properties": { 154 | "PolicyName": "lambda-execution-policy", 155 | "Roles": [ 156 | { 157 | "Ref": "LambdaExecutionRole" 158 | } 159 | ], 160 | "PolicyDocument": { 161 | "Version": "2012-10-17", 162 | "Statement": [ 163 | { 164 | "Effect": "Allow", 165 | "Action": [ 166 | "logs:CreateLogGroup", 167 | "logs:CreateLogStream", 168 | "logs:PutLogEvents" 169 | ], 170 | "Resource": { 171 | "Fn::Sub": [ 172 | "arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:*", 173 | { 174 | "region": { 175 | "Ref": "AWS::Region" 176 | }, 177 | "account": { 178 | "Ref": "AWS::AccountId" 179 | }, 180 | "lambda": { 181 | "Ref": "LambdaFunction" 182 | } 183 | } 184 | ] 185 | } 186 | } 187 | ] 188 | } 189 | } 190 | } 191 | }, 192 | "Outputs": { 193 | "Name": { 194 | "Value": { 195 | "Ref": "LambdaFunction" 196 | } 197 | }, 198 | "Arn": { 199 | "Value": { 200 | "Fn::GetAtt": [ 201 | "LambdaFunction", 202 | "Arn" 203 | ] 204 | } 205 | }, 206 | "LambdaExecutionRole": { 207 | "Value": { 208 | "Ref": "LambdaExecutionRole" 209 | } 210 | }, 211 | "Region": { 212 | "Value": { 213 | "Ref": "AWS::Region" 214 | } 215 | } 216 | } 217 | } -------------------------------------------------------------------------------- /web-app/amplify/team-provider-info.json: -------------------------------------------------------------------------------- 1 | { 2 | "dev": { 3 | "awscloudformation": { 4 | "AuthRoleName": "amplify-webapp-dev-233558-authRole", 5 | "UnauthRoleArn": "arn:aws:iam::809636549385:role/amplify-webapp-dev-233558-unauthRole", 6 | "AuthRoleArn": "arn:aws:iam::809636549385:role/amplify-webapp-dev-233558-authRole", 7 | "Region": "us-east-1", 8 | "DeploymentBucketName": "amplify-webapp-dev-233558-deployment", 9 | "UnauthRoleName": "amplify-webapp-dev-233558-unauthRole", 10 | "StackName": "amplify-webapp-dev-233558", 11 | "StackId": "arn:aws:cloudformation:us-east-1:809636549385:stack/amplify-webapp-dev-233558/6705d470-c00b-11ea-8db5-0a3d3edde975", 12 | "AmplifyAppId": "d1mlp6mhc4eut2" 13 | }, 14 | "categories": { 15 | "function": { 16 | "webappe28ff9ceDefineAuthChallenge": {}, 17 | "webappe28ff9ceCreateAuthChallenge": {}, 18 | "webappe28ff9ceVerifyAuthChallengeResponse": { 19 | "RECAPTCHASECRET": "6LcnCcAZAAAAAFXoywd24h5Q0B8zAs8mQPdZBnlj" 20 | } 21 | }, 22 | "master": { 23 | "awscloudformation": { 24 | "AuthRoleName": "amplify-webapp-master-00055-authRole", 25 | "UnauthRoleArn": "arn:aws:iam::809636549385:role/amplify-webapp-master-00055-unauthRole", 26 | "AuthRoleArn": "arn:aws:iam::809636549385:role/amplify-webapp-master-00055-authRole", 27 | "Region": "us-east-1", 28 | "DeploymentBucketName": "amplify-webapp-master-00055-deployment", 29 | "UnauthRoleName": "amplify-webapp-master-00055-unauthRole", 30 | "StackName": "amplify-webapp-master-00055", 31 | "StackId": "arn:aws:cloudformation:us-east-1:809636549385:stack/amplify-webapp-master-00055/968fa340-05fe-11eb-adf9-1272d872aba7", 32 | "AmplifyAppId": "d2farwzqn5jkjx" 33 | }, 34 | "categories": { 35 | "auth": { 36 | "webappe28ff9ce": {} 37 | }, 38 | "function": { 39 | "webappe28ff9ceDefineAuthChallenge": {}, 40 | "webappe28ff9ceCreateAuthChallenge": {}, 41 | "webappe28ff9ceVerifyAuthChallengeResponse": { 42 | "RECAPTCHASECRET": "6LcnCcAZAAAAAFXoywd24h5Q0B8zAs8mQPdZBnlj" 43 | } 44 | } 45 | } 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /web-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "web-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@aws-amplify/ui-react": "^0.2.15", 7 | "@material-ui/core": "^4.10.2", 8 | "@material-ui/icons": "^4.9.1", 9 | "@material-ui/lab": "^4.0.0-alpha.56", 10 | "aws-amplify": "^3.0.24", 11 | "aws-sdk": "^2.748.0", 12 | "dotenv": "^8.2.0", 13 | "firebase": "^7.24.0", 14 | "google-maps-react": "^2.0.6", 15 | "moment": "^2.27.0", 16 | "react": "^16.13.1", 17 | "react-big-calendar": "^0.26.0", 18 | "react-dom": "^16.13.1", 19 | "react-geocode": "^0.2.2", 20 | "react-image-resizer": "^1.3.0", 21 | "react-router": "^5.2.0", 22 | "react-router-dom": "^5.2.0", 23 | "react-scripts": "^3.4.3", 24 | "react-toastify": "^6.2.0" 25 | }, 26 | "scripts": { 27 | "start": "react-scripts start", 28 | "build": "react-scripts build", 29 | "test": "react-scripts test --passWithNoTests", 30 | "eject": "react-scripts eject" 31 | }, 32 | "eslintConfig": { 33 | "extends": "react-app" 34 | }, 35 | "browserslist": { 36 | "production": [ 37 | ">0.2%", 38 | "not dead", 39 | "not op_mini all" 40 | ], 41 | "development": [ 42 | "last 1 chrome version", 43 | "last 1 firefox version", 44 | "last 1 safari version" 45 | ] 46 | }, 47 | "devDependencies": { 48 | "eslint-plugin-react-hooks": "^4.2.0" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /web-app/public/_redirects: -------------------------------------------------------------------------------- 1 | /* /index.html 200 -------------------------------------------------------------------------------- /web-app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeformilwaukee/DECARCERATION-PLATFORM/764bda3be05c9b7c832cfeafe43f733af3a5cac1/web-app/public/favicon.ico -------------------------------------------------------------------------------- /web-app/public/favicon_temp.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeformilwaukee/DECARCERATION-PLATFORM/764bda3be05c9b7c832cfeafe43f733af3a5cac1/web-app/public/favicon_temp.ico -------------------------------------------------------------------------------- /web-app/public/images/b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeformilwaukee/DECARCERATION-PLATFORM/764bda3be05c9b7c832cfeafe43f733af3a5cac1/web-app/public/images/b.png -------------------------------------------------------------------------------- /web-app/public/images/bg-main.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeformilwaukee/DECARCERATION-PLATFORM/764bda3be05c9b7c832cfeafe43f733af3a5cac1/web-app/public/images/bg-main.jpg -------------------------------------------------------------------------------- /web-app/public/images/c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeformilwaukee/DECARCERATION-PLATFORM/764bda3be05c9b7c832cfeafe43f733af3a5cac1/web-app/public/images/c.png -------------------------------------------------------------------------------- /web-app/public/images/d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeformilwaukee/DECARCERATION-PLATFORM/764bda3be05c9b7c832cfeafe43f733af3a5cac1/web-app/public/images/d.png -------------------------------------------------------------------------------- /web-app/public/images/help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeformilwaukee/DECARCERATION-PLATFORM/764bda3be05c9b7c832cfeafe43f733af3a5cac1/web-app/public/images/help.png -------------------------------------------------------------------------------- /web-app/public/images/informed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeformilwaukee/DECARCERATION-PLATFORM/764bda3be05c9b7c832cfeafe43f733af3a5cac1/web-app/public/images/informed.png -------------------------------------------------------------------------------- /web-app/public/images/organised.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeformilwaukee/DECARCERATION-PLATFORM/764bda3be05c9b7c832cfeafe43f733af3a5cac1/web-app/public/images/organised.png -------------------------------------------------------------------------------- /web-app/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 19 | 28 | Wisconsin Decarceration Platform 29 | 30 | 31 | 32 |
33 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /web-app/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeformilwaukee/DECARCERATION-PLATFORM/764bda3be05c9b7c832cfeafe43f733af3a5cac1/web-app/public/logo192.png -------------------------------------------------------------------------------- /web-app/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeformilwaukee/DECARCERATION-PLATFORM/764bda3be05c9b7c832cfeafe43f733af3a5cac1/web-app/public/logo512.png -------------------------------------------------------------------------------- /web-app/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon_temp.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /web-app/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | -------------------------------------------------------------------------------- /web-app/src/assets/commandToRun.sh: -------------------------------------------------------------------------------- 1 | aws dynamodb batch-write-item --request-items file://sh101-114.json 2 | 3 | -------------------------------------------------------------------------------- /web-app/src/assets/normalizeAWSJSON.py: -------------------------------------------------------------------------------- 1 | 2 | # abbreviations: 3 | # sp: service provider 4 | 5 | import json 6 | 7 | 8 | def normalize_sp(service_provider): 9 | normalized_sp = { 10 | "id": int(service_provider["PutRequest"]["Item"]["id"]["S"]), 11 | "Label": service_provider["PutRequest"]["Item"]["Label"]["S"], 12 | "Type": service_provider["PutRequest"]["Item"]["Type"]["S"], 13 | "Program and Services": service_provider["PutRequest"]["Item"]["Program and Services"]["S"], 14 | "Description": service_provider["PutRequest"]["Item"]["Description"]["S"], 15 | "Tags": list(service_provider["PutRequest"]["Item"]["Tags"]["SS"]), 16 | "Address": service_provider["PutRequest"]["Item"]["Address"]["S"], 17 | "Phone": service_provider["PutRequest"]["Item"]["Phone"]["S"], 18 | "Fax": service_provider["PutRequest"]["Item"]["Fax"]["S"], 19 | "Email": service_provider["PutRequest"]["Item"]["Email"]["S"], 20 | "Website": service_provider["PutRequest"]["Item"]["Website"]["S"], 21 | "Attributions": service_provider["PutRequest"]["Item"]["Attributions"]["S"] 22 | } 23 | 24 | # print("processed: ", normalized_sp) 25 | 26 | return normalized_sp 27 | 28 | def read_aws_json(filepath): 29 | raw_json = {} 30 | json_str = {} 31 | with open(filepath) as f: 32 | raw_json = json.load(f) 33 | json_str = json.dumps(raw_json, indent = 4, sort_keys=True) 34 | 35 | # print(raw_json["ServiceProvider-yoruyjsfane6zfwi54uakwddje-dev"]) 36 | # print(raw_json["ServiceProvider-yoruyjsfane6zfwi54uakwddje-dev"][0]) 37 | return raw_json, json_str 38 | 39 | def store_json(to_store, filepath): 40 | with open(filepath, 'w') as json_file: 41 | json_file.write(json.dumps(to_store, indent=4, sort_keys=True)) 42 | 43 | def normalize_list_sp(raw_sp): 44 | normalized_service_providers = [] 45 | for put_request in raw_sp["ServiceProvider-yoruyjsfane6zfwi54uakwddje-dev"]: 46 | normalized_service_providers.append(normalize_sp(put_request)) 47 | # print(len(normalized_service_providers)) 48 | return {"service_providers": normalized_service_providers} 49 | 50 | ### MAIN ### 51 | all_sp_raw, all_sp_json_str = read_aws_json('shFULL.json') 52 | sp_json = normalize_list_sp(all_sp_raw) 53 | print(json.dumps(sp_json["service_providers"], indent=4, sort_keys=True)) 54 | store_json(sp_json, 'shFULLNormalized.json') 55 | -------------------------------------------------------------------------------- /web-app/src/assets/sh0.json: -------------------------------------------------------------------------------- 1 | { 2 | "ServiceProvider-unbzaidlhvha3fmiol3dqmyhpu-master": [ 3 | { 4 | "PutRequest": { 5 | "Item": { 6 | "id": { 7 | "S": "0" 8 | }, 9 | "Label": { 10 | "S": "Meta House" 11 | }, 12 | "Type": { 13 | "S": "Non-Profit" 14 | }, 15 | "Program and Services": { 16 | "S": "Recovery Community" 17 | }, 18 | "Description": { 19 | "S": "Our Recovery Community offers a safe, affordable, and supportive place for women in early recovery to live. There are two divisions of our housing program, one that serves single women and one that serves women with children. Single women enjoy a private bedroom and share common living spaces with another woman in the program. Women with children enjoy a private two- or three-bedroom apartment based on the family’s need. Each division is clinically-supervised and offers residents a furnished apartment and access to a full array of outpatient treatment services and on-site staff. \n\nAt Meta House’s 25 furnished and supervised apartments, single women and families with children are provided a safe, clean environment while women and moms work on their recovery. Women who come to these apartments often lack a support system and safe place to live and have little to no ability to pay for housing. Our Sober Living Community will continue to offer women the opportunity to learn and practice coping skills and find appropriate long-term housing. Within this community, women and families will also have the support of Consumer Peer Specialists and peers who are committed to recovery from substance use disorder. While living in Meta House’s Sober Living Community, women will be asked to engage in 20 hours of meaningful activities per week while continuing to focus on their recovery." 20 | }, 21 | "Tags": { 22 | "SS": [ 23 | "Behavioral Health & Mental Health", 24 | "Housing" 25 | ] 26 | }, 27 | "Address": { 28 | "S": "2625 N. WEIL STREET \nMILWAUKEE, WI 53212 \n" 29 | }, 30 | "Phone": { 31 | "S": "414.962.1200" 32 | }, 33 | "Fax": { 34 | "S": "414.962.2305" 35 | }, 36 | "Email": { 37 | "S": "" 38 | }, 39 | "Website": { 40 | "S": "https://www.metahouse.org/" 41 | }, 42 | "Attributions": { 43 | "S": "" 44 | } 45 | } 46 | } 47 | } 48 | ] 49 | } -------------------------------------------------------------------------------- /web-app/src/components/AboutPage/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Container, Typography } from '@material-ui/core'; 3 | 4 | const AboutPage = () => { 5 | return ( 6 | 7 | VISION 8 | A Wisconsin with connected resources to create effective alternatives to and within the criminal justice system to promote healthy and peaceful communities. 9 | MISSION 10 | The mission of the Wisconsin Decarceration Platform is to foster collective action for positive change in the lives of those impacted by the justice system. We are a self-organizing anti-mass incarceration community, providing a digital safe place for service providers, advocacy organizations, and affected individuals to connect with each-other and those in need of post-conviction services. We strive for equity by promoting a culture of learning, agency, and human dignity to encourage collaboration and transformation. 11 | ORGANIZATIONS INVOLVED 12 | The WDP was conceptualized in 2018 and has been in development for the past two years by a collaborative group of community members, philanthropists, activists, and academics from MSOE, UWM, Marquette University, Wisconsin Justice Initiative, Project RETURN, WISDOM, EXPO, the Milwaukee Turners’ Confronting Mass Incarceration project, Community Advocates, and many more Wisconsin organizations. 13 |
14 | The Team 15 | 16 | David Liners, WISDOM 17 |
Gretchen Schuldt, Wisconsin Justice Initiative (WJI) 18 |
Jeremy McClain, University of Wisconsin-Milwaukee 19 |
Julilly Kohler, Milwaukee Turners Confronting Mass Incarceration Committee 20 |
Marisola Xhelili Ciaccio, Marquette University 21 |
Michael Carriere, Milwaukee School of Engineering (carriere@msoe.edu) 22 |
Milton Bond, Milwaukee Area Technical College 23 |
Natraj Shanker, Milwaukee Rotary 24 |
Paul Rinaldi, Milwaukee School of Engineering 25 |
Robert S. Smith, Marquette University 26 |
Sara Onitsuka, University of Wisconsin-Milwaukee 27 |
Shannon Ross, The Community 28 |
Sylvester Jackson, EXPO 29 |
Timothy Ehlinger, University of Wisconsin-Milwaukee) 30 |
Wendel Hruska, Project Return 31 |
32 |
33 | ) 34 | }; 35 | 36 | export default AboutPage; 37 | -------------------------------------------------------------------------------- /web-app/src/components/Account/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Account = () => ( 4 |
5 | ); 6 | 7 | export default Account; -------------------------------------------------------------------------------- /web-app/src/components/App/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { BrowserRouter as Router, Route } from "react-router-dom"; 3 | 4 | import LandingPage from "../LandingPage"; 5 | import SignInPage from "../SignInPage"; 6 | import Navigation from "../Navigation"; 7 | import SignUpPage from "../SignUpPage"; 8 | import Account from "../Account"; 9 | import Footer from "../Footer"; 10 | import CalendarPage from "../CalendarPage"; 11 | import ServicesPage from "../ServicesPage"; 12 | import PrivacyPolicyPage from "../PrivacyPolicyPage"; 13 | import TermsAndConditionsPage from "../TermsAndConditionsPage"; 14 | import AboutPage from "../AboutPage"; 15 | 16 | import * as ROUTES from "../../constants/routes"; 17 | import SupportCirclePage from "../SupportCircles"; 18 | 19 | const App = (props) => ( 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | } /> 31 | 32 | 33 | 38 | 39 | 40 | 41 |
42 |