forked from juspay/hyperswitch-control-center
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: recovery code component (juspay#715)
- Loading branch information
1 parent
2e471cc
commit a3093b0
Showing
4 changed files
with
172 additions
and
196 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
let h2TextStyle = HSwitchUtils.getTextClass((H2, Optional)) | ||
|
||
@react.component | ||
let make = (~setTotpStatus, ~onClickDownload) => { | ||
let showToast = ToastState.useShowToast() | ||
let getURL = APIUtils.useGetURL() | ||
let fetchDetails = APIUtils.useGetMethod() | ||
let (recoveryCodes, setRecoveryCodes) = React.useState(_ => []) | ||
let (screenState, setScreenState) = React.useState(_ => PageLoaderWrapper.Success) | ||
|
||
let generateRecoveryCodes = async () => { | ||
open TotpTypes | ||
try { | ||
open LogicUtils | ||
setScreenState(_ => PageLoaderWrapper.Loading) | ||
let url = getURL(~entityName=USERS, ~userType=#GENERATE_RECOVERY_CODES, ~methodType=Get, ()) | ||
let response = await fetchDetails(url) | ||
let recoveryCodesValue = response->getDictFromJsonObject->getStrArray("recovery_codes") | ||
setRecoveryCodes(_ => recoveryCodesValue) | ||
setScreenState(_ => PageLoaderWrapper.Success) | ||
} catch { | ||
| _ => setTotpStatus(_ => TOTP_SHOW_QR) | ||
} | ||
} | ||
|
||
let downloadRecoveryCodes = () => { | ||
open LogicUtils | ||
DownloadUtils.downloadOld( | ||
~fileName="recoveryCodes.txt", | ||
~content=JSON.stringifyWithIndent(recoveryCodes->getJsonFromArrayOfString, 3), | ||
) | ||
} | ||
|
||
let copyRecoveryCodes = ev => { | ||
open LogicUtils | ||
ev->ReactEvent.Mouse.stopPropagation | ||
Clipboard.writeText(JSON.stringifyWithIndent(recoveryCodes->getJsonFromArrayOfString, 3)) | ||
showToast(~message="Copied to Clipboard!", ~toastType=ToastSuccess, ()) | ||
} | ||
|
||
React.useEffect0(() => { | ||
generateRecoveryCodes()->ignore | ||
None | ||
}) | ||
|
||
<PageLoaderWrapper screenState> | ||
<div className={`bg-white h-40-rem w-133 rounded-2xl flex flex-col`}> | ||
<div className="p-6 border-b-2 flex justify-between items-center"> | ||
<p className={`${h2TextStyle} text-grey-900`}> | ||
{"Two factor recovery codes"->React.string} | ||
</p> | ||
</div> | ||
<div className="px-8 py-8 flex flex-col flex-1 justify-between"> | ||
<div className="flex flex-col gap-6"> | ||
<p className="text-jp-gray-700"> | ||
{"Recovery codes provide a way to access your account if you lose your device and can't receive two-factor authentication codes."->React.string} | ||
</p> | ||
<HSwitchUtils.WarningArea | ||
warningText="These codes are the last resort for accessing your account in case you lose your password and second factors. If you cannot find these codes, you will lose access to your account." | ||
/> | ||
<TwoFaElements.ShowRecoveryCodes recoveryCodes /> | ||
</div> | ||
<div className="flex gap-4 justify-end"> | ||
<Button | ||
leftIcon={CustomIcon(<img src={`/assets/CopyToClipboard.svg`} />)} | ||
text={"Copy"} | ||
buttonType={Secondary} | ||
buttonSize={Small} | ||
onClick={copyRecoveryCodes} | ||
/> | ||
<Button | ||
leftIcon={FontAwesome("download-api-key")} | ||
text={"Download"} | ||
buttonType={Primary} | ||
buttonSize={Small} | ||
onClick={_ => { | ||
downloadRecoveryCodes() | ||
onClickDownload(false)->ignore | ||
}} | ||
/> | ||
</div> | ||
</div> | ||
</div> | ||
</PageLoaderWrapper> | ||
} |
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
165 changes: 0 additions & 165 deletions
165
src/entryPoints/AuthModule/TotpAuth/TotpSetupElements.res
This file was deleted.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
let h2TextStyle = HSwitchUtils.getTextClass((H2, Optional)) | ||
let h3TextStyle = HSwitchUtils.getTextClass((H3, Leading_1)) | ||
let p2Regular = HSwitchUtils.getTextClass((P2, Regular)) | ||
let p3Regular = HSwitchUtils.getTextClass((P3, Regular)) | ||
|
||
module TotpScanQR = { | ||
@react.component | ||
let make = (~totpUrl, ~isQrVisible) => { | ||
<> | ||
<div className="grid grid-cols-4 gap-4 w-full"> | ||
<div className="flex flex-col gap-10 col-span-3"> | ||
<p> {"Use any authenticator app to complete the setup"->React.string} </p> | ||
<div className="flex flex-col gap-4"> | ||
<p className=p2Regular> | ||
{"Follow these steps to configure two factor authentication:"->React.string} | ||
</p> | ||
<div className="flex flex-col gap-4 ml-2"> | ||
<p className={`${p2Regular} opacity-60 flex gap-2 items-center`}> | ||
<div className="text-white rounded-full bg-grey-900 opacity-50 px-2 py-0.5"> | ||
{"1"->React.string} | ||
</div> | ||
{"Scan the QR code shown on the screen with your authenticator application"->React.string} | ||
</p> | ||
<p className={`${p2Regular} opacity-60 flex gap-2 items-center`}> | ||
<div className="text-white rounded-full bg-grey-900 opacity-50 px-2 py-0.5"> | ||
{"2"->React.string} | ||
</div> | ||
{"Enter the OTP code displayed on the authenticator app in below text field or textbox"->React.string} | ||
</p> | ||
</div> | ||
</div> | ||
</div> | ||
<div | ||
className={`flex flex-col gap-2 col-span-1 items-center justify-center ${totpUrl->String.length > 0 | ||
? "blur-none" | ||
: "blur-sm"}`}> | ||
<p className=p3Regular> {"Scan the QR Code into your app"->React.string} </p> | ||
{if isQrVisible { | ||
<ReactQRCode value=totpUrl size=150 /> | ||
} else { | ||
<Icon | ||
name="spinner" | ||
size=20 | ||
className="animate-spin" | ||
parentClass="w-full h-full flex justify-center items-center" | ||
/> | ||
}} | ||
</div> | ||
</div> | ||
<div className="h-px w-11/12 bg-grey-200 opacity-50" /> | ||
</> | ||
} | ||
} | ||
|
||
module TotpInput = { | ||
@react.component | ||
let make = (~otp, ~setOtp) => { | ||
<div className="flex flex-col gap-4 items-center"> | ||
<p> | ||
{"Enter a 6-digit authentication code generated by you authenticator app"->React.string} | ||
</p> | ||
<OtpInput value={otp} setValue={setOtp} /> | ||
</div> | ||
} | ||
} | ||
|
||
module ShowRecoveryCodes = { | ||
@react.component | ||
let make = (~recoveryCodes) => { | ||
<div | ||
className="border border-gray-200 rounded-md bg-jp-gray-100 py-6 px-12 flex gap-8 flex justify-evenly"> | ||
<div className="grid grid-cols-2 gap-4"> | ||
{recoveryCodes | ||
->Array.map(recoveryCode => | ||
<div className="flex items-center gap-2"> | ||
<div className="p-1 rounded-full bg-jp-gray-600" /> | ||
<p className="text-jp-gray-700 text-xl"> {recoveryCode->React.string} </p> | ||
</div> | ||
) | ||
->React.array} | ||
</div> | ||
</div> | ||
} | ||
} |