@oneblink/apps-react 5.13.0 → 5.14.0-beta.1

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.
@@ -297,7 +297,7 @@
297
297
  * @returns
298
298
  * @group Hooks
299
299
  */
300
- export default function useLogin({ username, password, newPassword, newPasswordConfirmed, code, }: {
300
+ export default function useLogin({ username, password, newPassword, newPasswordConfirmed, code, formsAppId, }: {
301
301
  /** The email address entered by the user. */
302
302
  username: string;
303
303
  /** The password entered by the user. */
@@ -314,6 +314,8 @@ export default function useLogin({ username, password, newPassword, newPasswordC
314
314
  * "forgot password" process.
315
315
  */
316
316
  code: string;
317
+ /** The identifier for the current forms app */
318
+ formsAppId?: number;
317
319
  }): UseLoginValue;
318
320
  export interface UseLoginValue {
319
321
  /** Open redirect user to the Google sign-in page. */
@@ -301,7 +301,7 @@ import useBooleanState from './useBooleanState';
301
301
  * @returns
302
302
  * @group Hooks
303
303
  */
304
- export default function useLogin({ username, password, newPassword, newPasswordConfirmed, code, }) {
304
+ export default function useLogin({ username, password, newPassword, newPasswordConfirmed, code, formsAppId, }) {
305
305
  const isMounted = useIsMounted();
306
306
  // Validation
307
307
  const usernameValidation = React.useMemo(() => {
@@ -509,7 +509,7 @@ export default function useLogin({ username, password, newPassword, newPasswordC
509
509
  isResettingForgottenPassword: false,
510
510
  });
511
511
  try {
512
- const newResetForgottenPasswordCallback = await authService.forgotPassword(username);
512
+ const newResetForgottenPasswordCallback = await authService.forgotPassword(username, formsAppId);
513
513
  if (isMounted.current) {
514
514
  setForgotPasswordState({
515
515
  isSendingForgotPasswordCode: false,
@@ -530,7 +530,7 @@ export default function useLogin({ username, password, newPassword, newPasswordC
530
530
  });
531
531
  }
532
532
  }
533
- }, [isMounted, username, usernameValidation.isInvalid]);
533
+ }, [isMounted, username, usernameValidation.isInvalid, formsAppId]);
534
534
  const resetForgottenPassword = React.useCallback(async () => {
535
535
  if (!resetForgottenPasswordCallback) {
536
536
  return;
@@ -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 '@oneblink/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 * isMfaCodeRequired,\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 (isMfaCodeRequired) {\n * return (\n * <form\n * onSubmit={(e) => {\n * e.preventDefault()\n * submitMfaCode()\n * }}\n * >\n * <p>Enter the 6-digit code found in your authenticator app.</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}: {\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}): 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?.mfaCodeCallback\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?.mfaCodeCallback])\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)\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])\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 isMfaCodeRequired: !!loginAttemptResponse?.mfaCodeCallback,\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 /**\n * `true` if the user logged in using MFA and a code is required to finish the\n * login attempt. Prompt the user for a code and call `submitMfaCode()`.\n */\n isMfaCodeRequired: boolean\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":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAEpD,OAAO,YAAY,MAAM,gBAAgB,CAAA;AACzC,OAAO,eAAe,MAAM,mBAAmB,CAAA;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0SG;AACH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,EAC/B,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,oBAAoB,EACpB,IAAI,EACJ,UAAU,GAoBX;IACC,MAAM,SAAS,GAAG,YAAY,EAAE,CAAA;IAEhC,aAAa;IACb,MAAM,kBAAkB,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QAC5C,OAAO;YACL,SAAS,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE;SAC5B,CAAA;IACH,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAA;IAEd,MAAM,kBAAkB,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QAC5C,OAAO;YACL,SAAS,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE;SAC5B,CAAA;IACH,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAA;IAEd,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACxC,OAAO;YACL,SAAS,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE;SACxB,CAAA;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAEV,MAAM,qBAAqB,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QAC/C,MAAM,UAAU,GAAG;YACjB,kBAAkB,EAAE,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC;YAC9C,kBAAkB,EAAE,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC;YAC9C,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC;YAClC,mBAAmB,EAAE,sCAAsC,CAAC,IAAI,CAC9D,WAAW,CACZ;YACD,YAAY,EAAE,WAAW,CAAC,MAAM,IAAI,CAAC;YACrC,SAAS,EAAE,IAAI;SAChB,CAAA;QACD,UAAU,CAAC,SAAS;YAClB,CAAC,UAAU,CAAC,kBAAkB;gBAC9B,CAAC,UAAU,CAAC,kBAAkB;gBAC9B,CAAC,UAAU,CAAC,SAAS;gBACrB,CAAC,UAAU,CAAC,mBAAmB;gBAC/B,CAAC,UAAU,CAAC,YAAY,CAAA;QAC1B,OAAO,UAAU,CAAA;IACnB,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;IAEjB,MAAM,8BAA8B,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACxD,OAAO;YACL,SAAS,EAAE,WAAW,KAAK,oBAAoB;SAChD,CAAA;IACH,CAAC,EAAE,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAC,CAAA;IAEvC,6BAA6B;IAC7B,MAAM,CACJ,EACE,4BAA4B,EAC5B,WAAW,EACX,UAAU,EACV,oBAAoB,EACpB,mBAAmB,GACpB,EACD,aAAa,EACd,GAAG,KAAK,CAAC,QAAQ,CAMf;QACD,4BAA4B,EAAE,KAAK;QACnC,WAAW,EAAE,KAAK;QAClB,UAAU,EAAE,IAAI;QAChB,oBAAoB,EAAE,SAAS;QAC/B,mBAAmB,EAAE,KAAK;KAC3B,CAAC,CAAA;IACF,MAAM,eAAe,GAAG,KAAK,CAAC,WAAW,CACvC,GAAG,EAAE,CACH,aAAa,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC1B,GAAG,OAAO;QACV,UAAU,EAAE,IAAI;KACjB,CAAC,CAAC,EACL,EAAE,CACH,CAAA;IACD,MAAM,yBAAyB,GAAG,KAAK,CAAC,WAAW,CAAC,KAAK,IAAI,EAAE;QAC7D,IAAI,kBAAkB,CAAC,SAAS,EAAE;YAChC,aAAa,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBAC1B,GAAG,OAAO;gBACV,UAAU,EAAE,IAAI,KAAK,CAAC,oCAAoC,CAAC;aAC5D,CAAC,CAAC,CAAA;YACH,OAAM;SACP;QACD,IAAI,kBAAkB,CAAC,SAAS,EAAE;YAChC,aAAa,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBAC1B,GAAG,OAAO;gBACV,UAAU,EAAE,IAAI,KAAK,CAAC,+BAA+B,CAAC;aACvD,CAAC,CAAC,CAAA;YACH,OAAM;SACP;QAED,aAAa,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;YAC/B,GAAG,YAAY;YACf,WAAW,EAAE,IAAI;YACjB,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC,CAAA;QAEH,IAAI;YACF,MAAM,uBAAuB,GAAG,MAAM,WAAW,CAAC,qBAAqB,CACrE,QAAQ,EACR,QAAQ,CACT,CAAA;YACD,IAAI,SAAS,CAAC,OAAO,EAAE;gBACrB,aAAa,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;oBAC/B,GAAG,YAAY;oBACf,WAAW,EAAE,KAAK;oBAClB,oBAAoB,EAAE,uBAAuB;iBAC9C,CAAC,CAAC,CAAA;aACJ;SACF;QAAC,OAAO,KAAK,EAAE;YACd,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAA;YAC9B,IAAI,SAAS,CAAC,OAAO,EAAE;gBACrB,aAAa,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;oBAC/B,GAAG,YAAY;oBACf,WAAW,EAAE,KAAK;oBAClB,UAAU,EAAE,KAAc;iBAC3B,CAAC,CAAC,CAAA;aACJ;SACF;IACH,CAAC,EAAE;QACD,SAAS;QACT,QAAQ;QACR,kBAAkB,CAAC,SAAS;QAC5B,QAAQ;QACR,kBAAkB,CAAC,SAAS;KAC7B,CAAC,CAAA;IAEF,MAAM,sBAAsB,GAAG,KAAK,CAAC,WAAW,CAAC,KAAK,IAAI,EAAE;QAC1D,MAAM,8BAA8B,GAClC,oBAAoB,aAApB,oBAAoB,uBAApB,oBAAoB,CAAE,qBAAqB,CAAA;QAC7C,IAAI,CAAC,8BAA8B,EAAE;YACnC,OAAM;SACP;QAED,IAAI,qBAAqB,CAAC,SAAS,EAAE;YACnC,aAAa,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBAC1B,GAAG,OAAO;gBACV,UAAU,EAAE,IAAI,KAAK,CAAC,+BAA+B,CAAC;aACvD,CAAC,CAAC,CAAA;YACH,OAAM;SACP;QAED,IAAI,8BAA8B,CAAC,SAAS,EAAE;YAC5C,aAAa,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBAC1B,GAAG,OAAO;gBACV,UAAU,EAAE,IAAI,KAAK,CAAC,kCAAkC,CAAC;aAC1D,CAAC,CAAC,CAAA;YACH,OAAM;SACP;QAED,aAAa,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAC1B,GAAG,OAAO;YACV,mBAAmB,EAAE,IAAI;YACzB,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC,CAAA;QAEH,IAAI;YACF,MAAM,qBAAqB,GACzB,MAAM,8BAA8B,CAAC,WAAW,CAAC,CAAA;YACnD,IAAI,SAAS,CAAC,OAAO,EAAE;gBACrB,aAAa,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;oBAC/B,GAAG,YAAY;oBACf,4BAA4B,EAAE,KAAK;oBACnC,oBAAoB,EAAE,qBAAqB;iBAC5C,CAAC,CAAC,CAAA;aACJ;SACF;QAAC,OAAO,KAAK,EAAE;YACd,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAA;YAC9B,IAAI,SAAS,CAAC,OAAO,EAAE;gBACrB,aAAa,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;oBAC1B,GAAG,OAAO;oBACV,mBAAmB,EAAE,KAAK;oBAC1B,UAAU,EAAE,KAAc;iBAC3B,CAAC,CAAC,CAAA;aACJ;SACF;IACH,CAAC,EAAE;QACD,SAAS;QACT,oBAAoB,aAApB,oBAAoB,uBAApB,oBAAoB,CAAE,qBAAqB;QAC3C,WAAW;QACX,8BAA8B,CAAC,SAAS;QACxC,qBAAqB,CAAC,SAAS;KAChC,CAAC,CAAA;IAEF,MAAM,aAAa,GAAG,KAAK,CAAC,WAAW,CAAC,KAAK,IAAI,EAAE;QACjD,MAAM,eAAe,GAAG,oBAAoB,aAApB,oBAAoB,uBAApB,oBAAoB,CAAE,eAAe,CAAA;QAC7D,IAAI,CAAC,eAAe,EAAE;YACpB,OAAM;SACP;QAED,aAAa,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAC1B,GAAG,OAAO;YACV,mBAAmB,EAAE,IAAI;YACzB,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC,CAAA;QAEH,IAAI;YACF,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAA;YAC/C,IAAI,SAAS,CAAC,OAAO,EAAE;gBACrB,aAAa,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;oBAC/B,GAAG,YAAY;oBACf,mBAAmB,EAAE,KAAK;oBAC1B,oBAAoB,EAAE,WAAW;iBAClC,CAAC,CAAC,CAAA;aACJ;SACF;QAAC,OAAO,KAAK,EAAE;YACd,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAA;YAC9B,IAAI,SAAS,CAAC,OAAO,EAAE;gBACrB,aAAa,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;oBAC1B,GAAG,OAAO;oBACV,mBAAmB,EAAE,KAAK;oBAC1B,UAAU,EAAE,KAAc;iBAC3B,CAAC,CAAC,CAAA;aACJ;SACF;IACH,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,oBAAoB,aAApB,oBAAoB,uBAApB,oBAAoB,CAAE,eAAe,CAAC,CAAC,CAAA;IAE5D,kBAAkB;IAClB,MAAM,CAAC,uBAAuB,EAAE,kBAAkB,EAAE,kBAAkB,CAAC,GACrE,eAAe,CAAC,KAAK,CAAC,CAAA;IACxB,MAAM,CACJ,EACE,8BAA8B,EAC9B,2BAA2B,EAC3B,4BAA4B,EAC5B,mBAAmB,GACpB,EACD,sBAAsB,EACvB,GAAG,KAAK,CAAC,QAAQ,CAOf;QACD,2BAA2B,EAAE,KAAK;QAClC,mBAAmB,EAAE,IAAI;QACzB,8BAA8B,EAAE,IAAI;QACpC,4BAA4B,EAAE,KAAK;KACpC,CAAC,CAAA;IACF,MAAM,wBAAwB,GAAG,KAAK,CAAC,WAAW,CAChD,GAAG,EAAE,CACH,sBAAsB,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACnC,GAAG,OAAO;QACV,mBAAmB,EAAE,IAAI;KAC1B,CAAC,CAAC,EACL,EAAE,CACH,CAAA;IACD,MAAM,sBAAsB,GAAG,KAAK,CAAC,WAAW,CAAC,KAAK,IAAI,EAAE;QAC1D,IAAI,kBAAkB,CAAC,SAAS,EAAE;YAChC,sBAAsB,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBACnC,GAAG,OAAO;gBACV,mBAAmB,EAAE,IAAI,KAAK,CAAC,oCAAoC,CAAC;aACrE,CAAC,CAAC,CAAA;YACH,OAAM;SACP;QAED,sBAAsB,CAAC;YACrB,2BAA2B,EAAE,IAAI;YACjC,8BAA8B,EAAE,IAAI;YACpC,mBAAmB,EAAE,IAAI;YACzB,4BAA4B,EAAE,KAAK;SACpC,CAAC,CAAA;QAEF,IAAI;YACF,MAAM,iCAAiC,GACrC,MAAM,WAAW,CAAC,cAAc,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;YACxD,IAAI,SAAS,CAAC,OAAO,EAAE;gBACrB,sBAAsB,CAAC;oBACrB,2BAA2B,EAAE,KAAK;oBAClC,8BAA8B,EAAE,iCAAiC;oBACjE,mBAAmB,EAAE,IAAI;oBACzB,4BAA4B,EAAE,KAAK;iBACpC,CAAC,CAAA;aACH;SACF;QAAC,OAAO,KAAK,EAAE;YACd,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAA;YAC9B,IAAI,SAAS,CAAC,OAAO,EAAE;gBACrB,sBAAsB,CAAC;oBACrB,2BAA2B,EAAE,KAAK;oBAClC,8BAA8B,EAAE,IAAI;oBACpC,mBAAmB,EAAE,KAAc;oBACnC,4BAA4B,EAAE,KAAK;iBACpC,CAAC,CAAA;aACH;SACF;IACH,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,kBAAkB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAA;IAEnE,MAAM,sBAAsB,GAAG,KAAK,CAAC,WAAW,CAAC,KAAK,IAAI,EAAE;QAC1D,IAAI,CAAC,8BAA8B,EAAE;YACnC,OAAM;SACP;QAED,IAAI,cAAc,CAAC,SAAS,EAAE;YAC5B,sBAAsB,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBACnC,GAAG,OAAO;gBACV,mBAAmB,EAAE,IAAI,KAAK,CAC5B,2DAA2D,CAC5D;aACF,CAAC,CAAC,CAAA;SACJ;QACD,IAAI,qBAAqB,CAAC,SAAS,EAAE;YACnC,sBAAsB,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBACnC,GAAG,OAAO;gBACV,mBAAmB,EAAE,IAAI,KAAK,CAAC,+BAA+B,CAAC;aAChE,CAAC,CAAC,CAAA;YACH,OAAM;SACP;QACD,IAAI,8BAA8B,CAAC,SAAS,EAAE;YAC5C,sBAAsB,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBACnC,GAAG,OAAO;gBACV,mBAAmB,EAAE,IAAI,KAAK,CAAC,kCAAkC,CAAC;aACnE,CAAC,CAAC,CAAA;YACH,OAAM;SACP;QAED,sBAAsB,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACnC,GAAG,OAAO;YACV,kBAAkB,EAAE,IAAI;YACxB,mBAAmB,EAAE,IAAI;SAC1B,CAAC,CAAC,CAAA;QAEH,IAAI;YACF,MAAM,8BAA8B,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;YACvD,IAAI,SAAS,CAAC,OAAO,EAAE;gBACrB,sBAAsB,CAAC;oBACrB,2BAA2B,EAAE,KAAK;oBAClC,8BAA8B,EAAE,IAAI;oBACpC,mBAAmB,EAAE,IAAI;oBACzB,4BAA4B,EAAE,KAAK;iBACpC,CAAC,CAAA;gBACF,kBAAkB,EAAE,CAAA;aACrB;SACF;QAAC,OAAO,KAAK,EAAE;YACd,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAA;YAC9B,IAAI,SAAS,CAAC,OAAO,EAAE;gBACrB,sBAAsB,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;oBACnC,GAAG,OAAO;oBACV,kBAAkB,EAAE,KAAK;oBACzB,mBAAmB,EAAE,KAAc;iBACpC,CAAC,CAAC,CAAA;aACJ;SACF;IACH,CAAC,EAAE;QACD,8BAA8B;QAC9B,cAAc,CAAC,SAAS;QACxB,qBAAqB,CAAC,SAAS;QAC/B,8BAA8B,CAAC,SAAS;QACxC,IAAI;QACJ,WAAW;QACX,SAAS;QACT,kBAAkB;KACnB,CAAC,CAAA;IAEF,MAAM,eAAe,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QAC7C,WAAW,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;IACrC,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO;QACL,QAAQ;QACR,+CAA+C;QAC/C,eAAe;QACf,yBAAyB;QACzB,WAAW;QACX,UAAU;QACV,eAAe;QACf,sBAAsB;QACtB,mBAAmB,EAAE,CAAC,CAAC,CAAA,oBAAoB,aAApB,oBAAoB,uBAApB,oBAAoB,CAAE,qBAAqB,CAAA;QAClE,4BAA4B;QAC5B,sBAAsB;QACtB,WAAW;QACX,iBAAiB,EAAE,CAAC,CAAC,CAAA,oBAAoB,aAApB,oBAAoB,uBAApB,oBAAoB,CAAE,eAAe,CAAA;QAC1D,mBAAmB;QACnB,aAAa;QACb,0BAA0B;QAC1B,uBAAuB;QACvB,kBAAkB;QAClB,kBAAkB;QAClB,mBAAmB;QACnB,wBAAwB;QACxB,+BAA+B;QAC/B,2BAA2B;QAC3B,sBAAsB;QACtB,+BAA+B;QAC/B,yBAAyB,EAAE,CAAC,CAAC,8BAA8B;QAC3D,4BAA4B;QAC5B,sBAAsB;QACtB,aAAa;QACb,kBAAkB;QAClB,kBAAkB;QAClB,cAAc;QACd,qBAAqB;QACrB,8BAA8B;KAC/B,CAAA;AACH,CAAC","sourcesContent":["import * as React from 'react'\nimport { authService, Sentry } from '@oneblink/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 * isMfaCodeRequired,\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 (isMfaCodeRequired) {\n * return (\n * <form\n * onSubmit={(e) => {\n * e.preventDefault()\n * submitMfaCode()\n * }}\n * >\n * <p>Enter the 6-digit code found in your authenticator app.</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?.mfaCodeCallback\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?.mfaCodeCallback])\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 isMfaCodeRequired: !!loginAttemptResponse?.mfaCodeCallback,\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 /**\n * `true` if the user logged in using MFA and a code is required to finish the\n * login attempt. Prompt the user for a code and call `submitMfaCode()`.\n */\n isMfaCodeRequired: boolean\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"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@oneblink/apps-react",
3
3
  "description": "Helper functions for OneBlink apps in ReactJS.",
4
- "version": "5.13.0",
4
+ "version": "5.14.0-beta.1",
5
5
  "author": "OneBlink <developers@oneblink.io> (https://oneblink.io)",
6
6
  "bugs": {
7
7
  "url": "https://github.com/oneblink/apps-react/issues"
@@ -46,7 +46,7 @@
46
46
  "@mui/lab": "^5.0.0-alpha.152",
47
47
  "@mui/material": "^5.15.6",
48
48
  "@mui/x-date-pickers": "^6.19.2",
49
- "@oneblink/apps": "^11.1.0-beta.13",
49
+ "@oneblink/apps": "^11.2.0-beta.2",
50
50
  "@oneblink/release-cli": "^3.1.0",
51
51
  "@oneblink/types": "github:oneblink/types",
52
52
  "@types/blueimp-load-image": "^5.16.6",