@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.
@@ -1 +0,0 @@
1
- {"version":3,"file":"41devs-naya-id-angular-41devs-naya-id-angular-B7t92Ogc.mjs","sources":["../../../projects/naya-id/src/lib/models/naya-config.ts","../../../projects/naya-id/src/lib/naya-id.service.ts","../../../projects/naya-id/src/lib/models/naya-result.ts","../../../projects/naya-id/src/lib/api/naya-api.client.ts","../../../projects/naya-id/src/public-api.ts","../../../projects/naya-id/src/41devs-naya-id-angular.ts"],"sourcesContent":["/**\n * Configuration du parcours de vérification Naya ID.\n *\n * Reprend, à l'identique, le modèle du SDK Flutter : tous les champs sont\n * optionnels et le SDK fonctionne avec des valeurs par défaut raisonnables\n * (tous pays, tous documents, français).\n */\n\n/** Pays supportés par Naya ID (zone CEDEAO). Code = ISO 3166-1 alpha-2. */\nexport const NAYA_COUNTRIES = [\n { code: 'BJ', label: 'Bénin' },\n { code: 'CI', label: \"Côte d'Ivoire\" },\n { code: 'SN', label: 'Sénégal' },\n { code: 'ML', label: 'Mali' },\n { code: 'BF', label: 'Burkina Faso' },\n { code: 'TG', label: 'Togo' },\n] as const;\n\nexport type NayaCountryCode = (typeof NAYA_COUNTRIES)[number]['code'];\n\n/** Types de documents acceptés. La valeur est envoyée telle quelle à l'API. */\nexport type NayaDocumentType = 'cni' | 'passeport' | 'permis';\n\nexport const NAYA_DOCUMENT_TYPES: readonly NayaDocumentType[] = [\n 'cni',\n 'passeport',\n 'permis',\n];\n\n/** Langues de l'interface du SDK. */\nexport type NayaLocale = 'fr' | 'en';\n\n/**\n * Fournisseur d'authentification.\n *\n * Deux modes, un seul à renseigner :\n * • `apiKey` — la clé d'application est transmise depuis le navigateur.\n * Simple, mais la clé est lisible côté client : à réserver\n * aux démos et aux intégrations où le front est maîtrisé.\n * • `sessionToken` — jeton éphémère obtenu par le backend du client, limité à\n * une vérification. À privilégier en production. Le SDK est\n * prêt à le consommer dès que l'API l'expose.\n *\n * L'abstraction est volontaire : passer de l'un à l'autre ne touche pas au reste\n * du SDK.\n */\nexport interface NayaAuth {\n apiKey?: string;\n sessionToken?: string;\n}\n\n/** Palette optionnelle : surcharge des couleurs de marque. */\nexport interface NayaThemeOverrides {\n /** Couleur principale (défaut : navy Naya #1A3A5C). */\n primaryColor?: string;\n /** Couleur d'accent des CTA (défaut : ambre Naya #F5A623). */\n accentColor?: string;\n}\n\nexport interface NayaConfig {\n /** Pré-sélectionne le pays : l'utilisateur ne le choisit plus. */\n country?: NayaCountryCode;\n\n /**\n * Types de documents proposés. S'il n'y en a qu'un et que `country` est\n * défini, l'écran de sélection est sauté.\n */\n documentTypes?: readonly NayaDocumentType[];\n\n /** Pays proposés quand `country` n'est pas défini. */\n countries?: readonly NayaCountryCode[];\n\n /** Langue de l'interface. */\n locale?: NayaLocale;\n\n /**\n * URL (HTTPS) notifiée par le serveur Naya à chaque décision sur cette\n * session — décision automatique puis, le cas échéant, revue manuelle.\n */\n callbackUrl?: string;\n\n /** Nombre de parcours autorisés après un rejet (bouton « Réessayer »). */\n maxAttempts?: number;\n\n /** Surcharge des couleurs de marque. */\n theme?: NayaThemeOverrides;\n\n /** URL d'un logo client, affiché à côté de « Propulsé par Naya ID ». */\n clientLogoUrl?: string;\n\n /** Base URL de l'API — ne changer que pour un environnement de test. */\n baseUrl?: string;\n\n /**\n * Emplacement des ressources de détection de vivacité (MediaPipe). Par\n * défaut, elles sont chargées depuis un CDN public. Les applications à CSP\n * stricte (qui bloquent les hôtes externes) doivent auto-héberger ces\n * fichiers et renseigner ici leurs URL.\n */\n livenessAssets?: {\n /** Base des fichiers WASM `@mediapipe/tasks-vision`. */\n wasmBaseUrl?: string;\n /** URL du modèle `.task` de Face Landmarker. */\n modelUrl?: string;\n };\n}\n\n/** Configuration effective : `NayaConfig` avec tous les défauts appliqués. */\nexport interface ResolvedNayaConfig {\n country?: NayaCountryCode;\n documentTypes: readonly NayaDocumentType[];\n countries: readonly NayaCountryCode[];\n locale: NayaLocale;\n callbackUrl?: string;\n maxAttempts: number;\n theme: Required<NayaThemeOverrides>;\n clientLogoUrl?: string;\n baseUrl: string;\n livenessAssets: { wasmBaseUrl?: string; modelUrl?: string };\n}\n\nexport const NAYA_DEFAULT_PRIMARY = '#1A3A5C';\nexport const NAYA_DEFAULT_ACCENT = '#F5A623';\nexport const NAYA_DEFAULT_BASE_URL = 'https://api.naya.41devs.com/v1';\n\n/** Applique les valeurs par défaut à une configuration partielle. */\nexport function resolveConfig(config: NayaConfig = {}): ResolvedNayaConfig {\n return {\n country: config.country,\n documentTypes: config.documentTypes ?? NAYA_DOCUMENT_TYPES,\n countries: config.countries ?? NAYA_COUNTRIES.map((c) => c.code),\n locale: config.locale ?? 'fr',\n callbackUrl: config.callbackUrl,\n maxAttempts: config.maxAttempts ?? 2,\n theme: {\n primaryColor: config.theme?.primaryColor ?? NAYA_DEFAULT_PRIMARY,\n accentColor: config.theme?.accentColor ?? NAYA_DEFAULT_ACCENT,\n },\n clientLogoUrl: config.clientLogoUrl,\n baseUrl: config.baseUrl ?? NAYA_DEFAULT_BASE_URL,\n livenessAssets: {\n wasmBaseUrl: config.livenessAssets?.wasmBaseUrl,\n modelUrl: config.livenessAssets?.modelUrl,\n },\n };\n}\n\n/** Libellé lisible d'un code pays. */\nexport function countryLabel(code: NayaCountryCode): string {\n return NAYA_COUNTRIES.find((c) => c.code === code)?.label ?? code;\n}\n\n/** La CNI CEDEAO porte sa MRZ au verso ; passeport et permis n'en ont pas besoin. */\nexport function documentNeedsVerso(doc: NayaDocumentType): boolean {\n return doc === 'cni';\n}\n","import { ApplicationRef, EnvironmentInjector, Injectable, inject } from '@angular/core';\nimport {\n type NayaAuth,\n type NayaConfig,\n resolveConfig,\n} from './models/naya-config';\nimport type { NayaResult } from './models/naya-result';\n\n/**\n * Point d'entrée du SDK Naya ID pour Angular.\n *\n * Injecter le service, puis lancer le parcours :\n *\n * ```ts\n * const result = await this.naya.startVerification({\n * auth: { apiKey: 'naya_live_xxx' },\n * config: { country: 'BJ' },\n * });\n * ```\n *\n * `startVerification` monte l'interface Naya en plein écran au-dessus de\n * l'application, gère la capture et la vivacité, puis résout un `NayaResult` :\n * `approved`, `review`, `rejected`, `cancelled` (l'utilisateur a quitté) ou\n * `error`. Elle ne rejette jamais.\n */\n@Injectable({ providedIn: 'root' })\nexport class NayaIdService {\n private readonly appRef = inject(ApplicationRef);\n private readonly environmentInjector = inject(EnvironmentInjector);\n\n /**\n * Lance le parcours de vérification d'identité.\n *\n * @param params.auth Clé d'application (`apiKey`) ou jeton de session\n * éphémère (`sessionToken`). En production, privilégier\n * le jeton : la clé embarquée dans le front est lisible\n * côté navigateur.\n * @param params.config Configuration optionnelle (pays, documents, langue,\n * callbackUrl, thème…).\n */\n async startVerification(params: {\n auth: NayaAuth;\n config?: NayaConfig;\n }): Promise<NayaResult> {\n const auth = params.auth;\n const config = resolveConfig(params.config);\n\n if (!auth.apiKey && !auth.sessionToken) {\n return {\n status: 'error',\n errorMessage:\n 'Authentification manquante : fournissez auth.apiKey ou auth.sessionToken.',\n };\n }\n\n // L'interface (overlay + écrans) est importée à la demande : elle reste\n // hors du bundle initial de l'application tant que la vérification n'est\n // pas lancée.\n const { mountNayaFlow } = await import('./flow/naya-flow.launcher');\n return mountNayaFlow(\n { appRef: this.appRef, environmentInjector: this.environmentInjector },\n auth,\n config,\n );\n }\n}\n","/**\n * Résultat du parcours, rendu à l'application cliente à la fermeture du SDK.\n * Miroir fidèle du modèle Flutter (`naya_result.dart`).\n */\n\n/** Issue du parcours de vérification. */\nexport type NayaStatus =\n /** Identité vérifiée et approuvée automatiquement. */\n | 'approved'\n /** Dossier envoyé en revue manuelle — décision finale ultérieure. */\n | 'review'\n /** Vérification rejetée (document expiré, visage non concordant…). */\n | 'rejected'\n /** L'utilisateur a quitté le parcours avant la fin. */\n | 'cancelled'\n /** Erreur technique (réseau, serveur…) ayant interrompu le parcours. */\n | 'error';\n\n/**\n * Données d'identité extraites du document par l'OCR Naya, éventuellement\n * corrigées par l'utilisateur.\n */\nexport interface NayaOcrData {\n lastName?: string;\n firstName?: string;\n /** Format YYYY-MM-DD. */\n dateOfBirth?: string;\n placeOfBirth?: string;\n nationality?: string;\n /** Format YYYY-MM-DD. */\n expirationDate?: string;\n documentNumber?: string;\n /** Numéro Personnel d'Identification (Bénin) — 10 chiffres. */\n npi?: string;\n issuingCountry?: string;\n issuingAuthority?: string;\n /** 'M' ou 'F'. */\n gender?: string;\n}\n\nconst OCR_FIELDS: (keyof NayaOcrData)[] = [\n 'lastName', 'firstName', 'dateOfBirth', 'placeOfBirth', 'nationality',\n 'expirationDate', 'documentNumber', 'npi', 'issuingCountry',\n 'issuingAuthority', 'gender',\n];\n\n/** Lit un objet OCR brut de l'API en ne retenant que les champs connus. */\nexport function parseOcrData(raw: unknown): NayaOcrData | undefined {\n if (!raw || typeof raw !== 'object') return undefined;\n const src = raw as Record<string, unknown>;\n const out: NayaOcrData = {};\n for (const field of OCR_FIELDS) {\n const value = src[field];\n if (typeof value === 'string' && value.length > 0) out[field] = value;\n }\n return Object.keys(out).length ? out : undefined;\n}\n\n/** Réduit un objet OCR à ses seuls champs renseignés, en chaînes. */\nexport function ocrToDeclaredData(ocr: NayaOcrData): Record<string, string> {\n const out: Record<string, string> = {};\n for (const field of OCR_FIELDS) {\n const value = ocr[field];\n if (value) out[field] = value;\n }\n return out;\n}\n\n/** Résultat retourné à l'application cliente. */\nexport interface NayaResult {\n status: NayaStatus;\n /**\n * Identifiant de la session Naya — à conserver côté client pour rapprocher\n * les notifications `callbackUrl` et le dashboard.\n */\n verificationId?: string;\n /** Score de risque agrégé 0-100 (plus haut = plus sûr). */\n riskScore?: number;\n /** Concordance faciale document ↔ selfie, 0-100. */\n matchScore?: number;\n /** Intégrité du document, 0-100. */\n authenticityScore?: number;\n /** Score de vivacité, 0-100. */\n livenessScore?: number;\n /** Confiance de l'extraction OCR, 0-100. */\n ocrConfidence?: number;\n /** Données d'identité finales (OCR fusionné avec les corrections). */\n ocrData?: NayaOcrData;\n /** Note d'analyse produite par le pipeline Naya. */\n note?: string;\n /** Détail de l'erreur quand `status` vaut `'error'`. */\n errorMessage?: string;\n}\n\nexport function cancelledResult(verificationId?: string): NayaResult {\n return { status: 'cancelled', verificationId };\n}\n\nexport function errorResult(errorMessage: string, verificationId?: string): NayaResult {\n return { status: 'error', errorMessage, verificationId };\n}\n","import type { NayaAuth } from '../models/naya-config';\nimport { type NayaOcrData, parseOcrData } from '../models/naya-result';\n\n/**\n * Client HTTP du pipeline de vérification Naya.\n *\n * Bâti sur `fetch` natif — la librairie reste ainsi utilisable sans\n * `provideHttpClient` ni dépendance au module HTTP d'Angular. Les délais sont\n * dimensionnés pour les étapes longues (OCR et décision côté serveur).\n *\n * Authentification via `NayaAuth` : `apiKey` (en-tête `X-API-Key`) ou\n * `sessionToken` (en-tête `Authorization: Bearer`). Le choix est transparent\n * pour le reste du SDK.\n */\n\n/** Erreur renvoyée par l'API Naya ou par le transport réseau. */\nexport class NayaApiError extends Error {\n constructor(\n message: string,\n readonly statusCode?: number,\n ) {\n super(message);\n this.name = 'NayaApiError';\n }\n}\n\n/** Réponse de POST /verifications/start. */\nexport interface NayaSession {\n verificationId: string;\n sessionToken: string;\n}\n\n/** Réponse de POST /verifications/:id/submit. */\nexport interface NayaSubmitResponse {\n status: string;\n riskScore?: number;\n matchScore?: number;\n authenticityScore?: number;\n livenessScore?: number;\n ocrConfidence?: number;\n ocrData?: NayaOcrData;\n note?: string;\n}\n\nconst SECONDS = 1000;\n\nexport class NayaApiClient {\n constructor(\n private readonly auth: NayaAuth,\n private readonly baseUrl: string,\n ) {}\n\n private headers(): Record<string, string> {\n const h: Record<string, string> = { 'Content-Type': 'application/json' };\n if (this.auth.sessionToken) {\n h['Authorization'] = `Bearer ${this.auth.sessionToken}`;\n } else if (this.auth.apiKey) {\n h['X-API-Key'] = this.auth.apiKey;\n }\n return h;\n }\n\n private async post<T>(\n path: string,\n body: Record<string, unknown>,\n timeoutMs = 30 * SECONDS,\n ): Promise<T> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n\n let res: Response;\n try {\n res = await fetch(`${this.baseUrl}${path}`, {\n method: 'POST',\n headers: this.headers(),\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n } catch (err) {\n const aborted = err instanceof DOMException && err.name === 'AbortError';\n throw new NayaApiError(\n aborted ? 'Délai dépassé — réessayez.' : 'Réseau indisponible.',\n );\n } finally {\n clearTimeout(timer);\n }\n\n let json: any;\n try {\n json = await res.json();\n } catch {\n throw new NayaApiError('Réponse illisible du serveur.', res.status);\n }\n\n if (res.status >= 400 || json?.success !== true) {\n const message =\n (json?.error && typeof json.error === 'object'\n ? json.error.message\n : undefined) ?? 'Erreur inconnue.';\n throw new NayaApiError(message, res.status);\n }\n return (json.data ?? {}) as T;\n }\n\n /** Ouvre une session de vérification. */\n async start(params: {\n documentType: string;\n country: string;\n callbackUrl?: string;\n }): Promise<NayaSession> {\n const data = await this.post<Record<string, unknown>>(\n '/verifications/start',\n {\n documentType: params.documentType,\n country: params.country,\n ...(params.callbackUrl ? { callbackUrl: params.callbackUrl } : {}),\n device: 'Web',\n },\n );\n return {\n verificationId: String(data['verificationId'] ?? ''),\n sessionToken: String(data['sessionToken'] ?? ''),\n };\n }\n\n /**\n * Envoie le document capturé. L'OCR serveur est synchrone : la réponse\n * contient les champs extraits, utilisés pour pré-remplir l'étape suivante.\n * Le verso, quand il est fourni, porte la MRZ des CNI CEDEAO.\n */\n async uploadDocument(\n verificationId: string,\n params: { rectoBase64: string; versoBase64?: string },\n ): Promise<NayaOcrData | undefined> {\n const data = await this.post<Record<string, unknown>>(\n `/verifications/${verificationId}/document`,\n {\n imageBase64Recto: params.rectoBase64,\n ...(params.versoBase64 ? { imageBase64Verso: params.versoBase64 } : {}),\n },\n 120 * SECONDS,\n );\n return parseOcrData(data['ocrData']);\n }\n\n /**\n * Envoie le selfie et le score de vivacité mesuré sur l'appareil.\n * `matchScore` est requis par l'endpoint mais recalculé côté serveur : on\n * transmet 0, comme le SDK Flutter.\n */\n async submitLiveness(\n verificationId: string,\n params: { livenessScore: number; selfieBase64: string },\n ): Promise<void> {\n await this.post(\n `/verifications/${verificationId}/liveness`,\n {\n livenessScore: params.livenessScore,\n matchScore: 0,\n selfieBase64: params.selfieBase64,\n },\n 60 * SECONDS,\n );\n }\n\n /** Déclenche l'analyse finale (OCR différé, biométrie, AML, décision). */\n async submit(\n verificationId: string,\n userDeclaredData?: Record<string, string>,\n ): Promise<NayaSubmitResponse> {\n const data = await this.post<Record<string, unknown>>(\n `/verifications/${verificationId}/submit`,\n userDeclaredData && Object.keys(userDeclaredData).length\n ? { userDeclaredData }\n : {},\n 180 * SECONDS,\n );\n return {\n status: String(data['status'] ?? 'review'),\n riskScore: numOrUndef(data['riskScore']),\n matchScore: numOrUndef(data['matchScore']),\n authenticityScore: numOrUndef(data['authenticityScore']),\n livenessScore: numOrUndef(data['livenessScore']),\n ocrConfidence: numOrUndef(data['ocrConfidence']),\n ocrData: parseOcrData(data['ocrData']),\n note: typeof data['note'] === 'string' ? (data['note'] as string) : undefined,\n };\n }\n}\n\nfunction numOrUndef(v: unknown): number | undefined {\n return typeof v === 'number' && !Number.isNaN(v) ? v : undefined;\n}\n","/*\n * Surface publique du SDK Naya ID — Angular.\n *\n * Ce que l'application cliente importe : le service d'entrée, les modèles de\n * configuration et de résultat, et le type d'erreur du client HTTP.\n */\n\nexport { NayaIdService } from './lib/naya-id.service';\n\nexport {\n type NayaConfig,\n type NayaAuth,\n type NayaThemeOverrides,\n type NayaCountryCode,\n type NayaDocumentType,\n type NayaLocale,\n NAYA_COUNTRIES,\n NAYA_DOCUMENT_TYPES,\n countryLabel,\n} from './lib/models/naya-config';\n\nexport {\n type NayaResult,\n type NayaStatus,\n type NayaOcrData,\n} from './lib/models/naya-result';\n\nexport { NayaApiError } from './lib/api/naya-api.client';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}