3.5.1 • Published 2 months ago

dha-login v3.5.1

Weekly downloads
1
License
-
Repository
-
Last release
2 months ago

dha-login

Getting Started

Install

Install from npm:

  • npm i dha-login

Build

The package uses the Typescript compiler (TSC) & Vite to build the source code. To build the project run the following command:

  • npm run build

Peer Dependencies

These are the peerDependencies for dha-login. Make sure your app has these installed as dependencies if you want to use dha-login.

"peerDependencies": {
  "@reduxjs/toolkit": "^1.8.1",
  "react": "^17.0.2",
  "react-redux": "^7.2.8",
  "react-router-dom": "^6.3.0"
}

Usage Overview

This module should be used if you want login functionality in your PWA. This functionality involves prompting a user to make an "account" by designating a 6-digit pin & two security questions. The pin will be used on every subsequent login to identify the user, and correctly answering the security questions can authorize the user to reset their pin for any reason.

There are a few pieces from this module that you will need to configure inside your app:

  • Redux State
    • accountReducer
    • AccountState (type)
    • initialAccountState
  • Providers
    • <LoginDatabaseProvider /> - wrapper containing access to user login info
    • <AuthProvider /> - wrapper inside <LoginDatabaseProvider /> that handles authentication & provides access to AuthContext
  • Components (Routing)
    • <RequireAuth /> - wraps any routes you want only accessible by authenticated (logged-in) users, providing the screens necessary for user authentication.
  • Context

    • {AuthContext} - holds authenticated (logged-in) state boolean, a setter for that state (setAuthenticated), the username set by the current user, and the setter for setting the username variable.

    If you plan on using this module in the pwa-starter, make sure to edit the starter's 'tailwind.config.cjs' file with the following code (to tell tailwind to scan dha-login for tailwind classes):

    module.exports = {
      content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}', './node_modules/dha-login/**/*.js'],
    };

Redux State

Relevant exports:

  • accountReducer
  • AccountState (type)
  • InitialAccountState

Details

accountReducer, AccountState (type), and initialAccountState will be utilized to ensure that a user's "account created?" state (either true or false) remains even after they close the app.

The accountReducer reducer controls a a boolean state-value "created" that indicates whether or not the user has made an "account."

accountReducer is created using createSlice() from Redux Toolkit. You will need to add accountReducer to your root reducer. Most likely this will be done by including it in your combineReducers() function, which combines multiple reducers into one rootReducer. for example:

Implementation

example rootReducer.ts:

import { combineReducers } from '@reduxjs/toolkit';

import { accountReducer, AccountState, initialAccountState } from 'dha-login'; // Redux elements

export type State = {
  counterState: CounterState,
  eulaState: EulaState,
  accountState: AccountState, // AccountState type defines accountState prop of State type
};

export const initialState: State = {
  counterState: initialCounterState,
  eulaState: initialEulaState,
  accountState: initialAccountState, // initialAccountState
};

export const rootReducer = combineReducers({
  counterState: counterSlice,
  eulaState: eulaSlice,
  // key name for accountReducer MUST be "accountState"
  accountState: accountReducer, // accountReducer is added to rootReducers
});

!! IMPORTANT NOTE !!: In the root reducer, the key for the accountReducer MUST be "accountState." This is because <RequireAuth /> accesses that bit of state by that exact key.

!! You will also need to whitelist accountState in your redux-persist config (likely in your store.ts file, see example below) !!:

example store.ts:

const persistConfig = {
  key: 'root',
  storage,
  whitelist: ['eulaState', 'endorsementState', 'androidViewState', 'accountState'],
};

const store = configureStore({
  reducer: persistReducer(persistConfig, rootReducer),
  preloadedState: initialState,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
      },
    }),
});

The whitelist property controls which parts of your redux state actually get persisted across all sessions. See redux-persist documentation if you want more specific details.

Providers

Relevant Exports

  • <LoginDatabaseProvider />
  • <AuthProvider />

Details

<LoginDatabaseProvider /> and <AuthProvider /> should be wrapped somewhere around your <Routes />.

<LoginDatabaseProvider /> should wrap around <AuthProvider /> in your app (AuthContext depends on <LoginDatabaseProvider /> for authentication functionality).

  • <AuthProvider /> gives its children access to {AuthContext}, and stores base64-encoded authenticated state from {AuthContext} in Session Storage in order to persist authentication-state through page refresh.
  • <LoginDatabaseProvider /> gives <AuthProvider /> necessary database access (user "account" information).

Implementation

Your nesting should look something like this: example App.tsx:

import { AuthProvider, LoginDatabaseProvider } from 'dha-login';

const App = () => {
  return (
    //<BrowserRouter > or some other Router...
    <Provider store={store}>
      <PersistGate persistor={persistor}>
        <LoginDatabaseProvider>
          <DialogProvider>
            <AuthProvider>
              <Layout>
                <AppRoutes />
              </Layout>
            </AuthProvider>
          </DialogProvider>
        </LoginDatabaseProvider>
      </PersistGate>
    </Provider>
    //</BrowserRouter>
  );
};

Components

Relevant Exports

  • <RequireAuth />

Details

Use <RequireAuth /> to wrap any <Route /> that you want to only be accessible by a logged-in user.

You will use this component wherever you have set up routing for your app (using React Router).

Make a <Route /> for <RequireAuth />, and use it to wrap any other <Route />'s you only want accessible by the authenticated user.

Implementation

example AppRoutes.tsx:

import { RequireAuth } from 'dha-login';

import Home from 'somewhere/Home.tsx';

<Routes>
  <Route element={<RequireAuth />}>
    <Route element={<Home />} path="/" />
    <Route element={<Protected2 />} path="/protectedRoute2" />
  </Route>
</Routes>;

Context

Relevant Exports

  • {AuthContext}
    • contains:
      • username - string given by user during initial account setup
      • authenticated - boolean state value where true means the user is currently 'logged in'
      • setAuthenticated(booleanValue) - function you can use to log a user out by setting authenticated to false
      • setUsername(string) - function that allows username to be set, shouldn't be necessary but it's there if you need it

Details

{AuthContext} can be used via React.useContext() to access the authenticated state, and the setter for that state, setAuthenticated()

when authenticated state is true, <RequireAuth /> allows its child (protected) routes to be accessed/rendered.

when authenticated state is false, <RequireAuth /> prompts the user for their pin, or allows them to reset their PIN by answering two security questions set up during account creation.

you can use setAuthenticated(false) to log the user out. A user will also be logged out automatically an hour after logging-in, and will have to re-log.

Implementation

import { useContext } from 'react';

import { AuthContext } from 'dha-login';

const exampleComponent = () => {
  const { authenticated, setAuthenticated, username } = useContext(AuthContext);
  // authenticated returns true or false
  // setAuthenticated(false) sets authenticated to false, effectively logging a user out
  // username is the string the user set as their username upon account creation
  // ...
};

Theme

Relevant Exports

  • {themeProps}
  • {useUpdateTheme}

Details

You can update the theme of dha-login using {useUpdateTheme} by passing in a {themeProps} object. You call this function in a useEffect wherever you have set up routing for your app (using React Router). You must use tailwindcss in the {themeProps} object to modify the theme.

Implementation

example AppRoutes.tsx:

import { useUpdateTheme } from 'dha-login';
import type { themeProps } from 'dha-login';

const updater = useUpdateTheme();

useEffect(() => {
  const theme: themeProps = {
    modalBackground: 'bg-gradient-to-b from-gradient-light to-gradient-dark',
    cardColor: 'bg-white',
    textColor: 'text-black',
    secondaryTextColor: 'text-secondary-color',
    buttonColor: 'bg-secondary-color',
    buttonTextColor: 'text-theme-dark-grey',
    buttonShadow: 'shadow-card',
    dropDownBorder: 'border border-solid border-[#6b7280]',
  };
  updater(theme);
}, []);
themeProps

Properties you can modify to update the theme.

interface themeProps {
  modalBackground?: string;
  cardColor?: string;
  textColor?: string;
  secondaryTextColor?: string;
  buttonColor?: string;
  buttonTextColor?: string;
  buttonShadow?: string;
  dropDownBorder?: string;
}

Troubleshooting

Npm Install Issues

  • Clearing the package-lock.json and node_modules folder can help ensure that an app or package starts in a clean state.
    • rm -rf package-lock.json node_modules

Hook Errors

  • Hook errors can be caused when a local package is installed into an application where the package devDependencies conflict with the application dependencies by having multiple instances of the same dependency.
  • You must tell the local dha-login to use peerDependencies from the app you are including the dha-login into using npm link (the example below is for using the dha-login in the dha-login).
    • Refer to "Link peerDependencies" section above.
      • npm link ../dha-login/node_modules/@material-ui/core

NPM

https://www.npmjs.com/package/dha-login

License

pending

3.5.1

2 months ago

3.5.0

2 months ago

3.4.2

4 months ago

3.4.0

4 months ago

3.4.1

4 months ago

3.3.0

4 months ago

3.2.1

9 months ago

3.1.0

11 months ago

3.0.3

1 year ago

3.0.2

1 year ago

3.0.1

1 year ago

3.0.0

1 year ago

3.0.3-alpha2

1 year ago

3.0.3-alpha1

1 year ago

2.0.0

2 years ago

1.1.5

2 years ago

1.1.4

3 years ago

1.1.3

4 years ago

1.1.2

4 years ago

1.1.1

4 years ago

1.1.0

4 years ago

1.0.4

5 years ago

1.0.3

5 years ago

1.0.2

5 years ago

1.0.1

5 years ago