Skip to content

Commit

Permalink
Puts test message behind a captcha (nasa-gcn#2547)
Browse files Browse the repository at this point in the history
  • Loading branch information
dakota002 authored Sep 4, 2024
1 parent a5b693d commit fc5f69a
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 12 deletions.
73 changes: 61 additions & 12 deletions app/routes/user.email._index/EmailNotificationCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@ import { Form, useFetcher } from '@remix-run/react'
import type { ModalRef } from '@trussworks/react-uswds'
import {
Button,
ButtonGroup,
Grid,
Icon,
Modal,
ModalFooter,
ModalHeading,
ModalToggleButton,
} from '@trussworks/react-uswds'
import { useEffect, useRef } from 'react'
import { useEffect, useRef, useState } from 'react'

import type { EmailNotificationVM } from '../user.email/email_notices.server'
import { ReCAPTCHA } from '~/components/ReCAPTCHA'
import TimeAgo from '~/components/TimeAgo'
import { ToolbarButtonGroup } from '~/components/ToolbarButtonGroup'
import { useRecaptchaSiteKey } from '~/root'

export default function EmailNotificationCard({
uuid,
Expand All @@ -25,9 +28,11 @@ export default function EmailNotificationCard({
}: EmailNotificationVM) {
const deleteModalRef = useRef<ModalRef>(null)
const testModalRef = useRef<ModalRef>(null)
const testConfirmRef = useRef<ModalRef>(null)
const deleteFetcher = useFetcher()
const testFetcher = useFetcher()
const disabled = deleteFetcher.state !== 'idle'
const [recaptchaValid, setRecaptchaValid] = useState(!useRecaptchaSiteKey())

useEffect(() => {
if (
Expand All @@ -36,6 +41,8 @@ export default function EmailNotificationCard({
testModalRef.current
) {
testModalRef.current.toggleModal(undefined, true)
setRecaptchaValid(false)
grecaptcha.reset()
}
}, [testFetcher.state, testFetcher.data, testModalRef])

Expand All @@ -61,17 +68,15 @@ export default function EmailNotificationCard({
</div>
<div className="tablet:grid-col flex-auto">
<ToolbarButtonGroup>
<testFetcher.Form method="POST">
<input type="hidden" name="recipient" value={recipient} />
<input type="hidden" name="intent" value="sendTest" />
<Button type="submit" outline disabled={disabled}>
<Icon.MailOutline
role="presentation"
className="bottom-aligned margin-right-05"
/>
Test Message
</Button>
</testFetcher.Form>
<ModalToggleButton
opener
disabled={disabled || testFetcher.state !== 'idle'}
modalRef={testConfirmRef}
type="button"
className="bottom-aligned margin-right-05"
>
Test Message
</ModalToggleButton>
<Form method="GET" action="edit">
<input type="hidden" name="uuid" value={uuid} />
<Button type="submit" outline disabled={disabled}>
Expand Down Expand Up @@ -151,6 +156,50 @@ export default function EmailNotificationCard({
</ModalToggleButton>
</ModalFooter>
</Modal>
<Modal
id="test-confirmation"
ref={testConfirmRef}
aria-labelledby="modal-confirm-heading"
aria-describedby="modal-confirm-description"
renderToPortal={false} // FIXME: https://github.com/trussworks/react-uswds/pull/1890#issuecomment-1023730448
>
<ModalHeading id="modal-confirm-heading">
Test Email Confirmation
</ModalHeading>
<p id="modal-confirm-description">
This will send a generic test email to {recipient}. Do you wish to
continue?
</p>
<testFetcher.Form method="POST">
<ReCAPTCHA
onChange={(value) => {
setRecaptchaValid(Boolean(value))
}}
/>
<ModalFooter>
<input type="hidden" name="recipient" value={recipient} />
<input type="hidden" name="intent" value="sendTest" />
<ButtonGroup>
<ModalToggleButton
data-close-modal
modalRef={testConfirmRef}
closer
>
Cancel
</ModalToggleButton>
<Button
type="submit"
outline
data-close-modal
disabled={!(recaptchaValid && testFetcher.state === 'idle')}
>
<Icon.MailOutline role="presentation" />
Send
</Button>
</ButtonGroup>
</ModalFooter>
</testFetcher.Form>
</Modal>
</>
)
}
3 changes: 3 additions & 0 deletions app/routes/user.email._index/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
} from '../user.email/email_notices.server'
import EmailNotificationCard from './EmailNotificationCard'
import HeadingWithAddButton from '~/components/HeadingWithAddButton'
import { verifyRecaptcha } from '~/components/ReCAPTCHA'
import SegmentedCards from '~/components/SegmentedCards'
import Spinner from '~/components/Spinner'
import { getFormDataString } from '~/lib/utils'
Expand All @@ -49,6 +50,8 @@ export async function action({ request }: ActionFunctionArgs) {
}
break
case 'sendTest':
const recaptchaResponse = getFormDataString(data, 'g-recaptcha-response')
await verifyRecaptcha(recaptchaResponse)
const recipient = getFormDataString(data, 'recipient')
if (recipient) {
await sendTestEmail(recipient)
Expand Down

0 comments on commit fc5f69a

Please sign in to comment.