-
Notifications
You must be signed in to change notification settings - Fork 87
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6972 from opengovsg/release_v6.96.0
build: release v6.96.0
- Loading branch information
Showing
157 changed files
with
8,322 additions
and
4,828 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
export const MultiParty = ( | ||
props: React.SVGProps<SVGSVGElement>, | ||
): JSX.Element => { | ||
return ( | ||
<svg | ||
width="40" | ||
height="40" | ||
viewBox="0 0 40 40" | ||
fill="none" | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<path | ||
d="M20.5732 10.032L18.9012 11.5921L18.8229 11.6652L18.9012 11.7383L19.715 12.4977L19.7833 12.5614L19.8515 12.4977L23.0984 9.46808L23.1768 9.39498L23.0985 9.32186L19.8515 6.29096L19.7833 6.22727L19.715 6.29094L18.9012 7.05031L18.8229 7.1234L18.9012 7.19651L20.5734 8.75793H15.5221C15.2037 5.65438 12.5816 3.2335 9.39403 3.2335C5.99166 3.2335 3.2335 5.99166 3.2335 9.39403C3.2335 12.7964 5.99166 15.5546 9.39403 15.5546C12.581 15.5546 15.2026 13.1346 15.5219 10.032H20.5732ZM10.0317 19.4264L11.5918 21.0985L11.6649 21.1768L11.738 21.0985L12.4974 20.2846L12.5611 20.2164L12.4974 20.1482L9.46778 16.9012L9.39468 16.8229L9.32156 16.9012L6.29066 20.1482L6.22698 20.2164L6.29065 20.2846L7.05001 21.0985L7.1231 21.1768L7.19622 21.0985L8.75763 19.4263V24.4778C5.65422 24.7964 3.2335 27.4184 3.2335 30.6059C3.2335 34.0082 5.99166 36.7664 9.39402 36.7664C12.7964 36.7664 15.5546 34.0082 15.5546 30.6059C15.5546 27.4188 13.1345 24.7971 10.0317 24.478V19.4264ZM29.9682 15.5219L29.9682 20.5735L28.4081 18.9014L28.335 18.8231L28.2619 18.9014L27.5025 19.7153L27.4388 19.7835L27.5025 19.8517L30.5321 23.0987L30.6052 23.177L30.6783 23.0987L33.7092 19.8517L33.7729 19.7835L33.7093 19.7153L32.9499 18.9014L32.8768 18.8231L32.8037 18.9014L31.2423 20.5736V15.5221C34.3457 15.2035 36.7664 12.5815 36.7664 9.39403C36.7664 5.99166 34.0082 3.2335 30.6059 3.2335C27.2035 3.2335 24.4453 5.99166 24.4453 9.39403C24.4453 12.5811 26.8654 15.2028 29.9682 15.5219ZM13.3809 9.39403C13.3809 11.5959 11.5959 13.3809 9.39403 13.3809C7.19214 13.3809 5.40716 11.5959 5.40716 9.39403C5.40716 7.19214 7.19214 5.40716 9.39403 5.40716C11.5959 5.40716 13.3809 7.19214 13.3809 9.39403ZM9.39402 26.619C11.5959 26.619 13.3809 28.404 13.3809 30.6059C13.3809 32.8078 11.5959 34.5927 9.39402 34.5927C7.19214 34.5927 5.40716 32.8078 5.40716 30.6059C5.40715 28.404 7.19214 26.619 9.39402 26.619ZM30.6059 13.3809C28.404 13.3809 26.619 11.5959 26.619 9.39403C26.619 7.19214 28.404 5.40716 30.6059 5.40716C32.8078 5.40716 34.5927 7.19214 34.5927 9.39403C34.5927 11.5959 32.8078 13.3809 30.6059 13.3809ZM34.3734 30.5266C34.3734 32.6514 32.6509 34.3739 30.5261 34.3739C28.4013 34.3739 26.6788 32.6514 26.6788 30.5266C26.6788 28.4017 28.4013 26.6792 30.5261 26.6792C32.6509 26.6792 34.3734 28.4017 34.3734 30.5266ZM30.5261 36.7668C33.9725 36.7668 36.7664 33.973 36.7664 30.5266C36.7664 27.0802 33.9725 24.2863 30.5261 24.2863C27.0797 24.2863 24.2859 27.0802 24.2859 30.5266C24.2859 33.973 27.0797 36.7668 30.5261 36.7668Z" | ||
fill="#293044" | ||
stroke="#445072" | ||
stroke-width="0.2" | ||
/> | ||
</svg> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
168 changes: 168 additions & 0 deletions
168
frontend/src/components/SecretKeyVerificationInput/SecretKeyVerificationInput.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
import { useCallback, useMemo, useRef } from 'react' | ||
import { RegisterOptions, useForm } from 'react-hook-form' | ||
import { BiUpload } from 'react-icons/bi' | ||
import { | ||
FormControl, | ||
FormErrorMessage, | ||
IconButton, | ||
Input, | ||
Skeleton, | ||
Stack, | ||
} from '@chakra-ui/react' | ||
|
||
import { GUIDE_SECRET_KEY_LOSS } from '~constants/links' | ||
import { useIsMobile } from '~hooks/useIsMobile' | ||
import { isKeypairValid, SECRET_KEY_REGEX } from '~utils/secretKeyValidation' | ||
|
||
import Button from '../Button' | ||
import FormLabel from '../FormControl/FormLabel' | ||
import Link from '../Link' | ||
|
||
const SECRET_KEY_NAME = 'secretKey' | ||
|
||
export type SecretKeyVerificationInputProps = { | ||
publicKey: string | null | ||
setSecretKey: (secretKey: string) => void | ||
isLoading: boolean | ||
description: string | ||
isButtonFullWidth: boolean | ||
showGuideLink: boolean | ||
buttonText: string | ||
prefillSecretKey?: string | ||
} | ||
|
||
interface SecretKeyFormInputs { | ||
[SECRET_KEY_NAME]: string | ||
} | ||
|
||
export const SecretKeyVerificationInput = ({ | ||
publicKey, | ||
setSecretKey, | ||
isLoading, | ||
description, | ||
isButtonFullWidth, | ||
showGuideLink, | ||
buttonText, | ||
prefillSecretKey, | ||
}: SecretKeyVerificationInputProps) => { | ||
const isMobile = useIsMobile() | ||
|
||
const { | ||
formState: { errors }, | ||
setError, | ||
register, | ||
setValue, | ||
handleSubmit, | ||
} = useForm<SecretKeyFormInputs>({ | ||
defaultValues: { secretKey: prefillSecretKey }, | ||
}) | ||
|
||
const fileUploadRef = useRef<HTMLInputElement | null>(null) | ||
|
||
const secretKeyValidationRules: RegisterOptions = useMemo(() => { | ||
return { | ||
required: "Please enter the form's secret key", | ||
validate: (secretKey: string) => { | ||
// Should not see this error message. | ||
if (!publicKey) return 'Unexpected form mode' | ||
|
||
const isValid = isKeypairValid(publicKey, secretKey) | ||
return isValid || 'The secret key provided is invalid' | ||
}, | ||
} | ||
}, [publicKey]) | ||
|
||
const handleVerifyKeypair = handleSubmit(({ secretKey }) => { | ||
return setSecretKey(secretKey.trim()) | ||
}) | ||
|
||
const handleFileSelect = useCallback( | ||
({ target }: React.ChangeEvent<HTMLInputElement>) => { | ||
const file = target.files?.[0] | ||
// Reset file input so the same file selected will trigger this onChange | ||
// function. | ||
if (fileUploadRef.current) { | ||
fileUploadRef.current.value = '' | ||
} | ||
|
||
if (!file) return | ||
|
||
const reader = new FileReader() | ||
reader.onload = async (e) => { | ||
if (!e.target) return | ||
const text = e.target.result?.toString().trim() | ||
|
||
if (!text || !SECRET_KEY_REGEX.test(text)) { | ||
return setError( | ||
SECRET_KEY_NAME, | ||
{ | ||
type: 'invalidFile', | ||
message: 'Selected file seems to be invalid', | ||
}, | ||
{ shouldFocus: true }, | ||
) | ||
} | ||
|
||
setValue(SECRET_KEY_NAME, text, { shouldValidate: true }) | ||
} | ||
reader.readAsText(file) | ||
}, | ||
[setError, setValue], | ||
) | ||
|
||
return ( | ||
<form onSubmit={handleVerifyKeypair} noValidate> | ||
{/* Hidden input field to trigger file selector, can be anywhere in the DOM */} | ||
<Input | ||
name="secretKeyFile" | ||
ref={fileUploadRef} | ||
type="file" | ||
accept="text/plain" | ||
onChange={handleFileSelect} | ||
display="none" | ||
/> | ||
<FormControl isRequired isInvalid={!!errors.secretKey} mb="1rem"> | ||
<FormLabel description={description}> | ||
Enter or upload Secret Key | ||
</FormLabel> | ||
<Stack direction="row" spacing="0.5rem"> | ||
<Skeleton isLoaded={!isLoading} w="100%"> | ||
<Input | ||
isDisabled={isLoading} | ||
{...register(SECRET_KEY_NAME, secretKeyValidationRules)} | ||
/> | ||
</Skeleton> | ||
<Skeleton isLoaded={!isLoading}> | ||
<IconButton | ||
isDisabled={isLoading} | ||
variant="outline" | ||
aria-label="Pass secret key from file" | ||
icon={<BiUpload />} | ||
onClick={() => fileUploadRef.current?.click()} | ||
/> | ||
</Skeleton> | ||
</Stack> | ||
<FormErrorMessage>{errors.secretKey?.message}</FormErrorMessage> | ||
</FormControl> | ||
<Stack | ||
spacing={{ base: '1.5rem', md: '2rem' }} | ||
align="center" | ||
direction={{ base: 'column', md: 'row' }} | ||
mt="2rem" | ||
> | ||
<Button | ||
isFullWidth={isMobile || isButtonFullWidth} | ||
isDisabled={isLoading} | ||
type="submit" | ||
> | ||
{buttonText} | ||
</Button> | ||
{showGuideLink && ( | ||
<Link variant="standalone" isExternal href={GUIDE_SECRET_KEY_LOSS}> | ||
Can't find your Secret Key? | ||
</Link> | ||
)} | ||
</Stack> | ||
</form> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { SecretKeyVerificationInput as default } from './SecretKeyVerificationInput' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.