@41devs/naya-id-angular 0.1.1 → 0.4.0
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.
- package/README.md +84 -193
- package/fesm2022/41devs-naya-id-angular.mjs +197 -1
- package/fesm2022/41devs-naya-id-angular.mjs.map +1 -1
- package/index.d.ts +88 -198
- package/package.json +5 -5
- package/fesm2022/41devs-naya-id-angular-41devs-naya-id-angular-B7t92Ogc.mjs +0 -292
- package/fesm2022/41devs-naya-id-angular-41devs-naya-id-angular-B7t92Ogc.mjs.map +0 -1
- package/fesm2022/41devs-naya-id-angular-naya-flow.launcher-xIwcsV6g.mjs +0 -2066
- package/fesm2022/41devs-naya-id-angular-naya-flow.launcher-xIwcsV6g.mjs.map +0 -1
package/index.d.ts
CHANGED
|
@@ -1,221 +1,111 @@
|
|
|
1
|
+
import { StartVerificationParams, NayaResult, NayaEvent, NayaSupport, NayaCountryCode, NayaDocumentType } from '@41devs/naya-id-js';
|
|
2
|
+
export { NayaAuth, NayaCaptureOptions, NayaConfig, NayaConsentOptions, NayaCountryCode, NayaDocumentType, NayaDocumentTypeMismatchPolicy, NayaErrorCode, NayaEvent, NayaEventName, NayaHandoffOptions, NayaLivenessAssets, NayaLivenessOptions, NayaLocale, NayaOcrData, NayaResult, NayaStatus, NayaSupport, NayaThemeOverrides, ResolvedNayaConfig, StartVerificationParams } from '@41devs/naya-id-js';
|
|
1
3
|
import * as i0 from '@angular/core';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* optionnels et le SDK fonctionne avec des valeurs par défaut raisonnables
|
|
8
|
-
* (tous pays, tous documents, français).
|
|
9
|
-
*/
|
|
10
|
-
/** Pays supportés par Naya ID (zone CEDEAO). Code = ISO 3166-1 alpha-2. */
|
|
11
|
-
declare const NAYA_COUNTRIES: readonly [{
|
|
12
|
-
readonly code: "BJ";
|
|
13
|
-
readonly label: "Bénin";
|
|
14
|
-
}, {
|
|
15
|
-
readonly code: "CI";
|
|
16
|
-
readonly label: "Côte d'Ivoire";
|
|
17
|
-
}, {
|
|
18
|
-
readonly code: "SN";
|
|
19
|
-
readonly label: "Sénégal";
|
|
20
|
-
}, {
|
|
21
|
-
readonly code: "ML";
|
|
22
|
-
readonly label: "Mali";
|
|
23
|
-
}, {
|
|
24
|
-
readonly code: "BF";
|
|
25
|
-
readonly label: "Burkina Faso";
|
|
26
|
-
}, {
|
|
27
|
-
readonly code: "TG";
|
|
28
|
-
readonly label: "Togo";
|
|
29
|
-
}];
|
|
30
|
-
type NayaCountryCode = (typeof NAYA_COUNTRIES)[number]['code'];
|
|
31
|
-
/** Types de documents acceptés. La valeur est envoyée telle quelle à l'API. */
|
|
32
|
-
type NayaDocumentType = 'cni' | 'passeport' | 'permis';
|
|
33
|
-
declare const NAYA_DOCUMENT_TYPES: readonly NayaDocumentType[];
|
|
34
|
-
/** Langues de l'interface du SDK. */
|
|
35
|
-
type NayaLocale = 'fr' | 'en';
|
|
36
|
-
/**
|
|
37
|
-
* Fournisseur d'authentification.
|
|
38
|
-
*
|
|
39
|
-
* Deux modes, un seul à renseigner :
|
|
40
|
-
* • `apiKey` — la clé d'application est transmise depuis le navigateur.
|
|
41
|
-
* Simple, mais la clé est lisible côté client : à réserver
|
|
42
|
-
* aux démos et aux intégrations où le front est maîtrisé.
|
|
43
|
-
* • `sessionToken` — jeton éphémère obtenu par le backend du client, limité à
|
|
44
|
-
* une vérification. À privilégier en production. Le SDK est
|
|
45
|
-
* prêt à le consommer dès que l'API l'expose.
|
|
46
|
-
*
|
|
47
|
-
* L'abstraction est volontaire : passer de l'un à l'autre ne touche pas au reste
|
|
48
|
-
* du SDK.
|
|
6
|
+
* Parcours réutilisable : une instance qu'on ouvre, ferme et écoute.
|
|
7
|
+
* Miroir de `create()` du SDK Naya, avec les rappels ramenés dans la zone
|
|
8
|
+
* Angular.
|
|
49
9
|
*/
|
|
50
|
-
interface
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
10
|
+
interface NayaVerification {
|
|
11
|
+
/** Monte l'interface et résout à la fermeture. Un seul `open` à la fois. */
|
|
12
|
+
open(): Promise<NayaResult>;
|
|
13
|
+
/** Ferme le parcours (résultat `cancelled`). */
|
|
14
|
+
close(): void;
|
|
15
|
+
/** Abonne un écouteur ; rend la fonction de désabonnement. */
|
|
16
|
+
on(event: NayaEvent['type'] | 'result', cb: (payload: NayaEvent | NayaResult) => void): () => void;
|
|
17
|
+
/** Ferme et libère les écouteurs. */
|
|
18
|
+
destroy(): void;
|
|
19
|
+
readonly isOpen: boolean;
|
|
60
20
|
}
|
|
61
|
-
interface NayaConfig {
|
|
62
|
-
/** Pré-sélectionne le pays : l'utilisateur ne le choisit plus. */
|
|
63
|
-
country?: NayaCountryCode;
|
|
64
|
-
/**
|
|
65
|
-
* Types de documents proposés. S'il n'y en a qu'un et que `country` est
|
|
66
|
-
* défini, l'écran de sélection est sauté.
|
|
67
|
-
*/
|
|
68
|
-
documentTypes?: readonly NayaDocumentType[];
|
|
69
|
-
/** Pays proposés quand `country` n'est pas défini. */
|
|
70
|
-
countries?: readonly NayaCountryCode[];
|
|
71
|
-
/** Langue de l'interface. */
|
|
72
|
-
locale?: NayaLocale;
|
|
73
|
-
/**
|
|
74
|
-
* URL (HTTPS) notifiée par le serveur Naya à chaque décision sur cette
|
|
75
|
-
* session — décision automatique puis, le cas échéant, revue manuelle.
|
|
76
|
-
*/
|
|
77
|
-
callbackUrl?: string;
|
|
78
|
-
/** Nombre de parcours autorisés après un rejet (bouton « Réessayer »). */
|
|
79
|
-
maxAttempts?: number;
|
|
80
|
-
/** Surcharge des couleurs de marque. */
|
|
81
|
-
theme?: NayaThemeOverrides;
|
|
82
|
-
/** URL d'un logo client, affiché à côté de « Propulsé par Naya ID ». */
|
|
83
|
-
clientLogoUrl?: string;
|
|
84
|
-
/** Base URL de l'API — ne changer que pour un environnement de test. */
|
|
85
|
-
baseUrl?: string;
|
|
86
|
-
/**
|
|
87
|
-
* Emplacement des ressources de détection de vivacité (MediaPipe). Par
|
|
88
|
-
* défaut, elles sont chargées depuis un CDN public. Les applications à CSP
|
|
89
|
-
* stricte (qui bloquent les hôtes externes) doivent auto-héberger ces
|
|
90
|
-
* fichiers et renseigner ici leurs URL.
|
|
91
|
-
*/
|
|
92
|
-
livenessAssets?: {
|
|
93
|
-
/** Base des fichiers WASM `@mediapipe/tasks-vision`. */
|
|
94
|
-
wasmBaseUrl?: string;
|
|
95
|
-
/** URL du modèle `.task` de Face Landmarker. */
|
|
96
|
-
modelUrl?: string;
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
/** Libellé lisible d'un code pays. */
|
|
100
|
-
declare function countryLabel(code: NayaCountryCode): string;
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Résultat du parcours, rendu à l'application cliente à la fermeture du SDK.
|
|
104
|
-
* Miroir fidèle du modèle Flutter (`naya_result.dart`).
|
|
105
|
-
*/
|
|
106
|
-
/** Issue du parcours de vérification. */
|
|
107
|
-
type NayaStatus =
|
|
108
|
-
/** Identité vérifiée et approuvée automatiquement. */
|
|
109
|
-
'approved'
|
|
110
|
-
/** Dossier envoyé en revue manuelle — décision finale ultérieure. */
|
|
111
|
-
| 'review'
|
|
112
|
-
/** Vérification rejetée (document expiré, visage non concordant…). */
|
|
113
|
-
| 'rejected'
|
|
114
|
-
/** L'utilisateur a quitté le parcours avant la fin. */
|
|
115
|
-
| 'cancelled'
|
|
116
|
-
/** Erreur technique (réseau, serveur…) ayant interrompu le parcours. */
|
|
117
|
-
| 'error';
|
|
118
|
-
/**
|
|
119
|
-
* Données d'identité extraites du document par l'OCR Naya, éventuellement
|
|
120
|
-
* corrigées par l'utilisateur.
|
|
121
|
-
*/
|
|
122
|
-
interface NayaOcrData {
|
|
123
|
-
lastName?: string;
|
|
124
|
-
firstName?: string;
|
|
125
|
-
/** Format YYYY-MM-DD. */
|
|
126
|
-
dateOfBirth?: string;
|
|
127
|
-
placeOfBirth?: string;
|
|
128
|
-
nationality?: string;
|
|
129
|
-
/** Format YYYY-MM-DD. */
|
|
130
|
-
expirationDate?: string;
|
|
131
|
-
documentNumber?: string;
|
|
132
|
-
/** Numéro Personnel d'Identification (Bénin) — 10 chiffres. */
|
|
133
|
-
npi?: string;
|
|
134
|
-
issuingCountry?: string;
|
|
135
|
-
issuingAuthority?: string;
|
|
136
|
-
/** 'M' ou 'F'. */
|
|
137
|
-
gender?: string;
|
|
138
|
-
}
|
|
139
|
-
/** Résultat retourné à l'application cliente. */
|
|
140
|
-
interface NayaResult {
|
|
141
|
-
status: NayaStatus;
|
|
142
|
-
/**
|
|
143
|
-
* Identifiant de la session Naya — à conserver côté client pour rapprocher
|
|
144
|
-
* les notifications `callbackUrl` et le dashboard.
|
|
145
|
-
*/
|
|
146
|
-
verificationId?: string;
|
|
147
|
-
/** Score de risque agrégé 0-100 (plus haut = plus sûr). */
|
|
148
|
-
riskScore?: number;
|
|
149
|
-
/** Concordance faciale document ↔ selfie, 0-100. */
|
|
150
|
-
matchScore?: number;
|
|
151
|
-
/** Intégrité du document, 0-100. */
|
|
152
|
-
authenticityScore?: number;
|
|
153
|
-
/** Score de vivacité, 0-100. */
|
|
154
|
-
livenessScore?: number;
|
|
155
|
-
/** Confiance de l'extraction OCR, 0-100. */
|
|
156
|
-
ocrConfidence?: number;
|
|
157
|
-
/** Données d'identité finales (OCR fusionné avec les corrections). */
|
|
158
|
-
ocrData?: NayaOcrData;
|
|
159
|
-
/** Note d'analyse produite par le pipeline Naya. */
|
|
160
|
-
note?: string;
|
|
161
|
-
/** Détail de l'erreur quand `status` vaut `'error'`. */
|
|
162
|
-
errorMessage?: string;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
21
|
/**
|
|
166
22
|
* Point d'entrée du SDK Naya ID pour Angular.
|
|
167
23
|
*
|
|
168
|
-
* Injecter le service, puis lancer le parcours :
|
|
169
|
-
*
|
|
170
24
|
* ```ts
|
|
171
25
|
* const result = await this.naya.startVerification({
|
|
172
|
-
* auth: {
|
|
173
|
-
* config: {
|
|
26
|
+
* auth: { verificationId, sessionToken },
|
|
27
|
+
* config: { locale: 'fr' },
|
|
174
28
|
* });
|
|
175
29
|
* ```
|
|
176
30
|
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
31
|
+
* Le parcours (consentement, capture, vivacité, décision) est celui du SDK
|
|
32
|
+
* navigateur `@41devs/naya-id-js` : une seule implémentation, partagée avec
|
|
33
|
+
* les intégrations sans framework. Cette bibliothèque y ajoute ce qu'attend
|
|
34
|
+
* une application Angular :
|
|
35
|
+
*
|
|
36
|
+
* • **injection** — un service `providedIn: 'root'`, testable et
|
|
37
|
+
* remplaçable ;
|
|
38
|
+
* • **chargement différé** — le SDK n'entre pas dans le bundle initial ;
|
|
39
|
+
* il est importé au premier lancement ;
|
|
40
|
+
* • **zone** — le parcours tourne hors de la zone Angular (le flux caméra
|
|
41
|
+
* déclencherait sinon une détection de changements par trame), et les
|
|
42
|
+
* rappels de l'hôte y sont ramenés pour que signaux et vues se mettent
|
|
43
|
+
* à jour normalement ;
|
|
44
|
+
* • **rendu serveur** — sans `document`, le service rend une erreur typée
|
|
45
|
+
* au lieu de lever.
|
|
181
46
|
*/
|
|
182
47
|
declare class NayaIdService {
|
|
183
|
-
private readonly
|
|
184
|
-
private readonly
|
|
48
|
+
private readonly zone;
|
|
49
|
+
private readonly platformId;
|
|
50
|
+
/** Chargé une seule fois, au premier usage. */
|
|
51
|
+
private sdk?;
|
|
52
|
+
private load;
|
|
53
|
+
private get isBrowser();
|
|
54
|
+
private serverSideResult;
|
|
55
|
+
/**
|
|
56
|
+
* Enveloppe la configuration de l'hôte pour ramener ses rappels dans la
|
|
57
|
+
* zone Angular. Sans cela, un `onEvent` qui écrit dans un signal ne
|
|
58
|
+
* déclencherait aucun rafraîchissement : le parcours tourne hors zone.
|
|
59
|
+
*/
|
|
60
|
+
private withZone;
|
|
185
61
|
/**
|
|
186
62
|
* Lance le parcours de vérification d'identité.
|
|
187
63
|
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
64
|
+
* Authentification, au choix :
|
|
65
|
+
* • `auth.verificationId` + `auth.sessionToken`, rendus à votre backend
|
|
66
|
+
* par `POST /verifications/start` — à privilégier en production, la
|
|
67
|
+
* clé ne quitte pas le serveur ;
|
|
68
|
+
* • `auth.apiKey` — démos et fronts maîtrisés. Une clé live doit
|
|
69
|
+
* déclarer ses origines dans le dashboard.
|
|
70
|
+
*
|
|
71
|
+
* **Ne rejette jamais** : une erreur ou une annulation revient sous forme
|
|
72
|
+
* de `NayaResult` (`status: 'error'` avec `errorCode`, ou `'cancelled'`).
|
|
73
|
+
*/
|
|
74
|
+
startVerification(params: StartVerificationParams): Promise<NayaResult>;
|
|
75
|
+
/**
|
|
76
|
+
* Instance réutilisable, pour piloter l'ouverture et la fermeture depuis
|
|
77
|
+
* un composant et suivre les événements du parcours.
|
|
78
|
+
*/
|
|
79
|
+
create(params: StartVerificationParams): Promise<NayaVerification>;
|
|
80
|
+
/**
|
|
81
|
+
* Vérifie que le navigateur peut exécuter le parcours (caméra, contexte
|
|
82
|
+
* sécurisé, navigateur intégré) avant de l'ouvrir.
|
|
83
|
+
*/
|
|
84
|
+
isSupported(): Promise<NayaSupport>;
|
|
85
|
+
/** Version du SDK navigateur effectivement chargé. */
|
|
86
|
+
version(): Promise<string>;
|
|
87
|
+
/**
|
|
88
|
+
* Pays couverts, avec leur libellé — pour un sélecteur affiché par l'hôte
|
|
89
|
+
* avant d'ouvrir le parcours.
|
|
90
|
+
*
|
|
91
|
+
* Accesseur asynchrone, et non constante réexportée : une valeur importée
|
|
92
|
+
* statiquement depuis cette bibliothèque entraînerait tout le SDK
|
|
93
|
+
* navigateur dans le bundle initial de votre application. Vous n'en avez
|
|
94
|
+
* besoin que si vous construisez votre propre sélection ; sinon `config`
|
|
95
|
+
* accepte directement les codes (`country: 'BJ'`), typés par
|
|
96
|
+
* `NayaCountryCode`.
|
|
194
97
|
*/
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
}
|
|
98
|
+
countries(): Promise<readonly {
|
|
99
|
+
code: NayaCountryCode;
|
|
100
|
+
label: string;
|
|
101
|
+
}[]>;
|
|
102
|
+
/** Types de pièces acceptés. Même remarque que [countries]. */
|
|
103
|
+
documentTypes(): Promise<readonly NayaDocumentType[]>;
|
|
104
|
+
/** Libellé lisible d'un code pays. */
|
|
105
|
+
countryLabel(code: NayaCountryCode): Promise<string>;
|
|
199
106
|
static ɵfac: i0.ɵɵFactoryDeclaration<NayaIdService, never>;
|
|
200
107
|
static ɵprov: i0.ɵɵInjectableDeclaration<NayaIdService>;
|
|
201
108
|
}
|
|
202
109
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
*
|
|
206
|
-
* Bâti sur `fetch` natif — la librairie reste ainsi utilisable sans
|
|
207
|
-
* `provideHttpClient` ni dépendance au module HTTP d'Angular. Les délais sont
|
|
208
|
-
* dimensionnés pour les étapes longues (OCR et décision côté serveur).
|
|
209
|
-
*
|
|
210
|
-
* Authentification via `NayaAuth` : `apiKey` (en-tête `X-API-Key`) ou
|
|
211
|
-
* `sessionToken` (en-tête `Authorization: Bearer`). Le choix est transparent
|
|
212
|
-
* pour le reste du SDK.
|
|
213
|
-
*/
|
|
214
|
-
/** Erreur renvoyée par l'API Naya ou par le transport réseau. */
|
|
215
|
-
declare class NayaApiError extends Error {
|
|
216
|
-
readonly statusCode?: number | undefined;
|
|
217
|
-
constructor(message: string, statusCode?: number | undefined);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
export { NAYA_COUNTRIES, NAYA_DOCUMENT_TYPES, NayaApiError, NayaIdService, countryLabel };
|
|
221
|
-
export type { NayaAuth, NayaConfig, NayaCountryCode, NayaDocumentType, NayaLocale, NayaOcrData, NayaResult, NayaStatus, NayaThemeOverrides };
|
|
110
|
+
export { NayaIdService };
|
|
111
|
+
export type { NayaVerification };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@41devs/naya-id-angular",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "SDK Angular officiel de Naya ID — vérification d'identité (eKYC) clé en main pour l'Afrique de l'Ouest
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "SDK Angular officiel de Naya ID — vérification d'identité (eKYC) clé en main pour l'Afrique de l'Ouest : consentement, capture guidée, défi de vivacité imposé par le serveur, confirmation des données, résultat expliqué.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"kyc",
|
|
7
7
|
"ekyc",
|
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
"license": "SEE LICENSE IN LICENSE",
|
|
15
15
|
"author": "41Devs",
|
|
16
16
|
"peerDependencies": {
|
|
17
|
-
"@angular/common": "^20.
|
|
18
|
-
"@angular/core": "^20.
|
|
17
|
+
"@angular/common": "^19.0.0 || ^20.0.0",
|
|
18
|
+
"@angular/core": "^19.0.0 || ^20.0.0"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"tslib": "^2.3.0",
|
|
22
|
-
"@
|
|
22
|
+
"@41devs/naya-id-js": "^0.4.0"
|
|
23
23
|
},
|
|
24
24
|
"sideEffects": false,
|
|
25
25
|
"module": "fesm2022/41devs-naya-id-angular.mjs",
|
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, ApplicationRef, EnvironmentInjector, Injectable } from '@angular/core';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Configuration du parcours de vérification Naya ID.
|
|
6
|
-
*
|
|
7
|
-
* Reprend, à l'identique, le modèle du SDK Flutter : tous les champs sont
|
|
8
|
-
* optionnels et le SDK fonctionne avec des valeurs par défaut raisonnables
|
|
9
|
-
* (tous pays, tous documents, français).
|
|
10
|
-
*/
|
|
11
|
-
/** Pays supportés par Naya ID (zone CEDEAO). Code = ISO 3166-1 alpha-2. */
|
|
12
|
-
const NAYA_COUNTRIES = [
|
|
13
|
-
{ code: 'BJ', label: 'Bénin' },
|
|
14
|
-
{ code: 'CI', label: "Côte d'Ivoire" },
|
|
15
|
-
{ code: 'SN', label: 'Sénégal' },
|
|
16
|
-
{ code: 'ML', label: 'Mali' },
|
|
17
|
-
{ code: 'BF', label: 'Burkina Faso' },
|
|
18
|
-
{ code: 'TG', label: 'Togo' },
|
|
19
|
-
];
|
|
20
|
-
const NAYA_DOCUMENT_TYPES = [
|
|
21
|
-
'cni',
|
|
22
|
-
'passeport',
|
|
23
|
-
'permis',
|
|
24
|
-
];
|
|
25
|
-
const NAYA_DEFAULT_PRIMARY = '#1A3A5C';
|
|
26
|
-
const NAYA_DEFAULT_ACCENT = '#F5A623';
|
|
27
|
-
const NAYA_DEFAULT_BASE_URL = 'https://api.naya.41devs.com/v1';
|
|
28
|
-
/** Applique les valeurs par défaut à une configuration partielle. */
|
|
29
|
-
function resolveConfig(config = {}) {
|
|
30
|
-
return {
|
|
31
|
-
country: config.country,
|
|
32
|
-
documentTypes: config.documentTypes ?? NAYA_DOCUMENT_TYPES,
|
|
33
|
-
countries: config.countries ?? NAYA_COUNTRIES.map((c) => c.code),
|
|
34
|
-
locale: config.locale ?? 'fr',
|
|
35
|
-
callbackUrl: config.callbackUrl,
|
|
36
|
-
maxAttempts: config.maxAttempts ?? 2,
|
|
37
|
-
theme: {
|
|
38
|
-
primaryColor: config.theme?.primaryColor ?? NAYA_DEFAULT_PRIMARY,
|
|
39
|
-
accentColor: config.theme?.accentColor ?? NAYA_DEFAULT_ACCENT,
|
|
40
|
-
},
|
|
41
|
-
clientLogoUrl: config.clientLogoUrl,
|
|
42
|
-
baseUrl: config.baseUrl ?? NAYA_DEFAULT_BASE_URL,
|
|
43
|
-
livenessAssets: {
|
|
44
|
-
wasmBaseUrl: config.livenessAssets?.wasmBaseUrl,
|
|
45
|
-
modelUrl: config.livenessAssets?.modelUrl,
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
/** Libellé lisible d'un code pays. */
|
|
50
|
-
function countryLabel(code) {
|
|
51
|
-
return NAYA_COUNTRIES.find((c) => c.code === code)?.label ?? code;
|
|
52
|
-
}
|
|
53
|
-
/** La CNI CEDEAO porte sa MRZ au verso ; passeport et permis n'en ont pas besoin. */
|
|
54
|
-
function documentNeedsVerso(doc) {
|
|
55
|
-
return doc === 'cni';
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Point d'entrée du SDK Naya ID pour Angular.
|
|
60
|
-
*
|
|
61
|
-
* Injecter le service, puis lancer le parcours :
|
|
62
|
-
*
|
|
63
|
-
* ```ts
|
|
64
|
-
* const result = await this.naya.startVerification({
|
|
65
|
-
* auth: { apiKey: 'naya_live_xxx' },
|
|
66
|
-
* config: { country: 'BJ' },
|
|
67
|
-
* });
|
|
68
|
-
* ```
|
|
69
|
-
*
|
|
70
|
-
* `startVerification` monte l'interface Naya en plein écran au-dessus de
|
|
71
|
-
* l'application, gère la capture et la vivacité, puis résout un `NayaResult` :
|
|
72
|
-
* `approved`, `review`, `rejected`, `cancelled` (l'utilisateur a quitté) ou
|
|
73
|
-
* `error`. Elle ne rejette jamais.
|
|
74
|
-
*/
|
|
75
|
-
class NayaIdService {
|
|
76
|
-
appRef = inject(ApplicationRef);
|
|
77
|
-
environmentInjector = inject(EnvironmentInjector);
|
|
78
|
-
/**
|
|
79
|
-
* Lance le parcours de vérification d'identité.
|
|
80
|
-
*
|
|
81
|
-
* @param params.auth Clé d'application (`apiKey`) ou jeton de session
|
|
82
|
-
* éphémère (`sessionToken`). En production, privilégier
|
|
83
|
-
* le jeton : la clé embarquée dans le front est lisible
|
|
84
|
-
* côté navigateur.
|
|
85
|
-
* @param params.config Configuration optionnelle (pays, documents, langue,
|
|
86
|
-
* callbackUrl, thème…).
|
|
87
|
-
*/
|
|
88
|
-
async startVerification(params) {
|
|
89
|
-
const auth = params.auth;
|
|
90
|
-
const config = resolveConfig(params.config);
|
|
91
|
-
if (!auth.apiKey && !auth.sessionToken) {
|
|
92
|
-
return {
|
|
93
|
-
status: 'error',
|
|
94
|
-
errorMessage: 'Authentification manquante : fournissez auth.apiKey ou auth.sessionToken.',
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
// L'interface (overlay + écrans) est importée à la demande : elle reste
|
|
98
|
-
// hors du bundle initial de l'application tant que la vérification n'est
|
|
99
|
-
// pas lancée.
|
|
100
|
-
const { mountNayaFlow } = await import('./41devs-naya-id-angular-naya-flow.launcher-xIwcsV6g.mjs');
|
|
101
|
-
return mountNayaFlow({ appRef: this.appRef, environmentInjector: this.environmentInjector }, auth, config);
|
|
102
|
-
}
|
|
103
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: NayaIdService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
104
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: NayaIdService, providedIn: 'root' });
|
|
105
|
-
}
|
|
106
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: NayaIdService, decorators: [{
|
|
107
|
-
type: Injectable,
|
|
108
|
-
args: [{ providedIn: 'root' }]
|
|
109
|
-
}] });
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Résultat du parcours, rendu à l'application cliente à la fermeture du SDK.
|
|
113
|
-
* Miroir fidèle du modèle Flutter (`naya_result.dart`).
|
|
114
|
-
*/
|
|
115
|
-
const OCR_FIELDS = [
|
|
116
|
-
'lastName', 'firstName', 'dateOfBirth', 'placeOfBirth', 'nationality',
|
|
117
|
-
'expirationDate', 'documentNumber', 'npi', 'issuingCountry',
|
|
118
|
-
'issuingAuthority', 'gender',
|
|
119
|
-
];
|
|
120
|
-
/** Lit un objet OCR brut de l'API en ne retenant que les champs connus. */
|
|
121
|
-
function parseOcrData(raw) {
|
|
122
|
-
if (!raw || typeof raw !== 'object')
|
|
123
|
-
return undefined;
|
|
124
|
-
const src = raw;
|
|
125
|
-
const out = {};
|
|
126
|
-
for (const field of OCR_FIELDS) {
|
|
127
|
-
const value = src[field];
|
|
128
|
-
if (typeof value === 'string' && value.length > 0)
|
|
129
|
-
out[field] = value;
|
|
130
|
-
}
|
|
131
|
-
return Object.keys(out).length ? out : undefined;
|
|
132
|
-
}
|
|
133
|
-
/** Réduit un objet OCR à ses seuls champs renseignés, en chaînes. */
|
|
134
|
-
function ocrToDeclaredData(ocr) {
|
|
135
|
-
const out = {};
|
|
136
|
-
for (const field of OCR_FIELDS) {
|
|
137
|
-
const value = ocr[field];
|
|
138
|
-
if (value)
|
|
139
|
-
out[field] = value;
|
|
140
|
-
}
|
|
141
|
-
return out;
|
|
142
|
-
}
|
|
143
|
-
function cancelledResult(verificationId) {
|
|
144
|
-
return { status: 'cancelled', verificationId };
|
|
145
|
-
}
|
|
146
|
-
function errorResult(errorMessage, verificationId) {
|
|
147
|
-
return { status: 'error', errorMessage, verificationId };
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Client HTTP du pipeline de vérification Naya.
|
|
152
|
-
*
|
|
153
|
-
* Bâti sur `fetch` natif — la librairie reste ainsi utilisable sans
|
|
154
|
-
* `provideHttpClient` ni dépendance au module HTTP d'Angular. Les délais sont
|
|
155
|
-
* dimensionnés pour les étapes longues (OCR et décision côté serveur).
|
|
156
|
-
*
|
|
157
|
-
* Authentification via `NayaAuth` : `apiKey` (en-tête `X-API-Key`) ou
|
|
158
|
-
* `sessionToken` (en-tête `Authorization: Bearer`). Le choix est transparent
|
|
159
|
-
* pour le reste du SDK.
|
|
160
|
-
*/
|
|
161
|
-
/** Erreur renvoyée par l'API Naya ou par le transport réseau. */
|
|
162
|
-
class NayaApiError extends Error {
|
|
163
|
-
statusCode;
|
|
164
|
-
constructor(message, statusCode) {
|
|
165
|
-
super(message);
|
|
166
|
-
this.statusCode = statusCode;
|
|
167
|
-
this.name = 'NayaApiError';
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
const SECONDS = 1000;
|
|
171
|
-
class NayaApiClient {
|
|
172
|
-
auth;
|
|
173
|
-
baseUrl;
|
|
174
|
-
constructor(auth, baseUrl) {
|
|
175
|
-
this.auth = auth;
|
|
176
|
-
this.baseUrl = baseUrl;
|
|
177
|
-
}
|
|
178
|
-
headers() {
|
|
179
|
-
const h = { 'Content-Type': 'application/json' };
|
|
180
|
-
if (this.auth.sessionToken) {
|
|
181
|
-
h['Authorization'] = `Bearer ${this.auth.sessionToken}`;
|
|
182
|
-
}
|
|
183
|
-
else if (this.auth.apiKey) {
|
|
184
|
-
h['X-API-Key'] = this.auth.apiKey;
|
|
185
|
-
}
|
|
186
|
-
return h;
|
|
187
|
-
}
|
|
188
|
-
async post(path, body, timeoutMs = 30 * SECONDS) {
|
|
189
|
-
const controller = new AbortController();
|
|
190
|
-
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
191
|
-
let res;
|
|
192
|
-
try {
|
|
193
|
-
res = await fetch(`${this.baseUrl}${path}`, {
|
|
194
|
-
method: 'POST',
|
|
195
|
-
headers: this.headers(),
|
|
196
|
-
body: JSON.stringify(body),
|
|
197
|
-
signal: controller.signal,
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
catch (err) {
|
|
201
|
-
const aborted = err instanceof DOMException && err.name === 'AbortError';
|
|
202
|
-
throw new NayaApiError(aborted ? 'Délai dépassé — réessayez.' : 'Réseau indisponible.');
|
|
203
|
-
}
|
|
204
|
-
finally {
|
|
205
|
-
clearTimeout(timer);
|
|
206
|
-
}
|
|
207
|
-
let json;
|
|
208
|
-
try {
|
|
209
|
-
json = await res.json();
|
|
210
|
-
}
|
|
211
|
-
catch {
|
|
212
|
-
throw new NayaApiError('Réponse illisible du serveur.', res.status);
|
|
213
|
-
}
|
|
214
|
-
if (res.status >= 400 || json?.success !== true) {
|
|
215
|
-
const message = (json?.error && typeof json.error === 'object'
|
|
216
|
-
? json.error.message
|
|
217
|
-
: undefined) ?? 'Erreur inconnue.';
|
|
218
|
-
throw new NayaApiError(message, res.status);
|
|
219
|
-
}
|
|
220
|
-
return (json.data ?? {});
|
|
221
|
-
}
|
|
222
|
-
/** Ouvre une session de vérification. */
|
|
223
|
-
async start(params) {
|
|
224
|
-
const data = await this.post('/verifications/start', {
|
|
225
|
-
documentType: params.documentType,
|
|
226
|
-
country: params.country,
|
|
227
|
-
...(params.callbackUrl ? { callbackUrl: params.callbackUrl } : {}),
|
|
228
|
-
device: 'Web',
|
|
229
|
-
});
|
|
230
|
-
return {
|
|
231
|
-
verificationId: String(data['verificationId'] ?? ''),
|
|
232
|
-
sessionToken: String(data['sessionToken'] ?? ''),
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Envoie le document capturé. L'OCR serveur est synchrone : la réponse
|
|
237
|
-
* contient les champs extraits, utilisés pour pré-remplir l'étape suivante.
|
|
238
|
-
* Le verso, quand il est fourni, porte la MRZ des CNI CEDEAO.
|
|
239
|
-
*/
|
|
240
|
-
async uploadDocument(verificationId, params) {
|
|
241
|
-
const data = await this.post(`/verifications/${verificationId}/document`, {
|
|
242
|
-
imageBase64Recto: params.rectoBase64,
|
|
243
|
-
...(params.versoBase64 ? { imageBase64Verso: params.versoBase64 } : {}),
|
|
244
|
-
}, 120 * SECONDS);
|
|
245
|
-
return parseOcrData(data['ocrData']);
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* Envoie le selfie et le score de vivacité mesuré sur l'appareil.
|
|
249
|
-
* `matchScore` est requis par l'endpoint mais recalculé côté serveur : on
|
|
250
|
-
* transmet 0, comme le SDK Flutter.
|
|
251
|
-
*/
|
|
252
|
-
async submitLiveness(verificationId, params) {
|
|
253
|
-
await this.post(`/verifications/${verificationId}/liveness`, {
|
|
254
|
-
livenessScore: params.livenessScore,
|
|
255
|
-
matchScore: 0,
|
|
256
|
-
selfieBase64: params.selfieBase64,
|
|
257
|
-
}, 60 * SECONDS);
|
|
258
|
-
}
|
|
259
|
-
/** Déclenche l'analyse finale (OCR différé, biométrie, AML, décision). */
|
|
260
|
-
async submit(verificationId, userDeclaredData) {
|
|
261
|
-
const data = await this.post(`/verifications/${verificationId}/submit`, userDeclaredData && Object.keys(userDeclaredData).length
|
|
262
|
-
? { userDeclaredData }
|
|
263
|
-
: {}, 180 * SECONDS);
|
|
264
|
-
return {
|
|
265
|
-
status: String(data['status'] ?? 'review'),
|
|
266
|
-
riskScore: numOrUndef(data['riskScore']),
|
|
267
|
-
matchScore: numOrUndef(data['matchScore']),
|
|
268
|
-
authenticityScore: numOrUndef(data['authenticityScore']),
|
|
269
|
-
livenessScore: numOrUndef(data['livenessScore']),
|
|
270
|
-
ocrConfidence: numOrUndef(data['ocrConfidence']),
|
|
271
|
-
ocrData: parseOcrData(data['ocrData']),
|
|
272
|
-
note: typeof data['note'] === 'string' ? data['note'] : undefined,
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
function numOrUndef(v) {
|
|
277
|
-
return typeof v === 'number' && !Number.isNaN(v) ? v : undefined;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
/*
|
|
281
|
-
* Surface publique du SDK Naya ID — Angular.
|
|
282
|
-
*
|
|
283
|
-
* Ce que l'application cliente importe : le service d'entrée, les modèles de
|
|
284
|
-
* configuration et de résultat, et le type d'erreur du client HTTP.
|
|
285
|
-
*/
|
|
286
|
-
|
|
287
|
-
/**
|
|
288
|
-
* Generated bundle index. Do not edit.
|
|
289
|
-
*/
|
|
290
|
-
|
|
291
|
-
export { NayaApiClient as N, NayaApiError as a, NAYA_COUNTRIES as b, countryLabel as c, documentNeedsVerso as d, errorResult as e, NAYA_DOCUMENT_TYPES as f, NayaIdService as g };
|
|
292
|
-
//# sourceMappingURL=41devs-naya-id-angular-41devs-naya-id-angular-B7t92Ogc.mjs.map
|