@pass-culture/id-check

2.11.1 • Public • Published

@pass-culture/id-check

ID Check module can be used to implement identity check in an existing application.

It is build with React Native, and it supports iOS, Android and Web targets.

Table of Contents


Installation

yarn add @pass-culture/id-check

You must install the peer dependencies.

react-native

yarn add react-native-modal

If you have not done it yet, install all the peerDependencies (see package.json)

If you want to use the repo instead of the node_module in a project, run:

yarn link "@pass-culture/id-check"

react-native-web

yarn add modal-enhanced-react-native-web react-native-svg-web react-native-web-lottie

Edit your resolve.alias webpack configuration with:

+ 'react-native-modal$': 'modal-enhanced-react-native-web',
+ 'react-native-svg': 'react-native-svg-web',
+ 'lottie-react-native': 'react-native-web-lottie',

Edit your moduleNameMapper jest configuration with:

+ 'react-native-modal$': 'modal-enhanced-react-native-web',
+ 'react-native-svg': 'react-native-svg-web',
+ 'lottie-react-native': 'react-native-web-lottie',

API

Those are exports exposed:

Export name Type Description
IdCheckContextProvider React.Component The IdCheck context
useIdCheckContext React.Hook Read the whole IdCheck context (can be useful to know the id check state)
IdCheckAnalyticsInterface Interface Interface used to create a custom Id Check analytics client
IdCheckErrorMonitoringInterface Interface Interface used to create a custom error monitoring client
routes Array<Route> Array of all IDCheck routes
IdCheckRootStackParamList Interface Stack params for each screens required by the route. Only for TypeScript to know each Id Check route params
initialRouteName string The home screen name of Id Check
linkingConfig LinkingOptions Linking configuration for React Navigation
IdCheckHomePage React.Component The Id Check Home page including error boundary, auth persistence, auth and security checkpoint
cameraOptions CameraOptions Default options used in react-native-image-picker when taking pictures
imageLibraryOptions ImageLibraryOptions Default options used in react-native-image-picker when opening image gallery
CampaignTrackerInterface Interface Interface used for tracking campaign events: startIdCheckTrack, uploadDocuments, accountCreated and email
IdCheckRetentionClient Interface Interface used to create a retention client, used when retention mode is active

Required for demonstration purpose by the Native application, we also added those to exports:

Export name Type Description
IdCheckErrors Enum Enum with all Id Check errors
IdCheckError IdCheckError Error object used to throw Id Check custom error
withAsyncErrorBoundary HoC Error boundary higher order component for Id Check
Educonnect React.Component Educonnect page that navigates to educonnect webview

Usage

You must wrap your React application within an <IdCheckContextProvider />.

The module can be configured by injecting props into the ID Check context:

ID Check context props Type Required Default Description
Initialization
initialStep Step No id-check Initial step (only useful in retention mode)
URLs
jouveApiBaseUrl string Yes Base URL used for Id Check API call
homePageUrl string Yes Base URL used for success redirection
supportEmail string Yes Email address used for support links
dsmUrl string Yes URL for DSM links
personalDataDocUrl string Yes URL for personal data documentation
cguDocUrl string Yes URL for usage right documentation
dmsFrenchCitizenshipUrl string Yes URL for DMS french citizen
dmsForeignCitizenshipUrl string Yes URL for DMS foreign citizen
Features flips
displayDmsRedirection boolean No Display a DMS redirections when active
retention boolean Yes Set and switch to retention mode
shouldUseEduConnect boolean Yes Enable eduConnect identification method
Services
analytics IdCheckAnalyticsInterface Yes Services used for tracking analytics events
errorMonitoring IdCheckErrorMonitoringInterface Yes Services used for error monitoring
campaignTracker CampaignTrackerInterface Yes Services used for campaign tracking
requestLicenceToken Promise<{ licence_token: string, expiration_timestamp: number }> No Fetch request client can be provided to allow user to get a new licence_token when necessary
retentionClient IdCheckRetentionClient<RetentionIdDocumentResponse> No Services used when retention is active
eduConnectClient EduConnectClient No Services used when eduConnect identification method is active
Events
onAbandon ({ pageName, form }: { pageName: string, form: Record<string, unknown> }) => void Yes Callback used when user abandon the identity check
onSuccess () => void Yes Callback used when user successfully end the identity check
Camera
imagePickerOptions ImagePickerOptions No (cf. API) Reconfigure react-native-image-picker options used when taking pictures or opening gallery
Utilities
debug boolean No false Enable verbose analytics mode, useful for troubleshooting session issues

Navigation configuration

Since it can work on iOS, Android and Web, we highly recommend to use React Navigation 5 for your application routing.

initialRouteName

The initialRouteName is IdCheckV2, it can be reconfigured by passing initialRouteName to the Id Check Context.

React Navigation 5

It is the default navigation.

React Router 5

For demonstration purpose, we can use React Router in the Web Application of Id Check.

This is possible thanks to @pass-culture/react-navigation-to-react-router-adpater.

The adapter only have support for React Navigation method used by Id Check. We may later extend it's support if we decide to use React Router for the Web version of App Native

Create an ID Check Analytics client

Using IdCheckAnalyticsInterface, you can create your own analytics client and track ID Check events:

import React from 'react'
import { IdCheckAnalyticsInterface } from '@pass-culture/id-check'

export const idCheckAnalyticsClient: IdCheckAnalyticsInterface = {
  cancelSignUp({ pageName }) {},
  identityError() {},
  idValid() {},
  invalidAge() {},
  invalidDate() {},
  invalidDocument() {},
  invalidTwice() {},
  processCompleted() {},
  wrongSideDocument() {},
  externalLink({ href, canOpen }) {},
  fileSizeExceeded() {},
  permissionsBlocked() {},
  // method below only active when `debug` is on
  hasValidSession({ valid, accessToken, accessTokenExpiresAt }) {},
  startCheckTokens() {},
  endCheckTokens() {},
  getJouveToken({
    appIsAllowedToRenewLicenceToken,
    isLocalLicenceToken,
    licenceToken,
    licenceTokenExpirationTimestamp,
    success,
    accessToken,
    accessTokenExpiresAt,
  }) {},
  getLicenceToken({ isError, errorCode, licenceToken, licenceTokenExpirationTimestamp }) {},
  startDmsTransmission() {},
  takeIdCheckPicture() {},
  confirmIdCheckPicture() {},
}

Create an ID Check Error Monitoring client

Using IdCheckErrorMonitoringInterface<Scope, MonitoringUser, CaptureContext>, you can create your own error monitoring client and track ID Check errors:

As an example with @sentry/react-native:

import * as SentryModule from '@sentry/react-native' // or @sentry/react
import { CaptureContext, User } from '@sentry/types'
import { IdCheckErrorMonitoringInterface } from '@pass-culture/id-check'

export const errorMonitoring: IdCheckErrorMonitoringInterface<
  SentryModule.Scope,
  User,
  CaptureContext
> = {
  captureException: SentryModule.captureException,
  captureEvent: SentryModule.captureEvent,
  captureMessage: SentryModule.captureMessage,
  configureScope: SentryModule.configureScope,
  init: SentryModule.init,
  setUser: SentryModule.setUser,
}
  • captureException: will be call within the AsyncErrorBoundary, which is wrapping every Id Check screens.
  • captureEvent: when provided, can be used to capture event when debug is ON.
  • captureMessage: when provided, can be used to capture message when debug is ON.
  • configureScope: method can be used to reconfigure the error monitoring context.
  • init: initialize the error monitoring service.
  • setUser: add a user to the error monitoring scope.

You MUST call the error monitoring init from within your application at the very beginning.

Create an Id Check Retention Client

Retention mode was created to validate Identity Document asynchronously. In this mode, document will be upload to any backend, which will be in charge of the Identity Check processing.

After creating a retention service on your serveur, you'll have to create a retentionClient, this is the signature:

export type IdCheckRetentionClient = {
  confirmProfile: (values?: Partial<UserProfile>) => Promise<void | EmptyResponse>
  uploadDocument: (file: IdCheckFile) => Promise<IdDocumentResponse | EmptyResponse>
}

Since it is asynchronous, you can use an empty object {} in your response as you may not have the IdDocumentResponse.

To activate the retention, you must set within the Id Check Context retention=true.

Error handling

  • uploadDocument is called to upload the identity document. If the success code is not 200/204, you must handle the error accordingly using the ApiError, see example below.
  • confirmProfile is called at the end. If the success code is not 200/204, it will display service-unavailable error.

Retention Example

import {
  ApiError as IdCheckApiError,
  IdCheckErrors,
  IdCheckRetentionClient,
  UserProfile,
  IdCheckFile,
  LocalStorageService,
} from '@pass-culture/id-check'

import { api } from 'api/api'
import { ActivityEnum, BeneficiaryInformationUpdateRequest } from 'api/gen'
import { ApiError } from 'api/helpers'

export const idCheckRetentionClient: IdCheckRetentionClient = {
  confirmProfile(values?: Partial<UserProfile>) {
    return api.patchnativev1beneficiaryInformation({
      ...(values?.address ? { address: values?.address } : {}),
      ...(values?.city ? { city: values?.city } : {}),
      ...(values?.email ? { email: values?.email } : {}),
      ...(values?.phone ? { phone: values?.phone } : {}),
      ...(values?.postalCode ? { postalCode: values?.postalCode } : {}),
      ...(values?.status ? { activity: values?.status as ActivityEnum } : {}),
    } as BeneficiaryInformationUpdateRequest)
  },
  uploadDocument: async (file: IdCheckFile) => {
    let error, token
    try {
      token = await LocalStorageService.getLicenceToken()
      if (!token) {
        error = new IdCheckApiError('Auth required', 400, {
          code: IdCheckErrors['auth-required'],
        })
      }
    } catch (err) {
      error = err
    }
    if (error) {
      return Promise.reject(error)
    }
    try {
      const data = new FormData()
      data.append('token', token)
      data.append('identityDocumentFile', file as Blob)
      return await api.postnativev1identityDocument({
        body: data,
      })
    } catch (err) {
      error = err
      if (err instanceof ApiError) {
        if (err.content.code === 'EXPIRED_TOKEN') {
          error = new IdCheckApiError(err.content.message, err.statusCode, {
            code: IdCheckErrors['auth-token-expired'],
          })
        } else if (err.content.code === 'INVALID_TOKEN') {
          error = new IdCheckApiError(err.content.message, err.statusCode, {
            code: IdCheckErrors['auth-required'],
          })
        } else if (err.content.code === 'FILE_SIZE_EXCEEDED') {
          error = new IdCheckApiError(err.content.message, err.statusCode, {
            code: IdCheckErrors['file-size-exceeded'],
          })
        } else if (err.content.code === 'SERVICE_UNAVAILABLE') {
          error = new IdCheckApiError(err.content.message, err.statusCode, {
            code: IdCheckErrors['validation-unavailable'],
          })
        }
      }
      return Promise.reject(error)
    }
  },
}

Add ID Check routes to your existing application

You can use the export from the module to create routes in your application:

  • routes: necessary to add ID Check routes to your applications.
  • initialRouteName: can be necessary if your application home page is ID Check home, or to remap the ID Check home route.

Navigate to ID Check

  1. When navigating to ID Check route, you can provide a licence_token and it's expiration_timestamp (in ms), if:
    • the licence_token is expired:
      • requestLicenceToken exist in the context: we get a new licence token, if:
        • it fail with 400 http status code, user see TooManyAttempt error page
        • it succeed, user continue to ID Check home
      • requestLicenceToken does not exist in the context, we can't start id check:
        • it fail: user see SessionExpired error page (Usually for Webapp v1 which MUST pass licence_token and expiration_timestamp query param to the base URL endpoint of the standalone Id Check V2 App)
    • the licence_token is invalid:
      • it fail: user see SessionExpired error page

requestLicenceToken

A fetch client that does a unique request can be provided to automatically get a new licence_token when needed.

This is useful in the native application since the user and can call the secure API /native/v1/id_check_token endpoint.

Example

Within your App.js in a new project:

import React, { createRef } from 'react'
import { initialRouteName, routes, linkingConfig, RootStackParamList } from '@pass-culture/id-check'
import { NavigationContainer, NavigationContainerRef } from '@react-navigation/native'
import { createStackNavigator } from '@react-navigation/stack'

import { errorMonitoring, analytics } from './services'

const navigationRef = createRef<NavigationContainerRef>()
const Stack = createStackNavigator<RootStackParamList>()

function App() {
  function onSuccess() {
    console.log('success')
  }

  function onAbandon() {
    console.log('abandon')
  }

  return (
    <IdCheckContextProvider
      retention={false}
      errorMonitoring={errorMonitoring}
      analytics={analytics}
      onSuccess={onSuccess}
      onAbandon={onAbandon}>
      <NavigationContainer
        linking={linkingConfig}
        fallback={<div>Chargement...</div>}
        ref={navigationRef}>
        <Navigator
          initialRouteName={initialRouteName}
          screenOptions={{
            headerShown: false,
            cardShadowEnabled: false,
            cardStyle: {
              backgroundColor: 'transparent',
              flex: 1,
            },
          }}>
          {routes.map((route: Route) => (
            <Screen
              key={route.name}
              name={route.name}
              component={route.component}
              options={route.options}
              // Below is extra features used by @pass-culture/react-navigation-to-react-router-adapter
              // eslint-disable-next-line @typescript-eslint/ban-ts-comment
              // @ts-ignore
              from={route.from}
              path={route.path}
              strict={route.strict}
              exact={route.exact}
              push={route.push}
              to={route.to}
            />
          ))}
        </Navigator>
      </NavigationContainer>
    </IdCheckContextProvider>
  )
}

export default App

Readme

Keywords

none

Package Sidebar

Install

npm i @pass-culture/id-check

Weekly Downloads

11

Version

2.11.1

License

UNLICENSED

Unpacked Size

468 kB

Total Files

250

Last publish

Collaborators

  • anoukhello
  • apibrac
  • kopax-passculture
  • marionvalentinpassculture