1.0.8 • Published 2 years ago

@manacommon/web-auth v1.0.8

Weekly downloads
-
License
MIT
Repository
-
Last release
2 years ago

Mana Common WEB-AUTH

Mana Common web-auth is a collection of react components to handle all the mana common authentication.

Installation

To install the library, you can use npm or yarn:

yarn add @manacommon/web-auth

Compatibility

DependencyVersionRecommendation
Node16+Mandatory
React18+Recommended

Craco

All our packages are part of a monorepository architecture so Craco (Create React App Configuration Overrode) helps to keep all dependencies and configurations working.

In a monorepo, multiple packages or applications are managed within a single code repository, often using a tool like Lerna for dependency management and project orchestration.

When working with a monorepo, it's common to have shared React library packages that are used across different applications within the repository. These library packages may require custom configuration specific to each application.

By installing Craco as a dependency in the shared React library packages, developers gain the ability to modify the Create React App (CRA) configuration for each application without the need to eject from the default setup. This is crucial because ejecting from CRA can lead to complexities and difficulties in managing the shared codebase and dependencies.

You can install Craco in your project simply runing:

yarn add -D @craco/craco

or

npm i -D @craco/craco

Your craco.config.js should looks like:

const path = require('path');
const { getLoader, loaderByName } = require('@craco/craco');

const packages = [];

packages.push(path.join(__dirname, './node_modules/@manacommon/core'));
packages.push(path.join(__dirname, './node_modules/@manacommon/web'));
packages.push(path.join(__dirname, './node_modules/@manacommon/web-auth'));

module.exports = {
  webpack: {
    configure: (webpackConfig, arg) => {
      const { isFound, match } = getLoader(
        webpackConfig,
        loaderByName('babel-loader'),
      );
      if (isFound) {
        const include = Array.isArray(match.loader.include)
          ? match.loader.include
          : [match.loader.include];

        match.loader.include = include.concat(packages);
      }
      return webpackConfig;
    },
  },
};

Auth Flows

You can check the auth flow here

Set up your local configuration for social logins

In order to test the social logins there are some things that you have to do.

  1. Create a local record with your local IP pointing to https://tickets-localhost.manacommon.com. It is neccesary because all social logins have a whitelist for the redirectURI. In the case of the Apple does not allow to add a localhost URL.

Your hosts file should looks like:

##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1       localhost
255.255.255.255 broadcasthost
::1             localhost
# Added by Docker Desktop
# To allow the same kube context to work on the host and the container:
127.0.0.1 kubernetes.docker.internal
# End of section
127.0.0.1 tickets-localhost.manacommon.com
  1. Set up your local SSL certificate. You can and adding some scripts to your package.json and automate this process. You can check the example below. It is necessary because all social logins work only with HTTPS.
  "scripts": {
    "start": "craco start",
    "start:https": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "craco eject",
    "start:cert": "HTTPS=true HOST=tickets-localhost.manacommon.com SSL_CRT_FILE=/Users/your-mac-user-name/tickets-localhost.manacommon.com.cert SSL_KEY_FILE=/Users/your-mac-user-name/tickets-localhost.manacommon.com.key craco start",
    "cert": "devcert generate tickets-localhost.manacommon.com"
  },

NOTE: Before run start:cert you have to run cert in order to generate the cert and key, after that you have to copy the generated files to the SSL_CRT_FILE and SSL_KEY_FILE routes.

Demo Code

import React, { useEffect, useState } from "react";

import "./App.css";

import {
  type UserInformation,
  CreatePassword,
  LoginWithEmail,
  ForgotPassword,
  VerificationCode,
  Login,
  useConfig,
  SignUp,
  OnBoarding,
  useAuthentication,
  ValidateAccount,
  Welcome,
} from "@manacommon/web-auth";

import { PageWrapper } from "@manacommon/web";

enum RenderedPage {
  LOGIN,
  LOGIN_WITH_EMAIL,
  USER_LOGGED,
  SIGN_UP,
  ON_BOARDING,
  FORGOT_PASSWORD,
  VERIFICATION_CODE,
  CREATE_PASSWORD,
  VALIDATE_ACCOUNT,
  WELCOME,
}

function App() {
  const { getLoggedUserData } = useAuthentication();

  const { setConfiguration } = useConfig();

  const [currentPage, setCurrentPage] = useState(RenderedPage.LOGIN);
  const [userEmail, setUserEmail] = useState("");
  const [code, setCode] = useState("");

  useEffect(() => {
    const urlParams = new URLSearchParams(window.location.search);
    const userId = urlParams.get("userId");
    if (userId !== null) {
      setCurrentPage(RenderedPage.WELCOME);
    }
  }, []);

  const [userLogged, setUserLogged] = useState<UserInformation>();

  useEffect(() => {
    setConfiguration({
      ENVIRONMENT: "DEVELOP",
      TF_SSO_CLIENT: "your-tf-sso-client",
      TF_SSO_SECRET: "your-tf-sso-secret",
      SECRET_KEY: "your-mana-secret",
      CLIENT: "your-mana-client",
      ENABLE_TF_AUTHENTICATION: true
    });
  }, [setConfiguration]);

  const onLoginError = (error: any) => {
    console.log("Login error: ", error);
  };

  const handleGoToLoginWithEmail = () => {
    setCurrentPage(RenderedPage.LOGIN_WITH_EMAIL);
  };

  const handlegoToSignUp = () => {
    console.log("going to sign up");
    setCurrentPage(RenderedPage.SIGN_UP);
  };

  const handleCompleteVerification = () => {
    setCurrentPage(RenderedPage.ON_BOARDING);
  };

  const handleOnSubmitSignup = () => {
    setCurrentPage(RenderedPage.VALIDATE_ACCOUNT);
  };

  const handleLoginSuccess = async () => {
    const userData = await getLoggedUserData();
    setUserLogged(userData);

    if (userData.communityId === null) {
      setCurrentPage(RenderedPage.ON_BOARDING);
    } else {
      setCurrentPage(RenderedPage.USER_LOGGED);
    }
  };

  const handleGoToForgotPassword = () => {
    setCurrentPage(RenderedPage.FORGOT_PASSWORD);
  };

  const renderPage = () => {
    switch (currentPage) {
      case RenderedPage.LOGIN:
        return (
          <Login
            redirectUri="https://tickets-localhost.manacommon.com:3000"
            handleLoginWithEmail={handleGoToLoginWithEmail}
            handleSignUp={handlegoToSignUp}
            onLoginSuccess={handleLoginSuccess}
          />
        );
      case RenderedPage.LOGIN_WITH_EMAIL:
        return (
          <LoginWithEmail
            onLoginError={onLoginError}
            onLoginSuccess={handleLoginSuccess}
            onSignUp={handlegoToSignUp}
            onForgotPassword={handleGoToForgotPassword}
          />
        );
      case RenderedPage.USER_LOGGED:
        return <PageWrapper>User Logged! {userLogged?.email}</PageWrapper>;
      case RenderedPage.SIGN_UP:
        return (
          <SignUp
            onSubmit={handleOnSubmitSignup}
            onNavigateSignIn={() => setCurrentPage(RenderedPage.LOGIN)}
            onClickTerms={() =>
              window.open("https://app.manacommon.com/terms-of-use", "_blank")
            }
            externalRegisterEmailLink={
              "https://tickets-localhost.manacommon.com:3000/"
            }
          />
        );

      case RenderedPage.FORGOT_PASSWORD:
        return (
          <ForgotPassword
            showBackButton
            onClickBack={() => setCurrentPage(RenderedPage.LOGIN_WITH_EMAIL)}
            onSendEmail={(emailOrPhone) => {
              setUserEmail(emailOrPhone);
              setCurrentPage(RenderedPage.VERIFICATION_CODE);
            }}
          />
        );
      case RenderedPage.VERIFICATION_CODE:
        return (
          <VerificationCode
            onComplete={(code: string) => {
              setCode(code);
              setCurrentPage(RenderedPage.CREATE_PASSWORD);
            }}
            userEmail={userEmail}
          />
        );
      case RenderedPage.CREATE_PASSWORD:
        return (
          <CreatePassword
            email={userEmail}
            code={code}
            onConfirm={() => setCurrentPage(RenderedPage.LOGIN)}
          />
        );
      case RenderedPage.VALIDATE_ACCOUNT:
        return <ValidateAccount />;

      case RenderedPage.WELCOME:
        return <Welcome onCompleteVerification={handleCompleteVerification} />;

      case RenderedPage.ON_BOARDING:
        return (
          <OnBoarding
            userId={userLogged?.id ?? ""}
            onComplete={() => setCurrentPage(RenderedPage.USER_LOGGED)}
          />
        );
      default:
        return <Login />;
    }
  };

  return (
    <div className="App">
      <h3>@manacommon/web Example project</h3>
      {renderPage()}
    </div>
  );
}

export default App;

Configuration

To config the library you have set somes keys. For this you need to use useConfig hook.

NOTE: The vaid ENVIRONMENT values are: DEVELOP, STAGING, UAT and PROD

Web Configuration type

{
  CLIENT: string;
  SECRET_KEY: string;
  ENABLE_TF_AUTHENTICATION: boolean;
  ENVIRONMENT: Env;
  TIMEOUT: number;
  TF_SSO_CLIENT: string;
  TF_SSO_SECRET: string;
}

Example

import { useConfig } from '@manacommon/web-auth';

const App = () => {
  const { setConfiguration } = useConfig();

  useEffect(() => {
    setConfiguration({
      ENVIRONMENT: 'your_environment_name', // DEVELOP - STAGING - UAT - PROD. Default value: DEVELOP
      TF_SSO_CLIENT: 'your_TF_client_key', // Default value: empty
      TF_SSO_SECRET: 'your_TF_secret_key', // Default value: empty
      SECRET_KEY: 'your_secret_key', // Default value: empty
      CLIENT: 'your_client_key', // Default value: empty
      ENABLE_TF_AUTHENTICATION: true, // Enables or disables the ticket fairy authentication - Default value: true
    });
  }, [setConfiguration]);

  return (
    // Here you should render your app
  );
};

Documentation

Components

SignUp

Component with form to sign up a new user. Fields:

  • Name
  • Lastname
  • Email
  • Password
  • Confirm Password

Props

NameTypeRequiredDefaultDescription
onSubmit() => voidtrue-Function to execute after signup proccess end.
showLogobooleanfalsetrueIndicates whether to display the mana logo
errorsobjectfalse-Object to store errors
onNavigateSignIn() => voidfalse-Function to navigate to the sign-in page
onClickTerms() => voidfalse-Function to handle the click event for terms
stylesobjectfalsedefaultStylesCustom styles objects
onError(error:any) => voidfalse-Function to handle errors
onChangeData(data: IFormData) => voidfalse-Function to handle data change
externalRegisterEmailLinkstringtrue-External link to add on email confirmation. Should be url that contains the ActivateAccount component or another screen that calls the activate endpoint exported on useSignUp hook.
textsobjectfalsedefaultTextsCustom texts object
interface IFormData {
  name: string;
  lastName: string;
  email: string;
  password: string;
  confirmPassword: string;
}

interface ISignUpProps {
  showLogo?: boolean;
  onSubmit: () => void;
  onError?: (error: any) => void;
  /**
   * Errors object with this keys:
   * - name
   * - lastName
   * - email
   * - password
   * - confirmPassword
   */
  errors?: IFormData;
  /**
   * Navigation to sign in screen
   */
  onNavigateSignIn?: () => void;
  /**
   * Action or navigations to execute after pres on EULA terms
   */
  onClickTerms?: () => void;
  /**
   * Custom styles to diferents sections
   */
  styles?: {
    container?: CSSProperties,
    title?: CSSProperties,
    subtitle?: CSSProperties,
    formContainer?: CSSProperties,
    inputsContainer?: CSSProperties,
    terms?: CSSProperties,
    root?: {
      container?: CSSProperties,
      header?: CSSProperties,
      backButtonWrapper?: CSSProperties,
      logoWrapper?: CSSProperties,
    },
    passwordWrapper?: CSSProperties,
  };
  /**
   * Custom texts
   *
   */
  texts?: {
    title: string,
    subTitle: string,
    signIn: string,
    usernameInUse: string,
    invalidPassword: string,
    termsText: string,
    inputName: string,
    inputLastname: string,
    inputEmail: string,
    inputPassword: string,
    inputConfirmPassword: string,
    submitButton: string,
    validations?: {
      characters: string,
      uppercase: string,
      number: string,
      specialCharacter: string,
    },
  };
  onChangeData?: (data: IFormData) => void;
  /**
   *  This links it's added on the verification email.
   *
   *  Should be the url to go back when users press on 'Confirm Email'.
   *
   *  Should be url that contains the ActivateAccount component or another screen
   *  that calls the activate endpoint exported on useSignUp hook.
   */
  externalRegisterEmailLink: string;
  /**
   * Page wrapper options
   */
  showBackButton?: boolean;
  onClickBack?: () => void;
}

Example

import { SignUp } from "@manacommon/web-auth";
import { useNavigate } from 'react-router';

const SignUpScreen = () => {
    const [showModal, setShowModal] = useState(false);
    const navigate = useNavigate();

    const ExampleModal = () => {
        return <div> "(Terms information here)" </div>
    }

    return (
        <SignUp
            onSubmit={() => navigate("/home")}
            onNavigateSignIn={() => navigate("/sign-in")}
            onClickTerms={() => setShowModal(true)}
            externalRegisterEmailLink={"https://www.exampleweb.com/account_verification"}
            styles={{ container: { padding: 24 } }}
            texts={{ title: "Example title" }}
        />
        <ExampleModal isVisible={showModal} />
    )
}

CreatePassword

Components to create a new password with his validations tags under the inputs. You could use custom or default validations.

Props

NameTypeRequiredDefaultDescription
customValidationsIValidation[]falsedefaultValidationsCustom validations array
showLogobooleanfalsetrueIndicates whether to show the mana logo
onConfirm(password: string, confirmPassword: string) => voidtrue-Function to handle confirmation
stylesobjectfalsedefaultStylesCustom styles object
textsobjectfalsedefaultTextsCustom texts object
interface ICreatePasswordProps {
  customValidations?: IValidation[];
  showLogo?: boolean;
  onConfirm: (password: string, confirmPassword: string) => void;
  texts?: CreatePasswordTexts;
  styles?: {
    root?: {
      container?: CSSProperties,
      header?: CSSProperties,
      backButtonWrapper?: CSSProperties,
      logoWrapper?: CSSProperties,
    },
    container?: CSSProperties,
    manaLogo?: CSSProperties,
    inputPassword?: CSSProperties,
    inputConfirm?: CSSProperties,
    centerContainer?: CSSProperties,
    button?: CSSProperties,
  };
  email: string;
  code: string;
  /**
   * Page wrapper options
   */
  showBackButton?: boolean;
  onClickBack?: () => void;
}

Default Validations

  • 1 number
  • 1 Uppercase
  • 1 Special character
  • Length from 7 to 16

Example

import { CreatePassword } from '@manacommon/web-auth';
import { useNavigate } from 'react-router';

const CreatePasswordScreen = () => {
  const navigate = useNavigate();
  const validateLength = (value: string) => {
    return value.length >= 7 && value.length <= 16;
  };

  const customValidations = [
    {
      label: '7-16 characters',
      isApproved: false,
      id: 1,
      validationFn: validateLength,
    },
  ];

  const onConfirm = () => {
    navigate('/login');
  };

  return (
    <CreatePassword
      onConfirm={onConfirm}
      customValidations={customValidations}
      styles={{ inputConfirm: { paddingTop: 16 } }}
      texts={{
        placeholders: {
          password: 'Enter password',
          confirmPassword: 'Enter password confirmation',
        },
      }}
    />
  );
};

VerificationCode

Component with N fields to enter the verification code sended to email. The default length is 4.

Props

NameTypeRequiredDefaultDescription
onClickResend() => voidfalseundefinedFunction to handle click event for resend email action
showLogobooleanfalsetrueIndicates whether to display the mana logo
onComplete() => voidtrue-Function to handle click on complete button
stylesobjectfalsedefaultStylesCustom styles object
textsobjectfalsedefaultTextsCustom texts object
codeLengthnumberfalse4Length of the code for verification
interface IVerificationCodeProps {
  showLogo?: boolean;
  onClickResend?: () => void;
  onComplete: (code: string) => void;
  codeLength?: number;
  styles?: {
    root?: {
      container?: CSSProperties,
      header?: CSSProperties,
      backButtonWrapper?: CSSProperties,
      logoWrapper?: CSSProperties,
    }
    container?: CSSProperties,
    manaLogo?: CSSProperties,
    centerContainer?: CSSProperties,
    codeContainer?: CSSProperties,
    link?: CSSProperties,
    title?: CSSProperties,
  };
  texts?: {
    title?: string,
    linkFirstText?: string,
    linkSecondText?: string,
  };
  userEmail: string;
}

Example

import { VerificationCode } from '@manacommon/web-auth';
import { useNavigate } from 'react-router';

const CreatePasswordScreen = () => {
  const navigate = useNavigate();
  const validateLength = (value: string) => {
    return value.length >= 7 && value.length <= 16;
  };

  const onComplete = () => {
    navigate('/login');
  };

  return (
    <VerificationCode
      onComplete={onComplete}
      codeLength={5}
      styles={{ title: { color: 'red' } }}
      texts={{ title: 'New title' }}
    />
  );
};

Welcome

Render a loader and call the function to activate account. After a seconds show a welcome message or an error if the request fail.

Props

NameTypeRequiredDefaultDescription
onCompleteVerification(data: IApiConfirmEmailData) => voidtrue-Receive username and token
stylesobjectfalsedefaultStylesCustom styles object
textsobjectfalsedefaultTextsCustom texts object
interface IWelcomeProps {
  texts?: WelcomeTexts;
  styles?: {
    root?: {
      container?: CSSProperties,
      header?: CSSProperties,
      backButtonWrapper?: CSSProperties,
      logoWrapper?: CSSProperties,
    },
    container?: CSSProperties,
    icon?: CSSProperties,
    title?: CSSProperties,
  };
  onCompleteVerification: (data: IApiConfirmEmailData) => void;
}

Example

import { Welcome } from '@manacommon/web-auth';
import { useNavigate } from 'react-router';

const CreatePasswordScreen = () => {
  const navigate = useNavigate();

  const handleCompleteVerification = (data: IApiConfirmEmailData) => {
    // data information :
    //   - token: string;
    //   - refreshToken: string;
    //   - username: string;
    //   - isLockedOut: boolean;
    //   - isNotAllowed: boolean;

    console.log('This is the token to save -> ', data.token);
  };

  return <Welcome onCompleteVerification={handleCompleteVerification} />;
};

ForgotPassword

Props

NameTypeRequiredDefaultDescription
onSendEmail(emailOrPhone: string) => voidtrue-Function to execute after email is sended
stylesobjectfalsedefaultStylesCustom styles object
textsobjectfalsedefaultTextsCustom texts object
interface IForgotPasswordProps {
  onSendEmail: (emailOrPhone: string) => void;
  styles?: {
    centerContainer?: CSSProperties,
    input?: CSSProperties,
    button?: CSSProperties,
    root?: CSSProperties,
  };
  texts?: ForgotPasswordTexts;
  /**
   * Page wrapper options
   */
  showBackButton?: boolean;
  onClickBack?: () => void;
}

Example

import { ForgotPassword } from '@manacommon/web-auth';
import { useNavigate } from 'react-router';

const ForgotPasswordScreen = () => {
  const navigate = useNavigate();

  const handleOnSendEmail = (emailOrPhone: string) => {
    // You have to navigate to verification code screen
    navigate('/verification_code');
  };

  return <ForgotPassword onSendEmail={handleOnSendEmail} />;
};

Login

NameTypeRequiredDefaultDescription
handleLoginWithEmail() => voidfalse-Function to navigate to login with email screen
handleSignUp() => voidtrue-Function navigate to sign up
onLoginSuccess(data: ILoginResult ) => voidfalse-
onLoginFail(error: any) => voidfalse--
stylesobjectfalsedefaultStylesCustom styles object
textsobjectfalsedefaultTextsCustom texts object
enabledProvidersobjectfalse-Used to custom enable or disable the external logins
redirectUristringfalse-Used internaly by LoginButtons to add a custom redirection for external logins
interface ILoginProps {
  handleLoginWithEmail?: () => void;
  handleSignUp?: () => void;
  onLoginSuccess?: (data: ILoginResult | undefined) => void;
  onLoginFail?: (error: any) => void;
  texts?: LoginTexts;
  redirectUri?: string;
  enabledProviders?: IEnabledLogins;
  styles?: {
    root?: {
      container?: CSSProperties,
      header?: CSSProperties,
      backButtonWrapper?: CSSProperties,
      logoWrapper?: CSSProperties,
    }
    loginWrapper?: CSSProperties,
    footer?: CSSProperties,
  };
}

Example

import { Login } from '@manacommon/web-auth';
import { useNavigate } from 'react-router';

const LoginScreen = () => {
  const navigate = useNavigate();

  const handleGoToLoginWithEmail = () => {
    navigate('/login_with_email');
  };

  const handlegoToSignUp = () => {
    navigate('/sign_up');
  };

  return (
    <Login
      handleLoginWithEmail={handleGoToLoginWithEmail}
      handleSignUp={handlegoToSignUp}
    />
  );
};

LoginWithEmail

NameTypeRequiredDefaultDescription
onLoginSuccess(result: ILoginResult) => voidfalse-Function to execute after request success
onLoginError(error: any) => voidfalse-Function to execute if request fail
onForgotPassword() => voidfalse-Function to execute when the user press in the link
onSignUp() => voidfalse-Function to execute when the user press in the link
stylesobjectfalsedefaultStylesCustom styles object
textsobjectfalsedefaultTextsCustom texts object
interface LoginWithEmailProps {
  onLoginSuccess?: (result: OnLoginSuccess) => void;
  onLoginError?: (error: any) => void;
  onForgotPassword?: () => void;
  onSignUp?: () => void;
  texts?: LoginWithEmailTexts;
  styles?: {
    root?: {
      container?: CSSProperties,
      header?: CSSProperties,
      backButtonWrapper?: CSSProperties,
      logoWrapper?: CSSProperties,
    },
    loginBoxWrapper?: CSSProperties,
    inputWrapper?: CSSProperties,
    footer?: CSSProperties,
  };
  /**
   * Page wrapper options
   */
  showBackButton?: boolean;
  onClickBack?: () => void;
}

Example

import { LoginWithEmail } from '@manacommon/web-auth';
import { useNavigate } from 'react-router';

const LoginWithEmailScreen = () => {
  const navigate = useNavigate();

  const onLoginSuccess = (result: ILoginResult) => {
    // results information:
    //  - tfAccessToken?: string;
    //  - tfRefreshToken?: string;
    //  - tfScope?: string;
    //  - tfTokenType?: string;
    //  - userInformation: IApiUserInformation;

    navigate('/home');
  };

  const onLoginError = (error: any) => {
    console.log('Login error: ', error);
  };

  return (
    <LoginWithEmail
      onLoginError={onLoginError}
      onLoginSuccess={onLoginSuccess}
    />
  );
};

OnBoarding

Props

interface IOnBoardingProps {
  userId: string;
  texts?: OnBoardingTexts;
  initialStepConfig?: {
    step: OnBoardingStep,
    cityId?: number,
  };
  styles?: {
    root?: {
      container?: CSSProperties,
      header?: CSSProperties,
      backButtonWrapper?: CSSProperties,
      logoWrapper?: CSSProperties,
    },
  };
  onNext?: () => void;
  onPrevious?: () => void;
  onComplete?: () => void;
}

Example

import { OnBoarding } from '@manacommon/web-auth';

const OnBoardingExample = () => {
  const [userLogged, setUserLogged] = useState<UserInformation>();

  useEffect(()=> {
    /**
     * You can get the user information from the verificate account or any login component
     */
  })

  return (
    <OnBoarding
      userId={userLogged?.id ?? ''}
      onComplete={() => console.log('on boarding completed!')}
    />
  );
};

Hooks

useSignUp

signUp

Function to sign up a new user. Receives:

ParameterType
lastnamestring
namestring
usernamestring
passwordstring
roleNameRoles
externalRegisterboolean
externalRegisterEmailLinkstring

Example

import { RegisterErrors, Roles } from '@manacommon/core/src/models';
import { useSignUp } from '@manacommon/core/src/hooks';

const { signUp } = useSignUp();

const handleError = (error: any): void => {
  if (error.response.data.errorCode === RegisterErrors.USERNAME_IN_USE) {
    // Actions if email exist
  }
  // Other actions to handle error
};
const handleSignUp = async (): Promise<void> => {
  try {
    await signUp({
      lastname: 'Smith',
      name: 'Arnold',
      username: 'asmith@gmail.com',
      password: 'Qwerty1234.',
      roleName: Roles.Guest,
      externalRegister: true,
      externalRegisterEmailLink:
        'https://www.exampleweb.com/account_verification',
    });
    // On succes actions goes here
  } catch (e: any) {
    handleError(e);
  }
};

confirmEmail

Function to confirm validation from email. Receives:

ParameterType
userIdstring
tokenstring

Example

import { Loader } from '@manacommon/web';
import { useSignUp } from '@manacommon/core/src/hooks';

const WelcomeScreen = () => {
  const [isLoading, setIsLoading] = useState(true);
  const { confirmEmail } = useSignUp();
  const urlParams = new URLSearchParams(window.location.search);
  // Get user id by url
  const userId = urlParams.get('userId');
  // Get token by url
  const token = urlParams.get('verificationToken');

  useEffect(() => {
    const completeRegister = async (): Promise<void> => {
      if (userId !== null && token !== null) {
        try {
          const data = await confirmEmail(userId, token);
          setIsLoading(false);
        } catch {
          setIsLoading(false);
        }
      }
    };

    void completeRegister();
  }, [userId]);

  {
    isLoading ? <Loader /> : <div>{/* Welcome information goes here */}</div>;
  }
};

useAuthentication

Functions and params

export interface IExternalAuthRequest {
  provider: ApiExternalLoginProviders;
  idToken?: string;
  name?: string;
  lastName?: string;
  accessToken?: string;
}

export interface IUseAuthentication {
  getLoggedUserData: () => Promise<UserInformation>;
  handleLogin: (
    email: string,
    password: string,
    onSuccess?: (result: ILoginResult) => void,
    onError?: (error: any) => void,
  ) => Promise<ILoginResult | undefined>;
  handleLoginExternal: (
    request: IExternalAuthRequest,
    onSuccess?: (userInfo: any) => void,
    onError?: (error: any) => void,
  ) => Promise<ILoginResult | undefined>;
  sendForgotPasswordEmail: (emailOrPhone: string) => Promise<void>;
  checkValidCode: (email: string, code: string) => Promise<boolean>;
  changePassword: (
    email: string,
    code: string,
    password: string,
  ) => Promise<boolean>;
}

Import and use example

import useAuthentication from '@manacommon/web-auth';

const { handleLogin } = useAuthentication();

Login example

const handleLoginSuccess = (response: ILoginResult) => {
  // Do what do you need with the response
};

handleLoginError = (error: any) => {
  // Handle login error here
};

const handleSubmit = async (email: string, password: string): Promise<void> => {
  await handleLogin(email, password, handleLoginSuccess, handleLoginError);
};

Login external example

const handleExternalLogin = async (
  /*
   * Have to be access_token for google or id_token for facebook and apple.
   * You will get this data from <SocialButtons/> callbacs
   */
  token: string,
  provider: ApiExternalLoginProviders, // GOOGLE - FACEBOOK - APPLE
  onLoginSuccess?: (data: ILoginResult | undefined) => void,
  onLoginFail?: (error: any) => void,
): Promise<ILoginResult | undefined> => {
  const request: IExternalAuthRequest = { provider };

  if (provider === 'FACEBOOK' || provider === 'apple') {
    request.idToken = token;
  } else {
    request.accessToken = token;
  }

  try {
    const result = await handleLoginExternal(request);
    if (onLoginSuccess) {
      onLoginSuccess(result);
    }
    return result;
  } catch (error) {
    if (onLoginFail) {
      onLoginFail(data);
    }
  }
};

Troubleshooting

  • If you have created your project using CRA, maybe get a warning about babel in the console. In that case you can add this "@babel/plugin-proposal-private-property-in-object": "^7.21.11"`` asdev dependency` to avoid it.

Change Log

Version 1.0.4

  • Documentation update
  • Fixed issue with isSafari check
  • Fixed PageWrapper style property not being passed in Login component
  • Fixed PageWrapper style property not being passed in ForgotPassword component
  • Fixed PageWrapper style property not being passed in SignUp component
  • Fixed LoginWithEmail style property not being passed for login box and login box footer

Version 1.0.5

  • Update Documentation
  • Fixed configuration environment values
  • Updated config prop names for setConfiguration. (see documentation)
  • Updated root custom styles for: Login, OnBoarding, ValidateAccount, VerificationCode, Welcome, LoginWithEmail, CreatePassword, ForgotPassword and SignUp components. Now the type is IPageWrapperCustomStyle instead of CSSProperties. (see documentation)
  • Fixed goback in onboarding
  • Now LoginWithEmail, CreatePassword, ForgotPassword and SignUp components has a showBackButton flag and onClickBack callback. (See documentation)
  • Add new default validation messages for: LoginWithEmail, SignUp and CreatePassword components. (see documentation)

Version 1.0.6

  • ForgotPassword: param to add title styles
  • LoginWithEmail: param to add title styles
  • Disabled button bug fixed

Version 1.0.7

  • Fixed login-config params for useAuthentication hook

Version 1.0.8

  • We update @manacommon/core in order to add tfResponseHeaders to onLoginSuccess callbacks