@oneblink/apps-react 11.0.0-beta.1 → 11.0.0-beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/apps/auth-service.d.ts +15 -8
  2. package/dist/apps/auth-service.js +18 -8
  3. package/dist/apps/auth-service.js.map +1 -1
  4. package/dist/apps/index.d.ts +10 -0
  5. package/dist/apps/index.js +10 -0
  6. package/dist/apps/index.js.map +1 -1
  7. package/dist/apps/mfa-service.d.ts +29 -0
  8. package/dist/apps/mfa-service.js +30 -0
  9. package/dist/apps/mfa-service.js.map +1 -0
  10. package/dist/apps/services/AWSCognitoClient.d.ts +17 -11
  11. package/dist/apps/services/AWSCognitoClient.js +67 -38
  12. package/dist/apps/services/AWSCognitoClient.js.map +1 -1
  13. package/dist/apps/services/cognito.d.ts +5 -24
  14. package/dist/apps/services/cognito.js +3 -32
  15. package/dist/apps/services/cognito.js.map +1 -1
  16. package/dist/components/mfa/MfaAuthenticatorAppDialog.js +2 -2
  17. package/dist/components/mfa/MfaAuthenticatorAppDialog.js.map +1 -1
  18. package/dist/components/mfa/MfaMethodRow.d.ts +4 -1
  19. package/dist/components/mfa/MfaMethodRow.js +5 -5
  20. package/dist/components/mfa/MfaMethodRow.js.map +1 -1
  21. package/dist/components/mfa/MfaPhoneNumberDialog.js +10 -35
  22. package/dist/components/mfa/MfaPhoneNumberDialog.js.map +1 -1
  23. package/dist/components/mfa/MultiFactorAuthentication.d.ts +12 -10
  24. package/dist/components/mfa/MultiFactorAuthentication.js +21 -14
  25. package/dist/components/mfa/MultiFactorAuthentication.js.map +1 -1
  26. package/dist/form-elements/FormElementBarcodeScanner.js +66 -18
  27. package/dist/form-elements/FormElementBarcodeScanner.js.map +1 -1
  28. package/dist/hooks/useLogin.d.ts +16 -2
  29. package/dist/hooks/useLogin.js +53 -3
  30. package/dist/hooks/useLogin.js.map +1 -1
  31. package/dist/hooks/useMfa.d.ts +66 -31
  32. package/dist/hooks/useMfa.js +84 -61
  33. package/dist/hooks/useMfa.js.map +1 -1
  34. package/dist/hooks/useResendCoolDown.d.ts +5 -0
  35. package/dist/hooks/useResendCoolDown.js +27 -0
  36. package/dist/hooks/useResendCoolDown.js.map +1 -0
  37. package/dist/index.d.ts +2 -0
  38. package/dist/index.js +2 -0
  39. package/dist/index.js.map +1 -1
  40. package/dist/styles/barcode-scanner.scss +4 -0
  41. package/dist/styles.css +5 -0
  42. package/dist/styles.scss +1 -0
  43. package/dist/utils/joinArray.d.ts +1 -0
  44. package/dist/utils/joinArray.js +7 -0
  45. package/dist/utils/joinArray.js.map +1 -0
  46. package/dist/utils/mfa-requirement.d.ts +12 -0
  47. package/dist/utils/mfa-requirement.js +149 -0
  48. package/dist/utils/mfa-requirement.js.map +1 -0
  49. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"FormElementBarcodeScanner.js","sourceRoot":"","sources":["../../src/form-elements/FormElementBarcodeScanner.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport {\n Html5Qrcode,\n CameraDevice,\n Html5QrcodeSupportedFormats,\n} from 'html5-qrcode'\nimport CopyToClipboardButton from '../components/renderer/CopyToClipboardButton'\nimport useBooleanState from '../hooks/useBooleanState'\nimport LookupButton from '../components/renderer/LookupButton'\nimport { FormTypes } from '@oneblink/types'\nimport FormElementLabelContainer from '../components/renderer/FormElementLabelContainer'\nimport useLookupNotification, {\n LookupNotificationContext,\n} from '../hooks/useLookupNotification'\nimport { FormElementValueChangeHandler, IsDirtyProps } from '../types/form'\nimport useLoadDataState from '../hooks/useLoadDataState'\nimport OnLoading from '../components/renderer/OnLoading'\nimport useElementAriaDescribedby from '../hooks/useElementAriaDescribedby'\nimport MaterialIcon from '../components/MaterialIcon'\nimport FormElementValidationMessage from '../components/renderer/FormElementValidationMessage'\n\ntype Props = {\n id: string\n element: FormTypes.BarcodeScannerElement\n value: unknown | undefined\n onChange: FormElementValueChangeHandler<string>\n displayValidationMessage: boolean\n validationMessage: string | undefined\n autocompleteAttributes?: string\n} & IsDirtyProps\n\nfunction FormElementBarcodeScanner({\n id,\n element,\n value,\n onChange,\n validationMessage,\n displayValidationMessage,\n isDirty,\n setIsDirty,\n autocompleteAttributes,\n}: Props) {\n const ariaDescribedby = useElementAriaDescribedby(id, element)\n const [isCameraOpen, startBarcodeScanner, stopBarcodeScanner] =\n useBooleanState(false)\n const [error, setError] = React.useState<Error | null>(null)\n const { onLookup } = useLookupNotification(value)\n const handleScan = React.useCallback(\n (newValue: string | undefined) => {\n setIsDirty()\n onChange(element, {\n value: newValue,\n })\n stopBarcodeScanner()\n onLookup()\n },\n [element, onChange, onLookup, setIsDirty, stopBarcodeScanner],\n )\n\n const openBarcodeScanner = React.useCallback(() => {\n if (window.cordova) {\n setError(null)\n // @ts-expect-error ???\n window.cordova.plugins.barcodeScanner.scan(\n // @ts-expect-error ???\n (result) => {\n if (!result.cancelled) {\n handleScan(result.text)\n }\n },\n // @ts-expect-error ???\n (error) => {\n setError(\n new Error(\n `An error has occurred: \"${error}\". Please click \"Cancel\" below to try again. If the problem persists, please contact support.`,\n ),\n )\n },\n {\n showFlipCameraButton: true,\n showTorchButton: true,\n },\n )\n } else {\n startBarcodeScanner()\n }\n }, [handleScan, startBarcodeScanner])\n\n const { isLookingUp } = React.useContext(LookupNotificationContext)\n const isDisplayingValidationMessage =\n (isDirty || displayValidationMessage) && !!validationMessage && !isLookingUp\n\n const text = typeof value === 'string' ? value : ''\n return (\n <div className=\"cypress-barcode-scanner-element\">\n <FormElementLabelContainer\n className=\"ob-barcode-scanner\"\n element={element}\n id={id}\n required={element.required}\n >\n {error && (\n <figure className=\"ob-figure\">\n <div className=\"figure-content has-text-centered\">\n <div>\n <h4 className=\"title is-4\">Whoops...</h4>\n <p>{error.message}</p>\n </div>\n </div>\n </figure>\n )}\n\n {isCameraOpen ? (\n <BarcodeScannerSupported\n id={`${id}==BARCODE_SCANNER`}\n restrictedBarcodeTypes={\n element.restrictBarcodeTypes\n ? element.restrictedBarcodeTypes\n : undefined\n }\n onScan={handleScan}\n onClose={stopBarcodeScanner}\n aria-describedby={ariaDescribedby}\n />\n ) : (\n <div>\n <div className=\"field has-addons\">\n <div className=\"control is-expanded has-icons-right\">\n <input\n type=\"text\"\n placeholder={element.placeholderValue}\n id={id}\n name={element.name}\n className=\"input ob-input cypress-barcode-scanner-control has-margin-bottom-8\"\n value={text}\n onChange={(e) =>\n onChange(element, {\n value: e.target.value || undefined,\n })\n }\n required={element.required}\n disabled={element.readOnly}\n onBlur={setIsDirty}\n aria-describedby={ariaDescribedby}\n autoComplete={autocompleteAttributes}\n aria-required={element.required}\n />\n <span className=\"ob-input-icon icon is-small is-right\">\n <MaterialIcon className=\"is-size-5\">\n document_scanner\n </MaterialIcon>\n </span>\n </div>\n {!!element.readOnly && !!value && (\n <div className=\"control\">\n <CopyToClipboardButton\n className=\"button is-input-addon copy-button cypress-copy-to-clipboard-button\"\n text={text}\n />\n </div>\n )}\n <LookupButton\n isInputButton\n value={value}\n validationMessage={validationMessage}\n lookupButtonConfig={element.lookupButton}\n overrideRequiredMessage={undefined}\n />\n </div>\n\n <button\n type=\"button\"\n className=\"button ob-button ob-button__open is-primary cypress-start-scan-barcode-button\"\n disabled={element.readOnly}\n onClick={openBarcodeScanner}\n >\n Scan Barcode\n </button>\n </div>\n )}\n\n {isDisplayingValidationMessage && (\n <FormElementValidationMessage message={validationMessage} />\n )}\n </FormElementLabelContainer>\n </div>\n )\n}\n\nexport default React.memo(FormElementBarcodeScanner)\n\ntype BarcodeScannerProps = {\n id: string\n restrictedBarcodeTypes: FormTypes.BarcodeScannerElement['restrictedBarcodeTypes']\n onScan: (barcode: string | undefined) => void\n onClose: () => void\n 'aria-describedby'?: string\n}\n\nfunction BarcodeScannerSupported(props: BarcodeScannerProps) {\n const { onClose } = props\n if (!navigator.mediaDevices?.getUserMedia) {\n return (\n <BarcodeScannerFigure onClose={onClose}>\n <BarcodeScannerError\n title=\"Unsupported Device\"\n message=\"Your device does not support accessing your camera.\"\n />\n </BarcodeScannerFigure>\n )\n }\n\n return <BarcodeScannerCameraLoader {...props} />\n}\n\nfunction BarcodeScannerCameraLoader(props: BarcodeScannerProps) {\n const { onClose } = props\n const [state] = useLoadDataState(Html5Qrcode.getCameras)\n switch (state.status) {\n case 'LOADING': {\n return (\n <BarcodeScannerFigure onClose={onClose}>\n <div className=\"figure-content has-text-centered\">\n <OnLoading small />\n </div>\n </BarcodeScannerFigure>\n )\n }\n case 'ERROR': {\n return (\n <BarcodeScannerFigure onClose={onClose}>\n <BarcodeScannerError\n title=\"Whoops...\"\n message={\n state.error.name === 'NotAllowedError'\n ? 'Cannot scan for barcodes without granting the application access to the camera.'\n : state.error.message\n }\n />\n </BarcodeScannerFigure>\n )\n }\n }\n\n if (!state.result.length) {\n return (\n <BarcodeScannerFigure onClose={onClose}>\n <BarcodeScannerError\n title=\"No Cameras Available\"\n message=\"Your device does not have an accessible camera.\"\n />\n </BarcodeScannerFigure>\n )\n }\n\n return <BarcodeScanner {...props} cameraDevices={state.result} />\n}\n\nfunction BarcodeScanner({\n id,\n restrictedBarcodeTypes,\n onScan,\n onClose,\n ...props\n}: BarcodeScannerProps & {\n cameraDevices: CameraDevice[]\n}) {\n const formatsToSupport = React.useMemo(() => {\n return restrictedBarcodeTypes?.reduce<Html5QrcodeSupportedFormats[]>(\n (memo, barcodeType) => {\n const format =\n Html5QrcodeSupportedFormats[\n barcodeType as keyof typeof Html5QrcodeSupportedFormats\n ]\n if (format !== undefined) {\n memo.push(format)\n }\n return memo\n },\n [],\n )\n }, [restrictedBarcodeTypes])\n\n React.useEffect(() => {\n const html5Qrcode = new Html5Qrcode(id, {\n verbose: !!localStorage.getItem('BARCODE_SCANNER_VERBOSE'),\n formatsToSupport: formatsToSupport?.length ? formatsToSupport : undefined,\n })\n\n html5Qrcode\n .start(\n {\n facingMode: 'environment',\n },\n {\n fps: 20,\n qrbox: {\n width: 400,\n height: 400,\n },\n },\n function onScanSuccess(decodedText, decodedResult) {\n console.log('Barcode scanner decoded result:', decodedResult)\n onScan(decodedText)\n },\n function onScanFailure() {\n // do nothing and keep scanning\n },\n )\n .catch((error) => {\n console.warn('Failed to start scanning', error)\n })\n\n return () => {\n html5Qrcode.stop().catch((error) => {\n console.warn('Failed to stop barcode scanner', error)\n })\n }\n }, [formatsToSupport, id, onScan])\n\n return (\n <BarcodeScannerFigure onClose={onClose}>\n <div className=\"figure-content-absolute-center\">\n <OnLoading small />\n </div>\n <div\n id={id}\n className=\"ob-figure__barcode-scanner\"\n aria-describedby={props['aria-describedby']}\n />\n </BarcodeScannerFigure>\n )\n}\n\nfunction BarcodeScannerFigure({\n onClose,\n children,\n}: {\n onClose: () => void\n children: React.ReactNode\n}) {\n return (\n <div>\n <figure className=\"ob-figure\">{children}</figure>\n <div className=\"buttons ob-buttons\">\n <button\n type=\"button\"\n className=\"button ob-button ob-button__cancel is-light cypress-cancel-scan-barcode-button\"\n onClick={onClose}\n >\n Cancel\n </button>\n </div>\n </div>\n )\n}\n\nfunction BarcodeScannerError({\n title,\n message,\n}: {\n title: string\n message: string\n}) {\n return (\n <div className=\"figure-content has-text-centered\" role=\"alert\">\n <div>\n <h4 className=\"title is-4\">{title}</h4>\n <p className=\"has-margin-bottom-6\">{message}</p>\n <p>\n Please click <b>Cancel</b> below and type in the barcode value\n manually.\n </p>\n </div>\n </div>\n )\n}\n"]}
1
+ {"version":3,"file":"FormElementBarcodeScanner.js","sourceRoot":"","sources":["../../src/form-elements/FormElementBarcodeScanner.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport {\n Html5Qrcode,\n CameraDevice,\n Html5QrcodeSupportedFormats,\n Html5QrcodeCameraScanConfig,\n} from 'html5-qrcode'\nimport CopyToClipboardButton from '../components/renderer/CopyToClipboardButton'\nimport useBooleanState from '../hooks/useBooleanState'\nimport LookupButton from '../components/renderer/LookupButton'\nimport { FormTypes } from '@oneblink/types'\nimport FormElementLabelContainer from '../components/renderer/FormElementLabelContainer'\nimport useLookupNotification, {\n LookupNotificationContext,\n} from '../hooks/useLookupNotification'\nimport { FormElementValueChangeHandler, IsDirtyProps } from '../types/form'\nimport useLoadDataState from '../hooks/useLoadDataState'\nimport OnLoading from '../components/renderer/OnLoading'\nimport useElementAriaDescribedby from '../hooks/useElementAriaDescribedby'\nimport MaterialIcon from '../components/MaterialIcon'\nimport FormElementValidationMessage from '../components/renderer/FormElementValidationMessage'\n\ntype Props = {\n id: string\n element: FormTypes.BarcodeScannerElement\n value: unknown | undefined\n onChange: FormElementValueChangeHandler<string>\n displayValidationMessage: boolean\n validationMessage: string | undefined\n autocompleteAttributes?: string\n} & IsDirtyProps\n\nfunction FormElementBarcodeScanner({\n id,\n element,\n value,\n onChange,\n validationMessage,\n displayValidationMessage,\n isDirty,\n setIsDirty,\n autocompleteAttributes,\n}: Props) {\n const ariaDescribedby = useElementAriaDescribedby(id, element)\n const [isCameraOpen, startBarcodeScanner, stopBarcodeScanner] =\n useBooleanState(false)\n const [error, setError] = React.useState<Error | null>(null)\n const { onLookup } = useLookupNotification(value)\n const handleScan = React.useCallback(\n (newValue: string | undefined) => {\n setIsDirty()\n onChange(element, {\n value: newValue,\n })\n stopBarcodeScanner()\n onLookup()\n },\n [element, onChange, onLookup, setIsDirty, stopBarcodeScanner],\n )\n\n const openBarcodeScanner = React.useCallback(() => {\n if (window.cordova) {\n setError(null)\n // @ts-expect-error ???\n window.cordova.plugins.barcodeScanner.scan(\n // @ts-expect-error ???\n (result) => {\n if (!result.cancelled) {\n handleScan(result.text)\n }\n },\n // @ts-expect-error ???\n (error) => {\n setError(\n new Error(\n `An error has occurred: \"${error}\". Please click \"Cancel\" below to try again. If the problem persists, please contact support.`,\n ),\n )\n },\n {\n showFlipCameraButton: true,\n showTorchButton: true,\n },\n )\n } else {\n startBarcodeScanner()\n }\n }, [handleScan, startBarcodeScanner])\n\n const { isLookingUp } = React.useContext(LookupNotificationContext)\n const isDisplayingValidationMessage =\n (isDirty || displayValidationMessage) && !!validationMessage && !isLookingUp\n\n const text = typeof value === 'string' ? value : ''\n return (\n <div className=\"cypress-barcode-scanner-element\">\n <FormElementLabelContainer\n className=\"ob-barcode-scanner\"\n element={element}\n id={id}\n required={element.required}\n >\n {error && (\n <figure className=\"ob-figure\">\n <div className=\"figure-content has-text-centered\">\n <div>\n <h4 className=\"title is-4\">Whoops...</h4>\n <p>{error.message}</p>\n </div>\n </div>\n </figure>\n )}\n\n {isCameraOpen ? (\n <BarcodeScannerSupported\n id={`${id}==BARCODE_SCANNER`}\n restrictedBarcodeTypes={\n element.restrictBarcodeTypes\n ? element.restrictedBarcodeTypes\n : undefined\n }\n onScan={handleScan}\n onClose={stopBarcodeScanner}\n aria-describedby={ariaDescribedby}\n />\n ) : (\n <div>\n <div className=\"field has-addons\">\n <div className=\"control is-expanded has-icons-right\">\n <input\n type=\"text\"\n placeholder={element.placeholderValue}\n id={id}\n name={element.name}\n className=\"input ob-input cypress-barcode-scanner-control has-margin-bottom-8\"\n value={text}\n onChange={(e) =>\n onChange(element, {\n value: e.target.value || undefined,\n })\n }\n required={element.required}\n disabled={element.readOnly}\n onBlur={setIsDirty}\n aria-describedby={ariaDescribedby}\n autoComplete={autocompleteAttributes}\n aria-required={element.required}\n />\n <span className=\"ob-input-icon icon is-small is-right\">\n <MaterialIcon className=\"is-size-5\">\n document_scanner\n </MaterialIcon>\n </span>\n </div>\n {!!element.readOnly && !!value && (\n <div className=\"control\">\n <CopyToClipboardButton\n className=\"button is-input-addon copy-button cypress-copy-to-clipboard-button\"\n text={text}\n />\n </div>\n )}\n <LookupButton\n isInputButton\n value={value}\n validationMessage={validationMessage}\n lookupButtonConfig={element.lookupButton}\n overrideRequiredMessage={undefined}\n />\n </div>\n\n <button\n type=\"button\"\n className=\"button ob-button ob-button__open is-primary cypress-start-scan-barcode-button\"\n disabled={element.readOnly}\n onClick={openBarcodeScanner}\n >\n Scan Barcode\n </button>\n </div>\n )}\n\n {isDisplayingValidationMessage && (\n <FormElementValidationMessage message={validationMessage} />\n )}\n </FormElementLabelContainer>\n </div>\n )\n}\n\nexport default React.memo(FormElementBarcodeScanner)\n\ntype BarcodeScannerProps = {\n id: string\n restrictedBarcodeTypes: FormTypes.BarcodeScannerElement['restrictedBarcodeTypes']\n onScan: (barcode: string | undefined) => void\n onClose: () => void\n 'aria-describedby'?: string\n}\n\nfunction BarcodeScannerSupported(props: BarcodeScannerProps) {\n const { onClose } = props\n if (!navigator.mediaDevices?.getUserMedia) {\n return (\n <BarcodeScannerFigure onClose={onClose}>\n <BarcodeScannerError\n title=\"Unsupported Device\"\n message=\"Your device does not support accessing your camera.\"\n />\n </BarcodeScannerFigure>\n )\n }\n\n return <BarcodeScannerCameraLoader {...props} />\n}\n\nfunction BarcodeScannerCameraLoader(props: BarcodeScannerProps) {\n const { onClose } = props\n const [state] = useLoadDataState(Html5Qrcode.getCameras)\n switch (state.status) {\n case 'LOADING': {\n return (\n <BarcodeScannerFigure onClose={onClose}>\n <div className=\"figure-content has-text-centered\">\n <OnLoading small />\n </div>\n </BarcodeScannerFigure>\n )\n }\n case 'ERROR': {\n return (\n <BarcodeScannerFigure onClose={onClose}>\n <BarcodeScannerError\n title=\"Whoops...\"\n message={\n state.error.name === 'NotAllowedError'\n ? 'Cannot scan for barcodes without granting the application access to the camera.'\n : state.error.message\n }\n />\n </BarcodeScannerFigure>\n )\n }\n }\n\n if (!state.result.length) {\n return (\n <BarcodeScannerFigure onClose={onClose}>\n <BarcodeScannerError\n title=\"No Cameras Available\"\n message=\"Your device does not have an accessible camera.\"\n />\n </BarcodeScannerFigure>\n )\n }\n\n return <BarcodeScanner {...props} cameraDevices={state.result} />\n}\n\nfunction BarcodeScanner({\n id,\n restrictedBarcodeTypes,\n onScan,\n onClose,\n cameraDevices,\n ...props\n}: BarcodeScannerProps & {\n cameraDevices: CameraDevice[]\n}) {\n const formatsToSupport = React.useMemo(() => {\n return restrictedBarcodeTypes?.reduce<Html5QrcodeSupportedFormats[]>(\n (memo, barcodeType) => {\n const format =\n Html5QrcodeSupportedFormats[\n barcodeType as keyof typeof Html5QrcodeSupportedFormats\n ]\n if (format !== undefined) {\n memo.push(format)\n }\n return memo\n },\n [],\n )\n }, [restrictedBarcodeTypes])\n\n const [scannerState, setScannerState] = React.useState<\n { state: 'loading' } | { state: 'ready' } | { state: 'error'; error: Error }\n >({ state: 'loading' })\n\n React.useEffect(() => {\n setScannerState({ state: 'loading' })\n\n const html5Qrcode = new Html5Qrcode(id, {\n verbose: !!localStorage.getItem('BARCODE_SCANNER_VERBOSE'),\n formatsToSupport: formatsToSupport?.length ? formatsToSupport : undefined,\n })\n\n const backFacingCamera = cameraDevices.find((device) =>\n /back|rear|environment/i.test(device.label),\n )\n const preferredCamera = backFacingCamera ?? cameraDevices[0]\n const scanConfig: Html5QrcodeCameraScanConfig = {\n fps: 20,\n aspectRatio: 1,\n qrbox: (viewfinderWidth, viewfinderHeight) => {\n const size = Math.min(\n 250,\n Math.floor(Math.min(viewfinderWidth, viewfinderHeight) * 0.75),\n )\n return { width: size, height: size }\n },\n }\n\n const onScanSuccess = (decodedText: string, decodedResult: unknown) => {\n console.log('Barcode scanner decoded result:', decodedResult)\n onScan(decodedText)\n }\n const onScanFailure = () => {\n // do nothing and keep scanning\n }\n\n const abortController = new AbortController()\n\n const begin = async () => {\n try {\n // Attempt to start with the back facing camera\n await html5Qrcode.start(\n { deviceId: preferredCamera.id },\n scanConfig,\n onScanSuccess,\n onScanFailure,\n )\n if (abortController.signal.aborted) {\n return\n }\n setScannerState({ state: 'ready' })\n } catch (deviceIdError) {\n if (abortController.signal.aborted) {\n return\n }\n console.warn('Failed to start scanning with deviceId', deviceIdError)\n try {\n // If the back facing camera is not available, try to start in environment mode\n await html5Qrcode.start(\n { facingMode: 'environment' },\n scanConfig,\n onScanSuccess,\n onScanFailure,\n )\n if (abortController.signal.aborted) {\n return\n }\n setScannerState({ state: 'ready' })\n } catch (facingModeError) {\n if (abortController.signal.aborted) {\n return\n }\n console.warn('Failed to start scanning', facingModeError)\n setScannerState({\n state: 'error',\n error:\n facingModeError instanceof Error\n ? facingModeError\n : new Error(String(facingModeError)),\n })\n }\n }\n }\n\n begin()\n\n return () => {\n abortController.abort()\n if (!html5Qrcode.isScanning) {\n return\n }\n try {\n html5Qrcode.stop().catch((error) => {\n console.warn('Failed to stop barcode scanner', error)\n })\n } catch (error) {\n console.warn('Failed to stop barcode scanner', error)\n }\n }\n }, [cameraDevices, formatsToSupport, id, onScan])\n\n return (\n <BarcodeScannerFigure onClose={onClose}>\n {scannerState.state === 'loading' && (\n <div className=\"figure-content-absolute-center\">\n <OnLoading small />\n </div>\n )}\n {scannerState.state === 'error' && (\n <BarcodeScannerError\n title=\"Whoops...\"\n message={scannerState.error.message}\n />\n )}\n <div\n id={id}\n className=\"ob-figure__barcode-scanner\"\n aria-describedby={props['aria-describedby']}\n />\n </BarcodeScannerFigure>\n )\n}\n\nfunction BarcodeScannerFigure({\n onClose,\n children,\n}: {\n onClose: () => void\n children: React.ReactNode\n}) {\n return (\n <div>\n <figure className=\"ob-figure\">{children}</figure>\n <div className=\"buttons ob-buttons\">\n <button\n type=\"button\"\n className=\"button ob-button ob-button__cancel is-light cypress-cancel-scan-barcode-button\"\n onClick={onClose}\n >\n Cancel\n </button>\n </div>\n </div>\n )\n}\n\nfunction BarcodeScannerError({\n title,\n message,\n}: {\n title: string\n message: string\n}) {\n return (\n <div className=\"figure-content has-text-centered\" role=\"alert\">\n <div>\n <h4 className=\"title is-4\">{title}</h4>\n <p className=\"has-margin-bottom-6\">{message}</p>\n <p>\n Please click <b>Cancel</b> below and type in the barcode value\n manually.\n </p>\n </div>\n </div>\n )\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { authService } from '../apps';
1
+ import { mfaService } from '../apps';
2
2
  /**
3
3
  * This function is a react hook to help writing your own login screen.
4
4
  *
@@ -35,6 +35,8 @@ import { authService } from '../apps';
35
35
  * mfaMethod,
36
36
  * isSubmittingMfaCode,
37
37
  * submitMfaCode,
38
+ * isResendingMfaCode,
39
+ * resendMfaCode,
38
40
  * // Login Errors
39
41
  * loginError,
40
42
  * clearLoginError,
@@ -433,7 +435,7 @@ export interface UseLoginValue {
433
435
  isInvalid: boolean;
434
436
  };
435
437
  /** The MFA method the user must complete to finish signing in, if available. */
436
- mfaMethod: authService.MfaMethod | null;
438
+ mfaMethod: mfaService.MfaMethod | null;
437
439
  /** `true` while processing `submitMfaCode()`. */
438
440
  isSubmittingMfaCode: boolean;
439
441
  /**
@@ -441,4 +443,16 @@ export interface UseLoginValue {
441
443
  * Will call `onLogin()` if successful, otherwise will set `loginError`.
442
444
  */
443
445
  submitMfaCode: () => void;
446
+ /** `true` while processing `resendMfaCode()`, when available. */
447
+ isResendingMfaCode: boolean;
448
+ /**
449
+ * Request a new one-time verification code during sign-in. Defined when the
450
+ * active MFA step supports resending a code (e.g. SMS).
451
+ */
452
+ resendMfaCode?: () => void;
453
+ /**
454
+ * Timestamp when the current MFA code was sent. Use with `useResendCoolDown()`
455
+ * to enforce a resend cooldown.
456
+ */
457
+ mfaCodeSentAt?: number;
444
458
  }
@@ -38,6 +38,8 @@ import useBooleanState from './useBooleanState';
38
38
  * mfaMethod,
39
39
  * isSubmittingMfaCode,
40
40
  * submitMfaCode,
41
+ * isResendingMfaCode,
42
+ * resendMfaCode,
41
43
  * // Login Errors
42
44
  * loginError,
43
45
  * clearLoginError,
@@ -310,7 +312,7 @@ import useBooleanState from './useBooleanState';
310
312
  * @group Hooks
311
313
  */
312
314
  export default function useLogin({ username, password, newPassword, newPasswordConfirmed, code, formsAppId, }) {
313
- var _a, _b;
315
+ var _a, _b, _c;
314
316
  const isMounted = useIsMounted();
315
317
  // Validation
316
318
  const usernameValidation = React.useMemo(() => {
@@ -351,12 +353,14 @@ export default function useLogin({ username, password, newPassword, newPasswordC
351
353
  };
352
354
  }, [newPassword, newPasswordConfirmed]);
353
355
  // Login, Reset Password, MFA
354
- const [{ isResettingTemporaryPassword, isLoggingIn, loginError, loginAttemptResponse, isSubmittingMfaCode, }, setLoginState,] = React.useState({
356
+ const [{ isResettingTemporaryPassword, isLoggingIn, loginError, loginAttemptResponse, isSubmittingMfaCode, isResendingMfaCode, mfaCodeSentAt, }, setLoginState,] = React.useState({
355
357
  isResettingTemporaryPassword: false,
356
358
  isLoggingIn: false,
357
359
  loginError: null,
358
360
  loginAttemptResponse: undefined,
359
361
  isSubmittingMfaCode: false,
362
+ isResendingMfaCode: false,
363
+ mfaCodeSentAt: undefined,
360
364
  });
361
365
  const clearLoginError = React.useCallback(() => setLoginState((current) => ({
362
366
  ...current,
@@ -389,6 +393,9 @@ export default function useLogin({ username, password, newPassword, newPasswordC
389
393
  ...currentState,
390
394
  isLoggingIn: false,
391
395
  loginAttemptResponse: newLoginAttemptResponse,
396
+ mfaCodeSentAt: newLoginAttemptResponse.mfa
397
+ ? Date.now()
398
+ : undefined,
392
399
  }));
393
400
  }
394
401
  }
@@ -440,6 +447,9 @@ export default function useLogin({ username, password, newPassword, newPasswordC
440
447
  ...currentState,
441
448
  isResettingTemporaryPassword: false,
442
449
  loginAttemptResponse: resetPasswordResponse,
450
+ mfaCodeSentAt: resetPasswordResponse.mfa
451
+ ? Date.now()
452
+ : undefined,
443
453
  }));
444
454
  }
445
455
  }
@@ -478,6 +488,9 @@ export default function useLogin({ username, password, newPassword, newPasswordC
478
488
  ...currentState,
479
489
  isSubmittingMfaCode: false,
480
490
  loginAttemptResponse: mfaResponse,
491
+ mfaCodeSentAt: mfaResponse.mfa
492
+ ? currentState.mfaCodeSentAt
493
+ : undefined,
481
494
  }));
482
495
  }
483
496
  }
@@ -492,6 +505,40 @@ export default function useLogin({ username, password, newPassword, newPasswordC
492
505
  }
493
506
  }
494
507
  }, [code, isMounted, (_a = loginAttemptResponse === null || loginAttemptResponse === void 0 ? void 0 : loginAttemptResponse.mfa) === null || _a === void 0 ? void 0 : _a.codeCallback]);
508
+ const resendMfaCodeCallback = (_b = loginAttemptResponse === null || loginAttemptResponse === void 0 ? void 0 : loginAttemptResponse.mfa) === null || _b === void 0 ? void 0 : _b.resendCodeCallback;
509
+ const resendMfaCode = React.useMemo(() => {
510
+ if (!resendMfaCodeCallback) {
511
+ return;
512
+ }
513
+ return async () => {
514
+ setLoginState((current) => ({
515
+ ...current,
516
+ isResendingMfaCode: true,
517
+ loginError: null,
518
+ }));
519
+ try {
520
+ const mfaResponse = await resendMfaCodeCallback();
521
+ if (isMounted.current) {
522
+ setLoginState((currentState) => ({
523
+ ...currentState,
524
+ isResendingMfaCode: false,
525
+ loginAttemptResponse: mfaResponse,
526
+ mfaCodeSentAt: Date.now(),
527
+ }));
528
+ }
529
+ }
530
+ catch (error) {
531
+ Sentry.captureException(error);
532
+ if (isMounted.current) {
533
+ setLoginState((current) => ({
534
+ ...current,
535
+ isResendingMfaCode: false,
536
+ loginError: error,
537
+ }));
538
+ }
539
+ }
540
+ };
541
+ }, [isMounted, resendMfaCodeCallback]);
495
542
  // Forgot Password
496
543
  const [isShowingForgotPassword, showForgotPassword, hideForgotPassword] = useBooleanState(false);
497
544
  const [{ resetForgottenPasswordCallback, isSendingForgotPasswordCode, isResettingForgottenPassword, forgotPasswordError, }, setForgotPasswordState,] = React.useState({
@@ -618,9 +665,12 @@ export default function useLogin({ username, password, newPassword, newPasswordC
618
665
  isResettingTemporaryPassword,
619
666
  resetTemporaryPassword,
620
667
  // MFA Code
621
- mfaMethod: ((_b = loginAttemptResponse === null || loginAttemptResponse === void 0 ? void 0 : loginAttemptResponse.mfa) === null || _b === void 0 ? void 0 : _b.method) || null,
668
+ mfaMethod: ((_c = loginAttemptResponse === null || loginAttemptResponse === void 0 ? void 0 : loginAttemptResponse.mfa) === null || _c === void 0 ? void 0 : _c.method) || null,
622
669
  isSubmittingMfaCode,
623
670
  submitMfaCode,
671
+ isResendingMfaCode,
672
+ resendMfaCode,
673
+ mfaCodeSentAt,
624
674
  // Showing Forgot Password
625
675
  isShowingForgotPassword,
626
676
  showForgotPassword,
@@ -1 +1 @@
1
- {"version":3,"file":"useLogin.js","sourceRoot":"","sources":["../../src/hooks/useLogin.ts"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport { authService, Sentry } from '../apps'\n\nimport useIsMounted from './useIsMounted'\nimport useBooleanState from './useBooleanState'\n\n/**\n * This function is a react hook to help writing your own login screen.\n *\n * ## Example\n *\n * ```jsx\n * import * as React from 'react'\n * import { useHistory } from 'react-router-dom'\n * import { useLogin } from '@oneblink/apps-react'\n *\n * function App() {\n * const history = useHistory()\n *\n * const [username, setUsername] = React.useState('')\n * const [password, setPassword] = React.useState('')\n * const [newPasswordConfirmed, setNewPasswordConfirmed] = React.useState('')\n * const [newPassword, setNewPassword] = React.useState('')\n * const [code, setCode] = React.useState('')\n *\n * const onLogin = React.useCallback(() => {\n * history.push('/')\n * }, [history])\n *\n * const {\n * // Login\n * loginWithGoogle,\n * loginWithUsernamePassword,\n * isLoggingIn,\n * // Reset Temp Password\n * isPasswordTemporary,\n * isResettingTemporaryPassword,\n * resetTemporaryPassword,\n * // MFA Password\n * mfaMethod,\n * isSubmittingMfaCode,\n * submitMfaCode,\n * // Login Errors\n * loginError,\n * clearLoginError,\n * // Showing Forgot Password\n * isShowingForgotPassword,\n * showForgotPassword,\n * hideForgotPassword,\n * // Sending Forgot Password Code\n * isSendingForgotPasswordCode,\n * sendForgotPasswordCode,\n * // Resetting Forgotten Password\n * hasSentForgotPasswordCode,\n * isResettingForgottenPassword,\n * resetForgottenPassword,\n * // Forgot Password Errors\n * forgotPasswordError,\n * clearForgotPasswordError,\n * // Validation\n * usernameValidation,\n * passwordValidation,\n * codeValidation,\n * newPasswordValidation,\n * newPasswordConfirmedValidation,\n * } = useLogin({\n * username,\n * password,\n * newPassword,\n * newPasswordConfirmed,\n * code,\n * onLogin,\n * })\n *\n * if (hasSentForgotPasswordCode) {\n * return (\n * <form\n * onSubmit={(e) => {\n * e.preventDefault()\n * resetForgottenPassword()\n * }}\n * >\n * <p>We have sent you a password reset code via email. Enter it below to reset your password.</p>\n *\n * <input\n * type=\"password\"\n * placeholder=\"Code\"\n * value={code}\n * onChange={(e) => setCode(e.target.value)}\n * />\n *\n * <input\n * type=\"password\"\n * placeholder=\"New Password\"\n * value={newPassword}\n * onChange={(e) => setNewPassword(e.target.value)}\n * />\n *\n * <input\n * type=\"password\"\n * placeholder=\"Confirm Password\"\n * value={newPassword}\n * onChange={(e) => setNewPasswordConfirmed(e.target.value)}\n * />\n *\n * <button\n * type=\"submit\"\n * disabled={isResettingForgottenPassword || codeValidation.isInvalid || newPasswordValidation.isInvalid || newPasswordConfirmedValidation.isInvalid}\n * >\n * Change Password\n * </button>\n *\n * <p>Password Requirements</p>\n * <p>Contains a lowercase letter: {validation.hasLowercaseLetter ? 'Yes' : 'No'}</p>\n * <p>Contains an upper case letter: {validation.hasUpperCaseLetter ? 'Yes' : 'No'}</p>\n * <p>Contains a number: {validation.hasNumber ? 'Yes' : 'No'}</p>\n * <p>Contains a special character: {validation.hasSpecialCharacter ? 'Yes' : 'No'}</p>\n * <p>Contains at least 8 characters: {validation.hasMinLength ? 'Yes' : 'No'}</p>\n *\n * {forgotPasswordError && (\n * <p>{forgotPasswordError.message}</p>\n * <button type=\"button\" onClick={clearForgotPasswordError}>Clear Error</button>\n * )}\n * </form>\n * )\n * }\n *\n * if (isShowingForgotPassword) {\n * return (\n * <form\n * onSubmit={(e) => {\n * e.preventDefault()\n * sendForgotPasswordCode()\n * }}\n * >\n * <p>Enter your email address and we will send you a code to reset your password.</p>\n *\n * <input\n * type=\"email\"\n * placeholder=\"Email Address\"\n * value={username}\n * onChange={(e) => setUsername(e.target.value)}\n * />\n *\n * <p>\n * <a onClick={hideForgotPassword}>Remembered your password?</a>\n * </p>\n *\n * <button\n * type=\"submit\"\n * disabled={isSendingForgotPasswordCode || usernameValidation.isInvalid}\n * >\n * Reset Password\n * </button>\n *\n * {forgotPasswordError && (\n * <p>{forgotPasswordError.message}</p>\n * <button type=\"button\" onClick={clearForgotPasswordError}>Clear Error</button>\n * )}\n * </form>\n * )\n * }\n *\n * if (isPasswordTemporary) {\n * return (\n * <form\n * onSubmit={(e) => {\n * e.preventDefault()\n * resetTemporaryPassword()\n * }}\n * >\n * <p>The password you entered was only temporary and must be reset for security purposes. Please enter your new password below to continue.</p>\n *\n * <input\n * type=\"password\"\n * placeholder=\"New Password\"\n * value={newPassword}\n * onChange={(e) => setNewPassword(e.target.value)}\n * />\n *\n * <input\n * type=\"password\"\n * placeholder=\"Confirm Password\"\n * value={newPassword}\n * onChange={(e) => setNewPasswordConfirmed(e.target.value)}\n * />\n *\n * <button\n * type=\"submit\"\n * disabled={isResettingTemporaryPassword || newPasswordValidation.isInvalid || newPasswordConfirmedValidation.isInvalid}\n * >\n * Change Password &amp; Sign In\n * </button>\n *\n * <p>Password Requirements</p>\n * <p>Contains a lowercase letter: {validation.hasLowercaseLetter ? 'Yes' : 'No'}</p>\n * <p>Contains an upper case letter: {validation.hasUpperCaseLetter ? 'Yes' : 'No'}</p>\n * <p>Contains a number: {validation.hasNumber ? 'Yes' : 'No'}</p>\n * <p>Contains a special character: {validation.hasSpecialCharacter ? 'Yes' : 'No'}</p>\n * <p>Contains at least 8 characters: {validation.hasMinLength ? 'Yes' : 'No'}</p>\n *\n * {loginError && (\n * <p>{loginError.message}</p>\n * <button type=\"button\" onClick={clearLoginError}>Clear Error</button>\n * )}\n * </form>\n * )\n * }\n *\n * if (mfaMethod) {\n * return (\n * <form\n * onSubmit={(e) => {\n * e.preventDefault()\n * submitMfaCode()\n * }}\n * >\n * <p>\n * {mfaMethod === 'email'\n * ? 'Enter the verification code sent to your email address.'\n * : mfaMethod === 'sms'\n * ? 'Enter the verification code sent to your phone number.'\n * : mfaMethod === 'authenticator'\n * ? 'Enter the 6-digit code found in your authenticator app.'\n * : 'Enter your verification code.'}\n * </p>\n *\n * <input\n * type=\"password\"\n * placeholder=\"Code\"\n * value={code}\n * onChange={(e) => setCode(e.target.value)}\n * />\n *\n * <button\n * type=\"submit\"\n * disabled={isSubmittingMfaCode || codeValidation.isInvalid}\n * >\n * Sign In\n * </button>\n *\n * {loginError && (\n * <p>{loginError.message}</p>\n * <button type=\"button\" onClick={clearLoginError}>Clear Error</button>\n * )}\n * </form>\n * )\n * }\n *\n * return (\n * <form\n * onSubmit={(e) => {\n * e.preventDefault()\n * loginWithUsernamePassword()\n * }}\n * >\n * <p>Sign in with your email address and password.</p>\n * <input\n * type=\"email\"\n * placeholder=\"Email Address\"\n * value={username}\n * onChange={(e) => setUsername(e.target.value)}\n * />\n *\n * <input\n * type=\"password\"\n * placeholder=\"New Password\"\n * value={newPassword}\n * onChange={(e) => setNewPassword(e.target.value)}\n * />\n *\n * <p>\n * <a onClick={showForgotPassword}>Forgot your password?</a>\n * </p>\n *\n * <button\n * type=\"submit\"\n * disabled={isLoggingIn || usernameValidation.isInvalid || passwordValidation.isInvalid}\n * >\n * {children}\n * </button>\n *\n * <p>or</p>\n *\n * <button\n * type=\"button\"\n * onClick={loginWithGoogle}\n * >\n * <img\n * alt=\"Google\"\n * src=\"google-sign-in.png\"\n * />\n * <span>Sign in with Google</span>\n * </button>\n *\n * {loginError && (\n * <p>{loginError.message}</p>\n * <button type=\"button\" onClick={clearLoginError}>Clear Error</button>\n * )}\n * </form>\n * )\n * }\n *\n * const root = document.getElementById('root')\n * if (root) {\n * ReactDOM.render(<App />, root)\n * }\n * ```\n *\n * @param options\n * @returns\n * @group Hooks\n */\nexport default function useLogin({\n username,\n password,\n newPassword,\n newPasswordConfirmed,\n code,\n formsAppId,\n}: {\n /** The email address entered by the user. */\n username: string\n /** The password entered by the user. */\n password: string\n /** The new password entered by the user if changing their password. */\n newPassword: string\n /**\n * The new password repeated by the user if changing their password to ensure\n * they do type it in wrong.\n */\n newPasswordConfirmed: string\n /**\n * The code sent to the user after requesting a password reset by starting the\n * \"forgot password\" process.\n */\n code: string\n /** The identifier for the current forms app */\n formsAppId?: number\n}): UseLoginValue {\n const isMounted = useIsMounted()\n\n // Validation\n const usernameValidation = React.useMemo(() => {\n return {\n isInvalid: !username.trim(),\n }\n }, [username])\n\n const passwordValidation = React.useMemo(() => {\n return {\n isInvalid: !password.trim(),\n }\n }, [password])\n\n const codeValidation = React.useMemo(() => {\n return {\n isInvalid: !code.trim(),\n }\n }, [code])\n\n const newPasswordValidation = React.useMemo(() => {\n const validation = {\n hasLowercaseLetter: /[a-z]+/.test(newPassword),\n hasUpperCaseLetter: /[A-Z]+/.test(newPassword),\n hasNumber: /\\d+/.test(newPassword),\n hasSpecialCharacter: /[\\^$*.[\\]{}()?|\\-\"!@#%&/,><':;|_~`]+/.test(\n newPassword,\n ),\n hasMinLength: newPassword.length >= 8,\n isInvalid: true,\n }\n validation.isInvalid =\n !validation.hasLowercaseLetter ||\n !validation.hasUpperCaseLetter ||\n !validation.hasNumber ||\n !validation.hasSpecialCharacter ||\n !validation.hasMinLength\n return validation\n }, [newPassword])\n\n const newPasswordConfirmedValidation = React.useMemo(() => {\n return {\n isInvalid: newPassword !== newPasswordConfirmed,\n }\n }, [newPassword, newPasswordConfirmed])\n\n // Login, Reset Password, MFA\n const [\n {\n isResettingTemporaryPassword,\n isLoggingIn,\n loginError,\n loginAttemptResponse,\n isSubmittingMfaCode,\n },\n setLoginState,\n ] = React.useState<{\n isResettingTemporaryPassword: boolean\n isLoggingIn: boolean\n loginError: null | Error\n loginAttemptResponse: authService.LoginAttemptResponse | undefined\n isSubmittingMfaCode: boolean\n }>({\n isResettingTemporaryPassword: false,\n isLoggingIn: false,\n loginError: null,\n loginAttemptResponse: undefined,\n isSubmittingMfaCode: false,\n })\n const clearLoginError = React.useCallback(\n () =>\n setLoginState((current) => ({\n ...current,\n loginError: null,\n })),\n [],\n )\n const loginWithUsernamePassword = React.useCallback(async () => {\n if (usernameValidation.isInvalid) {\n setLoginState((current) => ({\n ...current,\n loginError: new Error('Please enter a valid email address'),\n }))\n return\n }\n if (passwordValidation.isInvalid) {\n setLoginState((current) => ({\n ...current,\n loginError: new Error('Please enter a valid password'),\n }))\n return\n }\n\n setLoginState((currentState) => ({\n ...currentState,\n isLoggingIn: true,\n loginError: null,\n }))\n\n try {\n const newLoginAttemptResponse = await authService.loginUsernamePassword(\n username,\n password,\n )\n if (isMounted.current) {\n setLoginState((currentState) => ({\n ...currentState,\n isLoggingIn: false,\n loginAttemptResponse: newLoginAttemptResponse,\n }))\n }\n } catch (error) {\n Sentry.captureException(error)\n if (isMounted.current) {\n setLoginState((currentState) => ({\n ...currentState,\n isLoggingIn: false,\n loginError: error as Error,\n }))\n }\n }\n }, [\n isMounted,\n password,\n passwordValidation.isInvalid,\n username,\n usernameValidation.isInvalid,\n ])\n\n const resetTemporaryPassword = React.useCallback(async () => {\n const resetTemporaryPasswordCallback =\n loginAttemptResponse?.resetPasswordCallback\n if (!resetTemporaryPasswordCallback) {\n return\n }\n\n if (newPasswordValidation.isInvalid) {\n setLoginState((current) => ({\n ...current,\n loginError: new Error('Please enter a valid password'),\n }))\n return\n }\n\n if (newPasswordConfirmedValidation.isInvalid) {\n setLoginState((current) => ({\n ...current,\n loginError: new Error('Please confirm your new password'),\n }))\n return\n }\n\n setLoginState((current) => ({\n ...current,\n isResettingPassword: true,\n loginError: null,\n }))\n\n try {\n const resetPasswordResponse =\n await resetTemporaryPasswordCallback(newPassword)\n if (isMounted.current) {\n setLoginState((currentState) => ({\n ...currentState,\n isResettingTemporaryPassword: false,\n loginAttemptResponse: resetPasswordResponse,\n }))\n }\n } catch (error) {\n Sentry.captureException(error)\n if (isMounted.current) {\n setLoginState((current) => ({\n ...current,\n isResettingPassword: false,\n loginError: error as Error,\n }))\n }\n }\n }, [\n isMounted,\n loginAttemptResponse?.resetPasswordCallback,\n newPassword,\n newPasswordConfirmedValidation.isInvalid,\n newPasswordValidation.isInvalid,\n ])\n\n const submitMfaCode = React.useCallback(async () => {\n const mfaCodeCallback = loginAttemptResponse?.mfa?.codeCallback\n if (!mfaCodeCallback) {\n return\n }\n\n setLoginState((current) => ({\n ...current,\n isSubmittingMfaCode: true,\n loginError: null,\n }))\n\n try {\n const mfaResponse = await mfaCodeCallback(code)\n if (isMounted.current) {\n setLoginState((currentState) => ({\n ...currentState,\n isSubmittingMfaCode: false,\n loginAttemptResponse: mfaResponse,\n }))\n }\n } catch (error) {\n Sentry.captureException(error)\n if (isMounted.current) {\n setLoginState((current) => ({\n ...current,\n isSubmittingMfaCode: false,\n loginError: error as Error,\n }))\n }\n }\n }, [code, isMounted, loginAttemptResponse?.mfa?.codeCallback])\n\n // Forgot Password\n const [isShowingForgotPassword, showForgotPassword, hideForgotPassword] =\n useBooleanState(false)\n const [\n {\n resetForgottenPasswordCallback,\n isSendingForgotPasswordCode,\n isResettingForgottenPassword,\n forgotPasswordError,\n },\n setForgotPasswordState,\n ] = React.useState<{\n isSendingForgotPasswordCode: boolean\n forgotPasswordError: null | Error\n resetForgottenPasswordCallback:\n | null\n | ((code: string, newPassword: string) => void)\n isResettingForgottenPassword: boolean\n }>({\n isSendingForgotPasswordCode: false,\n forgotPasswordError: null,\n resetForgottenPasswordCallback: null,\n isResettingForgottenPassword: false,\n })\n const clearForgotPasswordError = React.useCallback(\n () =>\n setForgotPasswordState((current) => ({\n ...current,\n forgotPasswordError: null,\n })),\n [],\n )\n const sendForgotPasswordCode = React.useCallback(async () => {\n if (usernameValidation.isInvalid) {\n setForgotPasswordState((current) => ({\n ...current,\n forgotPasswordError: new Error('Please enter a valid email address'),\n }))\n return\n }\n\n setForgotPasswordState({\n isSendingForgotPasswordCode: true,\n resetForgottenPasswordCallback: null,\n forgotPasswordError: null,\n isResettingForgottenPassword: false,\n })\n\n try {\n const newResetForgottenPasswordCallback =\n await authService.forgotPassword(username, formsAppId)\n if (isMounted.current) {\n setForgotPasswordState({\n isSendingForgotPasswordCode: false,\n resetForgottenPasswordCallback: newResetForgottenPasswordCallback,\n forgotPasswordError: null,\n isResettingForgottenPassword: false,\n })\n }\n } catch (error) {\n Sentry.captureException(error)\n if (isMounted.current) {\n setForgotPasswordState({\n isSendingForgotPasswordCode: false,\n resetForgottenPasswordCallback: null,\n forgotPasswordError: error as Error,\n isResettingForgottenPassword: false,\n })\n }\n }\n }, [isMounted, username, usernameValidation.isInvalid, formsAppId])\n\n const resetForgottenPassword = React.useCallback(async () => {\n if (!resetForgottenPasswordCallback) {\n return\n }\n\n if (codeValidation.isInvalid) {\n setForgotPasswordState((current) => ({\n ...current,\n forgotPasswordError: new Error(\n 'Please enter the code that was sent to your email address',\n ),\n }))\n }\n if (newPasswordValidation.isInvalid) {\n setForgotPasswordState((current) => ({\n ...current,\n forgotPasswordError: new Error('Please enter a valid password'),\n }))\n return\n }\n if (newPasswordConfirmedValidation.isInvalid) {\n setForgotPasswordState((current) => ({\n ...current,\n forgotPasswordError: new Error('Please confirm your new password'),\n }))\n return\n }\n\n setForgotPasswordState((current) => ({\n ...current,\n isChangingPassword: true,\n forgotPasswordError: null,\n }))\n\n try {\n await resetForgottenPasswordCallback(code, newPassword)\n if (isMounted.current) {\n setForgotPasswordState({\n isSendingForgotPasswordCode: false,\n resetForgottenPasswordCallback: null,\n forgotPasswordError: null,\n isResettingForgottenPassword: false,\n })\n hideForgotPassword()\n }\n } catch (error) {\n Sentry.captureException(error)\n if (isMounted.current) {\n setForgotPasswordState((current) => ({\n ...current,\n isChangingPassword: false,\n forgotPasswordError: error as Error,\n }))\n }\n }\n }, [\n resetForgottenPasswordCallback,\n codeValidation.isInvalid,\n newPasswordValidation.isInvalid,\n newPasswordConfirmedValidation.isInvalid,\n code,\n newPassword,\n isMounted,\n hideForgotPassword,\n ])\n\n const loginWithGoogle = React.useCallback(() => {\n authService.loginHostedUI('Google')\n }, [])\n\n return {\n // Login\n /** Open redirect user to the Google sign in */\n loginWithGoogle,\n loginWithUsernamePassword,\n isLoggingIn,\n loginError,\n clearLoginError,\n // Reset Temp Password\n isPasswordTemporary: !!loginAttemptResponse?.resetPasswordCallback,\n isResettingTemporaryPassword,\n resetTemporaryPassword,\n // MFA Code\n mfaMethod: loginAttemptResponse?.mfa?.method || null,\n isSubmittingMfaCode,\n submitMfaCode,\n // Showing Forgot Password\n isShowingForgotPassword,\n showForgotPassword,\n hideForgotPassword,\n forgotPasswordError,\n clearForgotPasswordError,\n // Sending Forgot Password Code\n isSendingForgotPasswordCode,\n sendForgotPasswordCode,\n // Resetting Forgotten Password\n hasSentForgotPasswordCode: !!resetForgottenPasswordCallback,\n isResettingForgottenPassword,\n resetForgottenPassword,\n // Validation\n usernameValidation,\n passwordValidation,\n codeValidation,\n newPasswordValidation,\n newPasswordConfirmedValidation,\n }\n}\n\nexport interface UseLoginValue {\n /** Open redirect user to the Google sign-in page. */\n loginWithGoogle: () => void\n /**\n * Attempt to use the `username` and `password` arguments to create a session.\n * Will call `onLogin()` if successful, otherwise will set `loginError`.\n */\n loginWithUsernamePassword: () => void\n /** `true` while processing `loginWithUsernamePassword()`. */\n isLoggingIn: boolean\n /**\n * `true` if the user logged in using a temporary password. Prompt the user\n * for a new password and call `resetTemporaryPassword()`.\n */\n isPasswordTemporary: boolean\n /**\n * Attempt to use `newPassword` and `newPasswordConfirmed` arguments to reset\n * the user's password and create a session. Will call `onLogin()` if\n * successful, otherwise will set `loginError`.\n */\n resetTemporaryPassword: () => void\n /**\n * Set if an error occurs while processing `loginWithUsernamePassword()` or\n * `resetTemporaryPassword()`.\n */\n loginError: Error | null\n /** Set `loginError` back to `null`. */\n clearLoginError: () => void\n /** `true` while processing `resetTemporaryPassword()`. */\n isResettingTemporaryPassword: boolean\n /** `true` when showing the forgot password flow. */\n isShowingForgotPassword: boolean\n /** Set `isShowingForgotPassword` to `true`. */\n showForgotPassword: () => void\n /** Set `isShowingForgotPassword` to `false`. */\n hideForgotPassword: () => void\n /**\n * Attempt to use the `username` argument to start the forgot password\n * process. This will send the user an email with a code to enter. A failed\n * request will set `forgotPasswordError`.\n */\n sendForgotPasswordCode: () => void\n /** `true` while processing `sendForgotPasswordCode()`. */\n isSendingForgotPasswordCode: boolean\n /** `true` if the forgot password code has been successfully sent to the user. */\n hasSentForgotPasswordCode: boolean\n /**\n * Attempt to use the `code`, `newPassword`, and `newPasswordConfirmed`\n * arguments to reset the user's password. A failed request will set\n * `forgotPasswordError`.\n */\n resetForgottenPassword: () => void\n /** `true` while processing `resetForgottenPassword()`. */\n isResettingForgottenPassword: boolean\n /**\n * Set if an error occurs while processing `sendForgotPasswordCode()` or\n * `resetForgottenPassword()`.\n */\n forgotPasswordError: Error | null\n /** Set `forgotPasswordError` back to `null`. */\n clearForgotPasswordError: () => void\n usernameValidation: {\n /** `true` if the `username` argument is invalid. */\n isInvalid: boolean\n }\n passwordValidation: {\n /** `true` if the `password` argument is invalid. */\n isInvalid: boolean\n }\n codeValidation: {\n /** `true` if the `code` argument is invalid. */\n isInvalid: boolean\n }\n newPasswordValidation: {\n /** `true` if the `newPassword` argument is invalid. */\n isInvalid: boolean\n /**\n * `true` if the `newPassword` argument has a lowercase letter (required to\n * be valid).\n */\n hasLowercaseLetter: boolean\n /**\n * `true` if the `newPassword` argument has an uppercase letter (required to\n * be valid).\n */\n hasUpperCaseLetter: boolean\n /** `true` if the `newPassword` argument has a number (required to be valid). */\n hasNumber: boolean\n /**\n * `true` if the `newPassword` argument has a special character (required to\n * be valid).\n */\n hasSpecialCharacter: boolean\n /**\n * `true` if the `newPassword` argument has at least the minimum number of\n * characters (required to be valid).\n */\n hasMinLength: boolean\n }\n newPasswordConfirmedValidation: {\n /**\n * `true` if the `newPasswordConfirmed` argument is invalid (must match the\n * `newPassword` argument).\n */\n isInvalid: boolean\n }\n /** The MFA method the user must complete to finish signing in, if available. */\n mfaMethod: authService.MfaMethod | null\n /** `true` while processing `submitMfaCode()`. */\n isSubmittingMfaCode: boolean\n /**\n * Attempt to use `code` argument to submit the MFA code and create a session.\n * Will call `onLogin()` if successful, otherwise will set `loginError`.\n */\n submitMfaCode: () => void\n}\n"]}
1
+ {"version":3,"file":"useLogin.js","sourceRoot":"","sources":["../../src/hooks/useLogin.ts"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport { authService, mfaService, Sentry } from '../apps'\n\nimport useIsMounted from './useIsMounted'\nimport useBooleanState from './useBooleanState'\n\n/**\n * This function is a react hook to help writing your own login screen.\n *\n * ## Example\n *\n * ```jsx\n * import * as React from 'react'\n * import { useHistory } from 'react-router-dom'\n * import { useLogin } from '@oneblink/apps-react'\n *\n * function App() {\n * const history = useHistory()\n *\n * const [username, setUsername] = React.useState('')\n * const [password, setPassword] = React.useState('')\n * const [newPasswordConfirmed, setNewPasswordConfirmed] = React.useState('')\n * const [newPassword, setNewPassword] = React.useState('')\n * const [code, setCode] = React.useState('')\n *\n * const onLogin = React.useCallback(() => {\n * history.push('/')\n * }, [history])\n *\n * const {\n * // Login\n * loginWithGoogle,\n * loginWithUsernamePassword,\n * isLoggingIn,\n * // Reset Temp Password\n * isPasswordTemporary,\n * isResettingTemporaryPassword,\n * resetTemporaryPassword,\n * // MFA Password\n * mfaMethod,\n * isSubmittingMfaCode,\n * submitMfaCode,\n * isResendingMfaCode,\n * resendMfaCode,\n * // Login Errors\n * loginError,\n * clearLoginError,\n * // Showing Forgot Password\n * isShowingForgotPassword,\n * showForgotPassword,\n * hideForgotPassword,\n * // Sending Forgot Password Code\n * isSendingForgotPasswordCode,\n * sendForgotPasswordCode,\n * // Resetting Forgotten Password\n * hasSentForgotPasswordCode,\n * isResettingForgottenPassword,\n * resetForgottenPassword,\n * // Forgot Password Errors\n * forgotPasswordError,\n * clearForgotPasswordError,\n * // Validation\n * usernameValidation,\n * passwordValidation,\n * codeValidation,\n * newPasswordValidation,\n * newPasswordConfirmedValidation,\n * } = useLogin({\n * username,\n * password,\n * newPassword,\n * newPasswordConfirmed,\n * code,\n * onLogin,\n * })\n *\n * if (hasSentForgotPasswordCode) {\n * return (\n * <form\n * onSubmit={(e) => {\n * e.preventDefault()\n * resetForgottenPassword()\n * }}\n * >\n * <p>We have sent you a password reset code via email. Enter it below to reset your password.</p>\n *\n * <input\n * type=\"password\"\n * placeholder=\"Code\"\n * value={code}\n * onChange={(e) => setCode(e.target.value)}\n * />\n *\n * <input\n * type=\"password\"\n * placeholder=\"New Password\"\n * value={newPassword}\n * onChange={(e) => setNewPassword(e.target.value)}\n * />\n *\n * <input\n * type=\"password\"\n * placeholder=\"Confirm Password\"\n * value={newPassword}\n * onChange={(e) => setNewPasswordConfirmed(e.target.value)}\n * />\n *\n * <button\n * type=\"submit\"\n * disabled={isResettingForgottenPassword || codeValidation.isInvalid || newPasswordValidation.isInvalid || newPasswordConfirmedValidation.isInvalid}\n * >\n * Change Password\n * </button>\n *\n * <p>Password Requirements</p>\n * <p>Contains a lowercase letter: {validation.hasLowercaseLetter ? 'Yes' : 'No'}</p>\n * <p>Contains an upper case letter: {validation.hasUpperCaseLetter ? 'Yes' : 'No'}</p>\n * <p>Contains a number: {validation.hasNumber ? 'Yes' : 'No'}</p>\n * <p>Contains a special character: {validation.hasSpecialCharacter ? 'Yes' : 'No'}</p>\n * <p>Contains at least 8 characters: {validation.hasMinLength ? 'Yes' : 'No'}</p>\n *\n * {forgotPasswordError && (\n * <p>{forgotPasswordError.message}</p>\n * <button type=\"button\" onClick={clearForgotPasswordError}>Clear Error</button>\n * )}\n * </form>\n * )\n * }\n *\n * if (isShowingForgotPassword) {\n * return (\n * <form\n * onSubmit={(e) => {\n * e.preventDefault()\n * sendForgotPasswordCode()\n * }}\n * >\n * <p>Enter your email address and we will send you a code to reset your password.</p>\n *\n * <input\n * type=\"email\"\n * placeholder=\"Email Address\"\n * value={username}\n * onChange={(e) => setUsername(e.target.value)}\n * />\n *\n * <p>\n * <a onClick={hideForgotPassword}>Remembered your password?</a>\n * </p>\n *\n * <button\n * type=\"submit\"\n * disabled={isSendingForgotPasswordCode || usernameValidation.isInvalid}\n * >\n * Reset Password\n * </button>\n *\n * {forgotPasswordError && (\n * <p>{forgotPasswordError.message}</p>\n * <button type=\"button\" onClick={clearForgotPasswordError}>Clear Error</button>\n * )}\n * </form>\n * )\n * }\n *\n * if (isPasswordTemporary) {\n * return (\n * <form\n * onSubmit={(e) => {\n * e.preventDefault()\n * resetTemporaryPassword()\n * }}\n * >\n * <p>The password you entered was only temporary and must be reset for security purposes. Please enter your new password below to continue.</p>\n *\n * <input\n * type=\"password\"\n * placeholder=\"New Password\"\n * value={newPassword}\n * onChange={(e) => setNewPassword(e.target.value)}\n * />\n *\n * <input\n * type=\"password\"\n * placeholder=\"Confirm Password\"\n * value={newPassword}\n * onChange={(e) => setNewPasswordConfirmed(e.target.value)}\n * />\n *\n * <button\n * type=\"submit\"\n * disabled={isResettingTemporaryPassword || newPasswordValidation.isInvalid || newPasswordConfirmedValidation.isInvalid}\n * >\n * Change Password &amp; Sign In\n * </button>\n *\n * <p>Password Requirements</p>\n * <p>Contains a lowercase letter: {validation.hasLowercaseLetter ? 'Yes' : 'No'}</p>\n * <p>Contains an upper case letter: {validation.hasUpperCaseLetter ? 'Yes' : 'No'}</p>\n * <p>Contains a number: {validation.hasNumber ? 'Yes' : 'No'}</p>\n * <p>Contains a special character: {validation.hasSpecialCharacter ? 'Yes' : 'No'}</p>\n * <p>Contains at least 8 characters: {validation.hasMinLength ? 'Yes' : 'No'}</p>\n *\n * {loginError && (\n * <p>{loginError.message}</p>\n * <button type=\"button\" onClick={clearLoginError}>Clear Error</button>\n * )}\n * </form>\n * )\n * }\n *\n * if (mfaMethod) {\n * return (\n * <form\n * onSubmit={(e) => {\n * e.preventDefault()\n * submitMfaCode()\n * }}\n * >\n * <p>\n * {mfaMethod === 'email'\n * ? 'Enter the verification code sent to your email address.'\n * : mfaMethod === 'sms'\n * ? 'Enter the verification code sent to your phone number.'\n * : mfaMethod === 'authenticator'\n * ? 'Enter the 6-digit code found in your authenticator app.'\n * : 'Enter your verification code.'}\n * </p>\n *\n * <input\n * type=\"password\"\n * placeholder=\"Code\"\n * value={code}\n * onChange={(e) => setCode(e.target.value)}\n * />\n *\n * <button\n * type=\"submit\"\n * disabled={isSubmittingMfaCode || codeValidation.isInvalid}\n * >\n * Sign In\n * </button>\n *\n * {loginError && (\n * <p>{loginError.message}</p>\n * <button type=\"button\" onClick={clearLoginError}>Clear Error</button>\n * )}\n * </form>\n * )\n * }\n *\n * return (\n * <form\n * onSubmit={(e) => {\n * e.preventDefault()\n * loginWithUsernamePassword()\n * }}\n * >\n * <p>Sign in with your email address and password.</p>\n * <input\n * type=\"email\"\n * placeholder=\"Email Address\"\n * value={username}\n * onChange={(e) => setUsername(e.target.value)}\n * />\n *\n * <input\n * type=\"password\"\n * placeholder=\"New Password\"\n * value={newPassword}\n * onChange={(e) => setNewPassword(e.target.value)}\n * />\n *\n * <p>\n * <a onClick={showForgotPassword}>Forgot your password?</a>\n * </p>\n *\n * <button\n * type=\"submit\"\n * disabled={isLoggingIn || usernameValidation.isInvalid || passwordValidation.isInvalid}\n * >\n * {children}\n * </button>\n *\n * <p>or</p>\n *\n * <button\n * type=\"button\"\n * onClick={loginWithGoogle}\n * >\n * <img\n * alt=\"Google\"\n * src=\"google-sign-in.png\"\n * />\n * <span>Sign in with Google</span>\n * </button>\n *\n * {loginError && (\n * <p>{loginError.message}</p>\n * <button type=\"button\" onClick={clearLoginError}>Clear Error</button>\n * )}\n * </form>\n * )\n * }\n *\n * const root = document.getElementById('root')\n * if (root) {\n * ReactDOM.render(<App />, root)\n * }\n * ```\n *\n * @param options\n * @returns\n * @group Hooks\n */\nexport default function useLogin({\n username,\n password,\n newPassword,\n newPasswordConfirmed,\n code,\n formsAppId,\n}: {\n /** The email address entered by the user. */\n username: string\n /** The password entered by the user. */\n password: string\n /** The new password entered by the user if changing their password. */\n newPassword: string\n /**\n * The new password repeated by the user if changing their password to ensure\n * they do type it in wrong.\n */\n newPasswordConfirmed: string\n /**\n * The code sent to the user after requesting a password reset by starting the\n * \"forgot password\" process.\n */\n code: string\n /** The identifier for the current forms app */\n formsAppId?: number\n}): UseLoginValue {\n const isMounted = useIsMounted()\n\n // Validation\n const usernameValidation = React.useMemo(() => {\n return {\n isInvalid: !username.trim(),\n }\n }, [username])\n\n const passwordValidation = React.useMemo(() => {\n return {\n isInvalid: !password.trim(),\n }\n }, [password])\n\n const codeValidation = React.useMemo(() => {\n return {\n isInvalid: !code.trim(),\n }\n }, [code])\n\n const newPasswordValidation = React.useMemo(() => {\n const validation = {\n hasLowercaseLetter: /[a-z]+/.test(newPassword),\n hasUpperCaseLetter: /[A-Z]+/.test(newPassword),\n hasNumber: /\\d+/.test(newPassword),\n hasSpecialCharacter: /[\\^$*.[\\]{}()?|\\-\"!@#%&/,><':;|_~`]+/.test(\n newPassword,\n ),\n hasMinLength: newPassword.length >= 8,\n isInvalid: true,\n }\n validation.isInvalid =\n !validation.hasLowercaseLetter ||\n !validation.hasUpperCaseLetter ||\n !validation.hasNumber ||\n !validation.hasSpecialCharacter ||\n !validation.hasMinLength\n return validation\n }, [newPassword])\n\n const newPasswordConfirmedValidation = React.useMemo(() => {\n return {\n isInvalid: newPassword !== newPasswordConfirmed,\n }\n }, [newPassword, newPasswordConfirmed])\n\n // Login, Reset Password, MFA\n const [\n {\n isResettingTemporaryPassword,\n isLoggingIn,\n loginError,\n loginAttemptResponse,\n isSubmittingMfaCode,\n isResendingMfaCode,\n mfaCodeSentAt,\n },\n setLoginState,\n ] = React.useState<{\n isResettingTemporaryPassword: boolean\n isLoggingIn: boolean\n loginError: null | Error\n loginAttemptResponse: authService.LoginAttemptResponse | undefined\n isSubmittingMfaCode: boolean\n isResendingMfaCode: boolean\n mfaCodeSentAt: number | undefined\n }>({\n isResettingTemporaryPassword: false,\n isLoggingIn: false,\n loginError: null,\n loginAttemptResponse: undefined,\n isSubmittingMfaCode: false,\n isResendingMfaCode: false,\n mfaCodeSentAt: undefined,\n })\n const clearLoginError = React.useCallback(\n () =>\n setLoginState((current) => ({\n ...current,\n loginError: null,\n })),\n [],\n )\n const loginWithUsernamePassword = React.useCallback(async () => {\n if (usernameValidation.isInvalid) {\n setLoginState((current) => ({\n ...current,\n loginError: new Error('Please enter a valid email address'),\n }))\n return\n }\n if (passwordValidation.isInvalid) {\n setLoginState((current) => ({\n ...current,\n loginError: new Error('Please enter a valid password'),\n }))\n return\n }\n\n setLoginState((currentState) => ({\n ...currentState,\n isLoggingIn: true,\n loginError: null,\n }))\n\n try {\n const newLoginAttemptResponse = await authService.loginUsernamePassword(\n username,\n password,\n )\n if (isMounted.current) {\n setLoginState((currentState) => ({\n ...currentState,\n isLoggingIn: false,\n loginAttemptResponse: newLoginAttemptResponse,\n mfaCodeSentAt: newLoginAttemptResponse.mfa\n ? Date.now()\n : undefined,\n }))\n }\n } catch (error) {\n Sentry.captureException(error)\n if (isMounted.current) {\n setLoginState((currentState) => ({\n ...currentState,\n isLoggingIn: false,\n loginError: error as Error,\n }))\n }\n }\n }, [\n isMounted,\n password,\n passwordValidation.isInvalid,\n username,\n usernameValidation.isInvalid,\n ])\n\n const resetTemporaryPassword = React.useCallback(async () => {\n const resetTemporaryPasswordCallback =\n loginAttemptResponse?.resetPasswordCallback\n if (!resetTemporaryPasswordCallback) {\n return\n }\n\n if (newPasswordValidation.isInvalid) {\n setLoginState((current) => ({\n ...current,\n loginError: new Error('Please enter a valid password'),\n }))\n return\n }\n\n if (newPasswordConfirmedValidation.isInvalid) {\n setLoginState((current) => ({\n ...current,\n loginError: new Error('Please confirm your new password'),\n }))\n return\n }\n\n setLoginState((current) => ({\n ...current,\n isResettingPassword: true,\n loginError: null,\n }))\n\n try {\n const resetPasswordResponse =\n await resetTemporaryPasswordCallback(newPassword)\n if (isMounted.current) {\n setLoginState((currentState) => ({\n ...currentState,\n isResettingTemporaryPassword: false,\n loginAttemptResponse: resetPasswordResponse,\n mfaCodeSentAt: resetPasswordResponse.mfa\n ? Date.now()\n : undefined,\n }))\n }\n } catch (error) {\n Sentry.captureException(error)\n if (isMounted.current) {\n setLoginState((current) => ({\n ...current,\n isResettingPassword: false,\n loginError: error as Error,\n }))\n }\n }\n }, [\n isMounted,\n loginAttemptResponse?.resetPasswordCallback,\n newPassword,\n newPasswordConfirmedValidation.isInvalid,\n newPasswordValidation.isInvalid,\n ])\n\n const submitMfaCode = React.useCallback(async () => {\n const mfaCodeCallback = loginAttemptResponse?.mfa?.codeCallback\n if (!mfaCodeCallback) {\n return\n }\n\n setLoginState((current) => ({\n ...current,\n isSubmittingMfaCode: true,\n loginError: null,\n }))\n\n try {\n const mfaResponse = await mfaCodeCallback(code)\n if (isMounted.current) {\n setLoginState((currentState) => ({\n ...currentState,\n isSubmittingMfaCode: false,\n loginAttemptResponse: mfaResponse,\n mfaCodeSentAt: mfaResponse.mfa\n ? currentState.mfaCodeSentAt\n : undefined,\n }))\n }\n } catch (error) {\n Sentry.captureException(error)\n if (isMounted.current) {\n setLoginState((current) => ({\n ...current,\n isSubmittingMfaCode: false,\n loginError: error as Error,\n }))\n }\n }\n }, [code, isMounted, loginAttemptResponse?.mfa?.codeCallback])\n\n const resendMfaCodeCallback = loginAttemptResponse?.mfa?.resendCodeCallback\n\n const resendMfaCode = React.useMemo(() => {\n if (!resendMfaCodeCallback) {\n return\n }\n\n return async () => {\n setLoginState((current) => ({\n ...current,\n isResendingMfaCode: true,\n loginError: null,\n }))\n\n try {\n const mfaResponse = await resendMfaCodeCallback()\n if (isMounted.current) {\n setLoginState((currentState) => ({\n ...currentState,\n isResendingMfaCode: false,\n loginAttemptResponse: mfaResponse,\n mfaCodeSentAt: Date.now(),\n }))\n }\n } catch (error) {\n Sentry.captureException(error)\n if (isMounted.current) {\n setLoginState((current) => ({\n ...current,\n isResendingMfaCode: false,\n loginError: error as Error,\n }))\n }\n }\n }\n }, [isMounted, resendMfaCodeCallback])\n\n // Forgot Password\n const [isShowingForgotPassword, showForgotPassword, hideForgotPassword] =\n useBooleanState(false)\n const [\n {\n resetForgottenPasswordCallback,\n isSendingForgotPasswordCode,\n isResettingForgottenPassword,\n forgotPasswordError,\n },\n setForgotPasswordState,\n ] = React.useState<{\n isSendingForgotPasswordCode: boolean\n forgotPasswordError: null | Error\n resetForgottenPasswordCallback:\n | null\n | ((code: string, newPassword: string) => void)\n isResettingForgottenPassword: boolean\n }>({\n isSendingForgotPasswordCode: false,\n forgotPasswordError: null,\n resetForgottenPasswordCallback: null,\n isResettingForgottenPassword: false,\n })\n const clearForgotPasswordError = React.useCallback(\n () =>\n setForgotPasswordState((current) => ({\n ...current,\n forgotPasswordError: null,\n })),\n [],\n )\n const sendForgotPasswordCode = React.useCallback(async () => {\n if (usernameValidation.isInvalid) {\n setForgotPasswordState((current) => ({\n ...current,\n forgotPasswordError: new Error('Please enter a valid email address'),\n }))\n return\n }\n\n setForgotPasswordState({\n isSendingForgotPasswordCode: true,\n resetForgottenPasswordCallback: null,\n forgotPasswordError: null,\n isResettingForgottenPassword: false,\n })\n\n try {\n const newResetForgottenPasswordCallback =\n await authService.forgotPassword(username, formsAppId)\n if (isMounted.current) {\n setForgotPasswordState({\n isSendingForgotPasswordCode: false,\n resetForgottenPasswordCallback: newResetForgottenPasswordCallback,\n forgotPasswordError: null,\n isResettingForgottenPassword: false,\n })\n }\n } catch (error) {\n Sentry.captureException(error)\n if (isMounted.current) {\n setForgotPasswordState({\n isSendingForgotPasswordCode: false,\n resetForgottenPasswordCallback: null,\n forgotPasswordError: error as Error,\n isResettingForgottenPassword: false,\n })\n }\n }\n }, [isMounted, username, usernameValidation.isInvalid, formsAppId])\n\n const resetForgottenPassword = React.useCallback(async () => {\n if (!resetForgottenPasswordCallback) {\n return\n }\n\n if (codeValidation.isInvalid) {\n setForgotPasswordState((current) => ({\n ...current,\n forgotPasswordError: new Error(\n 'Please enter the code that was sent to your email address',\n ),\n }))\n }\n if (newPasswordValidation.isInvalid) {\n setForgotPasswordState((current) => ({\n ...current,\n forgotPasswordError: new Error('Please enter a valid password'),\n }))\n return\n }\n if (newPasswordConfirmedValidation.isInvalid) {\n setForgotPasswordState((current) => ({\n ...current,\n forgotPasswordError: new Error('Please confirm your new password'),\n }))\n return\n }\n\n setForgotPasswordState((current) => ({\n ...current,\n isChangingPassword: true,\n forgotPasswordError: null,\n }))\n\n try {\n await resetForgottenPasswordCallback(code, newPassword)\n if (isMounted.current) {\n setForgotPasswordState({\n isSendingForgotPasswordCode: false,\n resetForgottenPasswordCallback: null,\n forgotPasswordError: null,\n isResettingForgottenPassword: false,\n })\n hideForgotPassword()\n }\n } catch (error) {\n Sentry.captureException(error)\n if (isMounted.current) {\n setForgotPasswordState((current) => ({\n ...current,\n isChangingPassword: false,\n forgotPasswordError: error as Error,\n }))\n }\n }\n }, [\n resetForgottenPasswordCallback,\n codeValidation.isInvalid,\n newPasswordValidation.isInvalid,\n newPasswordConfirmedValidation.isInvalid,\n code,\n newPassword,\n isMounted,\n hideForgotPassword,\n ])\n\n const loginWithGoogle = React.useCallback(() => {\n authService.loginHostedUI('Google')\n }, [])\n\n return {\n // Login\n /** Open redirect user to the Google sign in */\n loginWithGoogle,\n loginWithUsernamePassword,\n isLoggingIn,\n loginError,\n clearLoginError,\n // Reset Temp Password\n isPasswordTemporary: !!loginAttemptResponse?.resetPasswordCallback,\n isResettingTemporaryPassword,\n resetTemporaryPassword,\n // MFA Code\n mfaMethod: loginAttemptResponse?.mfa?.method || null,\n isSubmittingMfaCode,\n submitMfaCode,\n isResendingMfaCode,\n resendMfaCode,\n mfaCodeSentAt,\n // Showing Forgot Password\n isShowingForgotPassword,\n showForgotPassword,\n hideForgotPassword,\n forgotPasswordError,\n clearForgotPasswordError,\n // Sending Forgot Password Code\n isSendingForgotPasswordCode,\n sendForgotPasswordCode,\n // Resetting Forgotten Password\n hasSentForgotPasswordCode: !!resetForgottenPasswordCallback,\n isResettingForgottenPassword,\n resetForgottenPassword,\n // Validation\n usernameValidation,\n passwordValidation,\n codeValidation,\n newPasswordValidation,\n newPasswordConfirmedValidation,\n }\n}\n\nexport interface UseLoginValue {\n /** Open redirect user to the Google sign-in page. */\n loginWithGoogle: () => void\n /**\n * Attempt to use the `username` and `password` arguments to create a session.\n * Will call `onLogin()` if successful, otherwise will set `loginError`.\n */\n loginWithUsernamePassword: () => void\n /** `true` while processing `loginWithUsernamePassword()`. */\n isLoggingIn: boolean\n /**\n * `true` if the user logged in using a temporary password. Prompt the user\n * for a new password and call `resetTemporaryPassword()`.\n */\n isPasswordTemporary: boolean\n /**\n * Attempt to use `newPassword` and `newPasswordConfirmed` arguments to reset\n * the user's password and create a session. Will call `onLogin()` if\n * successful, otherwise will set `loginError`.\n */\n resetTemporaryPassword: () => void\n /**\n * Set if an error occurs while processing `loginWithUsernamePassword()` or\n * `resetTemporaryPassword()`.\n */\n loginError: Error | null\n /** Set `loginError` back to `null`. */\n clearLoginError: () => void\n /** `true` while processing `resetTemporaryPassword()`. */\n isResettingTemporaryPassword: boolean\n /** `true` when showing the forgot password flow. */\n isShowingForgotPassword: boolean\n /** Set `isShowingForgotPassword` to `true`. */\n showForgotPassword: () => void\n /** Set `isShowingForgotPassword` to `false`. */\n hideForgotPassword: () => void\n /**\n * Attempt to use the `username` argument to start the forgot password\n * process. This will send the user an email with a code to enter. A failed\n * request will set `forgotPasswordError`.\n */\n sendForgotPasswordCode: () => void\n /** `true` while processing `sendForgotPasswordCode()`. */\n isSendingForgotPasswordCode: boolean\n /** `true` if the forgot password code has been successfully sent to the user. */\n hasSentForgotPasswordCode: boolean\n /**\n * Attempt to use the `code`, `newPassword`, and `newPasswordConfirmed`\n * arguments to reset the user's password. A failed request will set\n * `forgotPasswordError`.\n */\n resetForgottenPassword: () => void\n /** `true` while processing `resetForgottenPassword()`. */\n isResettingForgottenPassword: boolean\n /**\n * Set if an error occurs while processing `sendForgotPasswordCode()` or\n * `resetForgottenPassword()`.\n */\n forgotPasswordError: Error | null\n /** Set `forgotPasswordError` back to `null`. */\n clearForgotPasswordError: () => void\n usernameValidation: {\n /** `true` if the `username` argument is invalid. */\n isInvalid: boolean\n }\n passwordValidation: {\n /** `true` if the `password` argument is invalid. */\n isInvalid: boolean\n }\n codeValidation: {\n /** `true` if the `code` argument is invalid. */\n isInvalid: boolean\n }\n newPasswordValidation: {\n /** `true` if the `newPassword` argument is invalid. */\n isInvalid: boolean\n /**\n * `true` if the `newPassword` argument has a lowercase letter (required to\n * be valid).\n */\n hasLowercaseLetter: boolean\n /**\n * `true` if the `newPassword` argument has an uppercase letter (required to\n * be valid).\n */\n hasUpperCaseLetter: boolean\n /** `true` if the `newPassword` argument has a number (required to be valid). */\n hasNumber: boolean\n /**\n * `true` if the `newPassword` argument has a special character (required to\n * be valid).\n */\n hasSpecialCharacter: boolean\n /**\n * `true` if the `newPassword` argument has at least the minimum number of\n * characters (required to be valid).\n */\n hasMinLength: boolean\n }\n newPasswordConfirmedValidation: {\n /**\n * `true` if the `newPasswordConfirmed` argument is invalid (must match the\n * `newPassword` argument).\n */\n isInvalid: boolean\n }\n /** The MFA method the user must complete to finish signing in, if available. */\n mfaMethod: mfaService.MfaMethod | null\n /** `true` while processing `submitMfaCode()`. */\n isSubmittingMfaCode: boolean\n /**\n * Attempt to use `code` argument to submit the MFA code and create a session.\n * Will call `onLogin()` if successful, otherwise will set `loginError`.\n */\n submitMfaCode: () => void\n /** `true` while processing `resendMfaCode()`, when available. */\n isResendingMfaCode: boolean\n /**\n * Request a new one-time verification code during sign-in. Defined when the\n * active MFA step supports resending a code (e.g. SMS).\n */\n resendMfaCode?: () => void\n /**\n * Timestamp when the current MFA code was sent. Use with `useResendCoolDown()`\n * to enforce a resend cooldown.\n */\n mfaCodeSentAt?: number\n}\n"]}
@@ -1,34 +1,34 @@
1
1
  import * as React from 'react';
2
- import { authService } from '../apps';
2
+ import { mfaService } from '../apps';
3
+ import { MiscTypes } from '@oneblink/types';
3
4
  type MfaState = {
4
5
  isExternalIdentityProviderUser: boolean;
5
6
  isLoading: boolean;
6
7
  isMfaEnabled: boolean;
7
- mfaSettings: authService.MfaSettings;
8
+ mfaSettings: mfaService.MfaSettings;
8
9
  isSetupSuccessOpen: boolean;
9
10
  loadingError?: Error;
10
11
  isSettingUpMfa: boolean;
11
- settingUpMfaMethod?: authService.MfaMethod;
12
+ settingUpMfaMethod?: mfaService.MfaMethod;
12
13
  isSetupMethodDialogOpen: boolean;
13
- disablingMfaMethod?: authService.MfaMethod;
14
+ disablingMfaMethod?: mfaService.MfaMethod;
14
15
  isSettingPreferredMfaMethod: boolean;
15
16
  setupError?: Error;
16
- mfaAuthenticatorAppSetup?: Awaited<ReturnType<typeof authService.setupMfaAuthenticatorApp>>;
17
+ mfaAuthenticatorAppSetup?: Awaited<ReturnType<typeof mfaService.setupMfaAuthenticatorApp>>;
17
18
  isPhoneNumberDialogOpen: boolean;
18
19
  phoneVerificationCodeSentAt?: number;
19
20
  isRemovePhoneNumberDialogOpen: boolean;
20
21
  };
21
22
  export declare const MfaContext: React.Context<MfaState & {
22
- beginMfaSetup: (mfaMethod: authService.MfaMethod) => Promise<void>;
23
+ beginMfaSetup: (mfaMethod: mfaService.MfaMethod) => Promise<void>;
23
24
  openMfaSetupMethodDialog: () => void;
24
25
  closeMfaSetupMethodDialog: () => void;
25
- beginDisablingMfaMethod: (mfaMethod: authService.MfaMethod) => void;
26
- setPreferredMfaMethod: (mfaMethod: authService.MfaMethod) => Promise<void>;
26
+ beginDisablingMfaMethod: (mfaMethod: mfaService.MfaMethod) => void;
27
+ setPreferredMfaMethod: (mfaMethod: mfaService.MfaMethod) => Promise<void>;
27
28
  openPhoneNumberDialog: () => void;
28
29
  closePhoneNumberDialog: () => void;
29
30
  savePhoneNumber: (phoneNumber: string) => Promise<void>;
30
31
  verifyPhoneNumber: (code: string) => Promise<void>;
31
- resendPhoneNumberVerificationCode: () => Promise<void>;
32
32
  beginRemovingPhoneNumber: () => void;
33
33
  cancelRemovingPhoneNumber: () => void;
34
34
  completeRemovingPhoneNumber: () => Promise<void>;
@@ -56,23 +56,36 @@ export declare const MfaContext: React.Context<MfaState & {
56
56
  * useUserMeetsMfaRequirement,
57
57
  * } from '@oneblink/apps-react'
58
58
  *
59
- * function Component() {
60
- * const { isLoading, userMeetsMfaRequirement } =
61
- * useUserMeetsMfaRequirement(true)
62
- * // use MFA Requirement details here
59
+ * function Component({ teamMemberMfaRequirement }) {
60
+ * const { mfaSetupRequired, isLoading, loadingError, refreshMfa } =
61
+ * useUserMeetsMfaRequirement(teamMemberMfaRequirement)
62
+ *
63
+ * if (isLoading) {
64
+ * return <Loading />
65
+ * }
66
+ *
67
+ * if (loadingError) {
68
+ * return <Error onRetry={refreshMfa} />
69
+ * }
70
+ *
71
+ * if (mfaSetupRequired) {
72
+ * return <ConfigureMfa />
73
+ * }
74
+ *
75
+ * return <Application />
63
76
  * }
64
77
  *
65
- * function App() {
78
+ * function App({ teamMemberMfaRequirement }) {
66
79
  * return (
67
80
  * <MfaProvider isExternalIdentityProviderUser={false}>
68
- * <Component />
81
+ * <Component teamMemberMfaRequirement={teamMemberMfaRequirement} />
69
82
  * </MfaProvider>
70
83
  * )
71
84
  * }
72
85
  *
73
86
  * const root = document.getElementById('root')
74
87
  * if (root) {
75
- * ReactDOM.render(<App />, root)
88
+ * ReactDOM.render(<App teamMemberMfaRequirement={mfaRequirement} />, root)
76
89
  * }
77
90
  * ```
78
91
  *
@@ -85,16 +98,15 @@ export declare function MfaProvider({ children, isExternalIdentityProviderUser,
85
98
  isExternalIdentityProviderUser: boolean;
86
99
  }): import("react/jsx-runtime").JSX.Element;
87
100
  export default function useMfa(): MfaState & {
88
- beginMfaSetup: (mfaMethod: authService.MfaMethod) => Promise<void>;
101
+ beginMfaSetup: (mfaMethod: mfaService.MfaMethod) => Promise<void>;
89
102
  openMfaSetupMethodDialog: () => void;
90
103
  closeMfaSetupMethodDialog: () => void;
91
- beginDisablingMfaMethod: (mfaMethod: authService.MfaMethod) => void;
92
- setPreferredMfaMethod: (mfaMethod: authService.MfaMethod) => Promise<void>;
104
+ beginDisablingMfaMethod: (mfaMethod: mfaService.MfaMethod) => void;
105
+ setPreferredMfaMethod: (mfaMethod: mfaService.MfaMethod) => Promise<void>;
93
106
  openPhoneNumberDialog: () => void;
94
107
  closePhoneNumberDialog: () => void;
95
108
  savePhoneNumber: (phoneNumber: string) => Promise<void>;
96
109
  verifyPhoneNumber: (code: string) => Promise<void>;
97
- resendPhoneNumberVerificationCode: () => Promise<void>;
98
110
  beginRemovingPhoneNumber: () => void;
99
111
  cancelRemovingPhoneNumber: () => void;
100
112
  completeRemovingPhoneNumber: () => Promise<void>;
@@ -107,25 +119,48 @@ export default function useMfa(): MfaState & {
107
119
  loadMfa: () => void;
108
120
  };
109
121
  /**
110
- * React hook to check if the logged in user meets the MFA requirement of your
111
- * application. Will throw an Error if used outside of the
112
- * `<MfaProvider />` component.
122
+ * React hook to determine whether the logged in user must set up MFA before
123
+ * accessing your application. Reads MFA settings from the `<MfaProvider />`
124
+ * context. Will throw an Error if used outside of `<MfaProvider />`.
125
+ *
126
+ * Users signed in via an external identity provider are not required to set up
127
+ * MFA.
113
128
  *
114
- * Example
129
+ * #### Example
115
130
  *
116
131
  * ```js
117
- * import { useUserMeetsMfaRequirement } from '@oneblink/apps-react'
132
+ * import { MfaProvider, useUserMeetsMfaRequirement } from '@oneblink/apps-react'
118
133
  *
119
- * const isMfaRequired = true
134
+ * function Component({ teamMemberMfaRequirement }) {
135
+ * const { mfaSetupRequired, isLoading, loadingError, refreshMfa } =
136
+ * useUserMeetsMfaRequirement(teamMemberMfaRequirement)
120
137
  *
121
- * function Component() {
122
- * const userMeetsMfaRequirement =
123
- * useUserMeetsMfaRequirement(isMfaRequired)
138
+ * if (isLoading) {
139
+ * return <Loading />
140
+ * }
141
+ *
142
+ * if (loadingError) {
143
+ * return <Error onRetry={refreshMfa} />
144
+ * }
145
+ *
146
+ * if (mfaSetupRequired) {
147
+ * return <ConfigureMfa />
148
+ * }
149
+ *
150
+ * return <Application />
124
151
  * }
125
152
  * ```
126
153
  *
127
- * @returns
154
+ * @param mfaRequirement - The MFA requirement to enforce, e.g. from your
155
+ * organisation or app settings.
156
+ * @returns Whether MFA setup is required, along with loading state from the MFA
157
+ * provider.
128
158
  * @group Hooks
129
159
  */
130
- export declare function useUserMeetsMfaRequirement(isMfaRequired: boolean): boolean;
160
+ export declare function useUserMeetsMfaRequirement(mfaRequirement: MiscTypes.MfaRequirement | undefined): {
161
+ mfaSetupRequired: boolean;
162
+ isLoading: boolean;
163
+ loadingError: Error | undefined;
164
+ refreshMfa: () => void;
165
+ };
131
166
  export {};