@sekyro/node 0.1.0-rc.3 → 0.1.0-rc.4
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/CHANGELOG.md +28 -0
- package/LICENSE +25 -16
- package/README.md +66 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +479 -14
- package/dist/index.d.ts +479 -14
- package/dist/index.js +1 -1
- package/package.json +2 -2
- package/sbom.cdx.json +5 -5
package/dist/index.d.cts
CHANGED
|
@@ -16,12 +16,14 @@ type SessionStatus = "created" | "in_progress" | "review_pending" | "completed"
|
|
|
16
16
|
type SessionOutcome = "approved" | "review" | "rejected";
|
|
17
17
|
/**
|
|
18
18
|
* How the person proves their identity on an optional-document app: type the
|
|
19
|
-
* national number, or photograph the document.
|
|
19
|
+
* national number, or photograph the document (`document_chip`: native NFC clients only).
|
|
20
|
+
* `national_eid`: the country's national eID (e.g. Houwiyeti for Mauritania),
|
|
21
|
+
* offered when the app's profile turns the national eID on.
|
|
20
22
|
* @public
|
|
21
23
|
*/
|
|
22
|
-
type IdentityMethod = "national_number" | "document_photo";
|
|
24
|
+
type IdentityMethod = "national_number" | "document_photo" | "document_chip" | "national_eid";
|
|
23
25
|
/** The verification checks a flow may contain. @public */
|
|
24
|
-
type CheckType = "liveness" | "face_match" | "doc_ocr" | "population_registry" | "phone_otp";
|
|
26
|
+
type CheckType = "liveness" | "face_match" | "doc_ocr" | "population_registry" | "phone_otp" | "nfc_chip" | "email_otp" | "portrait_icao" | "eid_auth";
|
|
25
27
|
/** Per-check execution state within a session. @public */
|
|
26
28
|
type CheckState = "pending" | "input_required" | "processing" | "passed" | "failed" | "review" | "skipped";
|
|
27
29
|
/**
|
|
@@ -79,6 +81,14 @@ type PolicyFailureReason = SessionFailureReason | EligibilityReason | "document_
|
|
|
79
81
|
* @public
|
|
80
82
|
*/
|
|
81
83
|
type MatchReason = "name_mismatch" | "birth_date_mismatch" | "nationality_mismatch" | "document_number_mismatch";
|
|
84
|
+
/**
|
|
85
|
+
* Face-match probe-binding reason a `face_match` {@link SessionStep.reason} may
|
|
86
|
+
* carry (SDK spec §4.10): `probe_not_from_liveness` — the face image isn't the
|
|
87
|
+
* person in the liveness clip. Retryable within the step's attempts (the
|
|
88
|
+
* person re-takes the liveness capture); billed.
|
|
89
|
+
* @public
|
|
90
|
+
*/
|
|
91
|
+
type ProbeBindingReason = "probe_not_from_liveness";
|
|
82
92
|
/** Hosted-flow languages. @public */
|
|
83
93
|
type Locale = "ar" | "fr" | "en";
|
|
84
94
|
/** The environment a webhook was emitted from. @public */
|
|
@@ -97,6 +107,57 @@ interface SessionStep {
|
|
|
97
107
|
calibratedScore?: number;
|
|
98
108
|
/** The check failed after using all of its attempts. */
|
|
99
109
|
attemptsExhausted?: boolean;
|
|
110
|
+
/**
|
|
111
|
+
* `portrait_icao` only (ID mode): the per-criterion ICAO report of the last
|
|
112
|
+
* attempt — numbers and enums only, never the image.
|
|
113
|
+
*/
|
|
114
|
+
report?: PortraitReportEntry[];
|
|
115
|
+
/**
|
|
116
|
+
* `face_match` only: the probe-quality measurement of the selfie that was
|
|
117
|
+
* matched (occlusion, head pose, eye openness, sharpness). Recorded for
|
|
118
|
+
* information only: it never changes the step's state or reason.
|
|
119
|
+
*/
|
|
120
|
+
probeQuality?: ProbeQuality;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* The probe-quality measurement on a `face_match` step. Numbers only; `null`
|
|
124
|
+
* means the value could not be measured. Informational: no threshold applies.
|
|
125
|
+
* @public
|
|
126
|
+
*/
|
|
127
|
+
interface ProbeQuality {
|
|
128
|
+
/** Share of the inner face that is covered (a hand, a mask, a phone), in [0, 1]. */
|
|
129
|
+
occlusion: number | null;
|
|
130
|
+
/** Head pose in degrees. */
|
|
131
|
+
pose: {
|
|
132
|
+
yaw: number | null;
|
|
133
|
+
pitch: number | null;
|
|
134
|
+
roll: number | null;
|
|
135
|
+
};
|
|
136
|
+
/** Openness of the less-open eye, in [0, 1]. */
|
|
137
|
+
eyesOpen: number | null;
|
|
138
|
+
/** Sharpness of the face region (higher is sharper; no fixed scale). */
|
|
139
|
+
sharpness: number | null;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* One row of the `portrait_icao` report (ID mode): the server's measurement of
|
|
143
|
+
* one ICAO criterion and the threshold that applied.
|
|
144
|
+
* @public
|
|
145
|
+
*/
|
|
146
|
+
interface PortraitReportEntry {
|
|
147
|
+
criterion: "pose" | "eyes" | "mouth" | "occlusion" | "glare" | "lighting" | "background" | "resolution";
|
|
148
|
+
value: number | null;
|
|
149
|
+
threshold: number | string | null;
|
|
150
|
+
pass: boolean;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* A short-lived link to a session's ICAO portrait (480×640 JPEG), from
|
|
154
|
+
* {@link SessionsApi.portrait}. Download it before `expiresAt`; never store the URL.
|
|
155
|
+
* @public
|
|
156
|
+
*/
|
|
157
|
+
interface SessionPortraitLink {
|
|
158
|
+
url: string;
|
|
159
|
+
/** ISO 8601 (about 5 minutes after the call). */
|
|
160
|
+
expiresAt: string;
|
|
100
161
|
}
|
|
101
162
|
/**
|
|
102
163
|
* Out-of-band delivery of the session's hosted link, sent by Sekyro AI after the
|
|
@@ -134,9 +195,36 @@ interface SessionSubjectInput {
|
|
|
134
195
|
* its webhooks, and searchable on the subjects API.
|
|
135
196
|
*/
|
|
136
197
|
externalRef?: string;
|
|
198
|
+
/**
|
|
199
|
+
* Returning user (profile v2 step 5): verify this already-verified subject
|
|
200
|
+
* again with liveness + face match only, against the reference photo stored
|
|
201
|
+
* on the subject. Name exactly one target. Errors at create:
|
|
202
|
+
* `404 subject_not_found`, `409 subject_revoked`, `409 subject_no_reference`,
|
|
203
|
+
* `409 subject_stale` (older than the app's `reuse.maxAgeMonths`) and
|
|
204
|
+
* `400` / `409 reuse_target_ambiguous`.
|
|
205
|
+
*/
|
|
206
|
+
reuse?: SubjectReuseTarget;
|
|
137
207
|
}
|
|
138
|
-
/**
|
|
139
|
-
|
|
208
|
+
/**
|
|
209
|
+
* Which subject a returning-user session re-verifies — exactly ONE of the
|
|
210
|
+
* subject id, your own `externalRef` (must match a single subject) or the NNI.
|
|
211
|
+
* @public
|
|
212
|
+
*/
|
|
213
|
+
type SubjectReuseTarget = {
|
|
214
|
+
subjectId: string;
|
|
215
|
+
externalRef?: never;
|
|
216
|
+
nni?: never;
|
|
217
|
+
} | {
|
|
218
|
+
externalRef: string;
|
|
219
|
+
subjectId?: never;
|
|
220
|
+
nni?: never;
|
|
221
|
+
} | {
|
|
222
|
+
nni: string;
|
|
223
|
+
subjectId?: never;
|
|
224
|
+
externalRef?: never;
|
|
225
|
+
};
|
|
226
|
+
/** A document type the backend reads (kyc-docs-v2 vocabulary; `carte_identite` = identity card of any issuer). @public */
|
|
227
|
+
type ProfileDocumentType = "carte_identite" | "passport" | "residence_permit";
|
|
140
228
|
/**
|
|
141
229
|
* The settings of an app's eKYC profile that a session may override — a
|
|
142
230
|
* mirror of the backend profile (schema version 2) without `schemaVersion`,
|
|
@@ -146,10 +234,32 @@ type ProfileDocumentType = "carte_identite" | "passport";
|
|
|
146
234
|
* @public
|
|
147
235
|
*/
|
|
148
236
|
interface EkycProfileSettings {
|
|
149
|
-
/**
|
|
237
|
+
/**
|
|
238
|
+
* Phone OTP step: off, or on with where the number comes from. The person
|
|
239
|
+
* chooses WhatsApp or SMS from the channels left after the org's settings
|
|
240
|
+
* and `channels`.
|
|
241
|
+
*/
|
|
150
242
|
phone: "off" | {
|
|
243
|
+
/** Where the number comes from: your `subject.phone` / `input.phone`, the person, or either. */
|
|
151
244
|
numberSource: "prefilled" | "user_entered" | "prefilled_or_entered";
|
|
245
|
+
/**
|
|
246
|
+
* Narrow the channels the person may choose from (absent = every
|
|
247
|
+
* channel the org has on). A channel the org turned off answers
|
|
248
|
+
* `400 phone_channels_disabled_for_org`; an empty or duplicated list
|
|
249
|
+
* `400 phone_channels_invalid`.
|
|
250
|
+
*/
|
|
251
|
+
channels?: Array<"whatsapp" | "sms">;
|
|
252
|
+
/**
|
|
253
|
+
* Which countries codes may be sent to: the profile's allowed
|
|
254
|
+
* `locations` (default), `any`, or a list of ISO 3166-1 alpha-2 codes.
|
|
255
|
+
* Invalid values answer `400 phone_destinations_invalid`.
|
|
256
|
+
*/
|
|
257
|
+
destinations?: "locations" | "any" | {
|
|
258
|
+
countries: string[];
|
|
259
|
+
};
|
|
152
260
|
};
|
|
261
|
+
/** Email OTP step (absent = off): a one-time code sent to the person's email address. */
|
|
262
|
+
email?: "off" | ProfileEmail;
|
|
153
263
|
document: {
|
|
154
264
|
mode: "off" | "optional" | "mandatory";
|
|
155
265
|
/** Accepted document types: `'*'` (all) or a list, optionally per issuing country. */
|
|
@@ -185,6 +295,8 @@ interface EkycProfileSettings {
|
|
|
185
295
|
/** Per-step attempt limits. */
|
|
186
296
|
attempts?: {
|
|
187
297
|
phone: number;
|
|
298
|
+
/** Email OTP attempts (1–5); absent = the platform default. */
|
|
299
|
+
email?: number;
|
|
188
300
|
document: number;
|
|
189
301
|
registry: number;
|
|
190
302
|
liveness: number;
|
|
@@ -227,6 +339,32 @@ interface EkycProfileSettings {
|
|
|
227
339
|
action: "signal" | "block";
|
|
228
340
|
};
|
|
229
341
|
};
|
|
342
|
+
/**
|
|
343
|
+
* The live photo. `purpose: "id_document"` also takes an ICAO 480×640 portrait you
|
|
344
|
+
* download for printing on an ID document. `icao` makes a verification selfie meet
|
|
345
|
+
* the ICAO photo rules: `"reject"` asks the person to retake a non-compliant photo
|
|
346
|
+
* (after the last attempt the session fails, or goes to review in review mode);
|
|
347
|
+
* `"alert"` lets the person continue and adds the risk signal `icao_non_compliant`.
|
|
348
|
+
* Both need liveness on; `"alert"` with `"id_document"` answers
|
|
349
|
+
* `400 portrait_icao_policy_id_document`. Absent = a verification selfie, no ICAO check.
|
|
350
|
+
*/
|
|
351
|
+
portrait?: {
|
|
352
|
+
purpose?: "verification" | "id_document";
|
|
353
|
+
icao?: {
|
|
354
|
+
policy: "alert" | "reject";
|
|
355
|
+
};
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* The email OTP step of a profile. When the email check is not available on
|
|
360
|
+
* the platform yet, saving it answers `400 email_otp_not_available`.
|
|
361
|
+
* @public
|
|
362
|
+
*/
|
|
363
|
+
interface ProfileEmail {
|
|
364
|
+
/** Where the address comes from: your `input.email`, the person, or either. */
|
|
365
|
+
emailSource: "prefilled" | "user_entered" | "prefilled_or_entered";
|
|
366
|
+
/** Disposable (temporary) addresses: allowed, flagged as a risk signal (default), or refused. */
|
|
367
|
+
disposable?: "allow" | "signal" | "block";
|
|
230
368
|
}
|
|
231
369
|
/**
|
|
232
370
|
* `T` with every property optional, recursively. Arrays are replaced as a
|
|
@@ -296,11 +434,59 @@ interface CreateSessionInput {
|
|
|
296
434
|
nni?: string;
|
|
297
435
|
/** E.164 phone number, e.g. `+22236123456`. */
|
|
298
436
|
phone?: string;
|
|
437
|
+
/** Email address for the email OTP step (`emailSource` `prefilled` / `prefilled_or_entered`). */
|
|
438
|
+
email?: string;
|
|
299
439
|
fullName?: string;
|
|
300
440
|
/** ISO 8601 date (`YYYY-MM-DD`). */
|
|
301
441
|
birthDate?: string;
|
|
442
|
+
/**
|
|
443
|
+
* Partner-supplied identity data (`supplied` mode only): the person's
|
|
444
|
+
* biographic record and photo as YOUR system holds them — for example
|
|
445
|
+
* from your own ANRPTS answer, converted with {@link registryFromAnrpts}.
|
|
446
|
+
* Sekyro AI stores it as data you vouch for, makes no registry call, and
|
|
447
|
+
* never receives or stores any registry key. `nni` must be set too and
|
|
448
|
+
* equal `suppliedIdentity.nni`. Refused unless Sekyro AI enabled the mode
|
|
449
|
+
* for the environment (`403 supplied_identity_not_entitled`); required in
|
|
450
|
+
* that mode when the app verifies identity (`422 supplied_identity_required`).
|
|
451
|
+
*/
|
|
452
|
+
suppliedIdentity?: SuppliedIdentityRecord;
|
|
302
453
|
} & Record<string, unknown>;
|
|
303
454
|
}
|
|
455
|
+
/**
|
|
456
|
+
* Partner-supplied identity data (`sessions.create` `input.suppliedIdentity`):
|
|
457
|
+
* the person's biographic record and photo, as your organization holds them.
|
|
458
|
+
* Sekyro AI treats it as identity data supplied by your organization, not as
|
|
459
|
+
* a registry lookup. Refusals at create: `400 supplied_identity_nni_mismatch`,
|
|
460
|
+
* `422 supplied_identity_stale` (`fetchedAt` older than 24 h),
|
|
461
|
+
* `422 supplied_identity_photo_unusable` (not a JPEG/PNG of at most 1 MB within the
|
|
462
|
+
* size bounds). In a `supplied` environment whose app verifies identity, a create
|
|
463
|
+
* without `input.suppliedIdentity` is `422 supplied_identity_required`. The face on
|
|
464
|
+
* the photo is checked after consent, at the face match (`no_face_reference`).
|
|
465
|
+
* @public
|
|
466
|
+
*/
|
|
467
|
+
interface SuppliedIdentityRecord {
|
|
468
|
+
/** 10-digit NNI, as a string. */
|
|
469
|
+
nni: string;
|
|
470
|
+
firstNameFr: string;
|
|
471
|
+
lastNameFr: string;
|
|
472
|
+
fatherNameFr?: string;
|
|
473
|
+
firstNameAr: string;
|
|
474
|
+
lastNameAr: string;
|
|
475
|
+
fatherNameAr?: string;
|
|
476
|
+
/** ISO 8601 date (`YYYY-MM-DD`). */
|
|
477
|
+
birthDate: string;
|
|
478
|
+
birthPlaceFr?: string;
|
|
479
|
+
birthPlaceAr?: string;
|
|
480
|
+
sex?: "M" | "F";
|
|
481
|
+
/** Nationality text as your source holds it (e.g. `Mauritanienne`). */
|
|
482
|
+
nationalities?: string[];
|
|
483
|
+
/** Base64 JPEG or PNG (at most 1 MB decoded). */
|
|
484
|
+
photo: string;
|
|
485
|
+
/** ISO 8601 date (`YYYY-MM-DD`) of the registry photo. */
|
|
486
|
+
photoDate?: string;
|
|
487
|
+
/** ISO 8601 date-time at which your system obtained this record. */
|
|
488
|
+
fetchedAt: string;
|
|
489
|
+
}
|
|
304
490
|
/** Per-request options. @public */
|
|
305
491
|
interface RequestOptions {
|
|
306
492
|
/**
|
|
@@ -382,6 +568,43 @@ interface SessionDevice {
|
|
|
382
568
|
deviceKeys: string[];
|
|
383
569
|
signals: SessionDeviceSignal[];
|
|
384
570
|
}
|
|
571
|
+
/**
|
|
572
|
+
* The national eID that verified the session's identity (the `eid_auth` check
|
|
573
|
+
* passed): the provider id (`{country}.{provider}`, e.g. `MR.houwiyeti`), its
|
|
574
|
+
* ISO 3166-1 alpha-2 country and when. A passed eID ends the session.
|
|
575
|
+
* @public
|
|
576
|
+
*/
|
|
577
|
+
interface EidResult {
|
|
578
|
+
provider: string;
|
|
579
|
+
country: string;
|
|
580
|
+
verifiedAt: string;
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* The full phone number and email address the person verified in a session
|
|
584
|
+
* (an OTP check that passed) — sent ONLY to you (the session view and your
|
|
585
|
+
* webhooks), never to the person's browser, and removed when the session's
|
|
586
|
+
* personal data is purged. You are the controller of these values. A
|
|
587
|
+
* prefilled value that was not verified is never listed.
|
|
588
|
+
* @public
|
|
589
|
+
*/
|
|
590
|
+
interface VerifiedContacts {
|
|
591
|
+
/** From a passed `phone_otp` check. */
|
|
592
|
+
phone?: {
|
|
593
|
+
/** E.164, e.g. `+22236123456`. */
|
|
594
|
+
number: string;
|
|
595
|
+
/** The channel the code was delivered on. */
|
|
596
|
+
channel: "whatsapp" | "sms";
|
|
597
|
+
/** ISO 8601. */
|
|
598
|
+
verifiedAt: string;
|
|
599
|
+
};
|
|
600
|
+
/** From a passed `email_otp` check. */
|
|
601
|
+
email?: {
|
|
602
|
+
/** The verified address (domain lowercased). */
|
|
603
|
+
address: string;
|
|
604
|
+
/** ISO 8601. */
|
|
605
|
+
verifiedAt: string;
|
|
606
|
+
};
|
|
607
|
+
}
|
|
385
608
|
/**
|
|
386
609
|
* The whitelisted session view returned by {@link SessionsApi.get}. Never
|
|
387
610
|
* contains the client token.
|
|
@@ -424,9 +647,27 @@ interface Session {
|
|
|
424
647
|
overriddenFields?: string[];
|
|
425
648
|
/**
|
|
426
649
|
* Risk signals recorded on the session (e.g. `device_velocity`,
|
|
427
|
-
* `timezone_mismatch`
|
|
650
|
+
* `timezone_mismatch`, `icao_non_compliant` when an `alert` ICAO policy flagged
|
|
651
|
+
* the selfie) — signals only, never a verdict by themselves.
|
|
428
652
|
*/
|
|
429
653
|
riskSignals?: string[];
|
|
654
|
+
/**
|
|
655
|
+
* `true` for a returning-user session (created with
|
|
656
|
+
* {@link SessionSubjectInput.reuse}): liveness + face match against the
|
|
657
|
+
* subject's stored reference photo only.
|
|
658
|
+
*/
|
|
659
|
+
returning?: true;
|
|
660
|
+
/** On a returning-user session: the subject (person) it re-verifies. */
|
|
661
|
+
reuseOf?: string;
|
|
662
|
+
/** The contacts verified in this session (passed OTP checks only); absent when none. */
|
|
663
|
+
verifiedContacts?: VerifiedContacts;
|
|
664
|
+
/** The national eID that verified this session (the `eid_auth` check passed); absent otherwise. */
|
|
665
|
+
eid?: EidResult;
|
|
666
|
+
/**
|
|
667
|
+
* ID mode (`portrait.purpose = id_document`) only: the ICAO portrait can be
|
|
668
|
+
* fetched with {@link SessionsApi.portrait}.
|
|
669
|
+
*/
|
|
670
|
+
portraitAvailable?: boolean;
|
|
430
671
|
}
|
|
431
672
|
/**
|
|
432
673
|
* `data` of the terminal / review-pending session lifecycle events
|
|
@@ -463,6 +704,10 @@ interface SessionLifecycleEventData {
|
|
|
463
704
|
* different subject than `subjectId` — the subjects are never merged.
|
|
464
705
|
*/
|
|
465
706
|
subjectConflict?: boolean;
|
|
707
|
+
/** `true` on a returning-user session (liveness + face match against the stored photo). */
|
|
708
|
+
returning?: true;
|
|
709
|
+
/** On a returning-user session: the subject (person) it re-verifies. */
|
|
710
|
+
reuseOf?: string;
|
|
466
711
|
/**
|
|
467
712
|
* On `session.failed` with `failureReason: 'device_cooldown'`: ISO time
|
|
468
713
|
* from which the device may start a new verification.
|
|
@@ -470,18 +715,129 @@ interface SessionLifecycleEventData {
|
|
|
470
715
|
retryAfter?: string;
|
|
471
716
|
/** Dotted profile paths the session's create-time override changed. */
|
|
472
717
|
overriddenFields?: string[];
|
|
718
|
+
/** On `completed` / `failed`: the contacts verified in this session (passed OTP checks only). */
|
|
719
|
+
verifiedContacts?: VerifiedContacts;
|
|
720
|
+
/** On `completed` / `failed`: the national eID that verified this session, when one did. */
|
|
721
|
+
eid?: EidResult;
|
|
722
|
+
/**
|
|
723
|
+
* ID mode only, on `completed` / `failed`: the ICAO portrait can be fetched
|
|
724
|
+
* with {@link SessionsApi.portrait} (the event never carries the image).
|
|
725
|
+
*/
|
|
726
|
+
portraitAvailable?: boolean;
|
|
473
727
|
}
|
|
474
728
|
/**
|
|
475
|
-
* `data` of `subject.updated` — a session linked to the subject reached
|
|
476
|
-
* terminal state
|
|
729
|
+
* `data` of `subject.updated` — either a session linked to the subject reached
|
|
730
|
+
* a terminal state (`sessionId`, session `status`, `outcome`), or the subject
|
|
731
|
+
* was revoked (`status: 'revoked'`, no session). Ids and enums only.
|
|
477
732
|
* @public
|
|
478
733
|
*/
|
|
479
734
|
interface SubjectUpdatedEventData {
|
|
480
735
|
subjectId: string;
|
|
736
|
+
/** The session that reached a terminal state; absent on a revocation. */
|
|
737
|
+
sessionId?: string;
|
|
738
|
+
status: SessionStatus | "revoked";
|
|
739
|
+
/** The session outcome; absent on a revocation. */
|
|
740
|
+
outcome?: SessionOutcome | null;
|
|
741
|
+
}
|
|
742
|
+
/**
|
|
743
|
+
* `data` of `subject.enrolled` — the subject's first reference photo was
|
|
744
|
+
* stored (it can now be used for returning-user sessions). Ids and enums only.
|
|
745
|
+
* @public
|
|
746
|
+
*/
|
|
747
|
+
interface SubjectEnrolledEventData {
|
|
748
|
+
subjectId: string;
|
|
749
|
+
/** The approved session the reference photo came from. */
|
|
481
750
|
sessionId: string;
|
|
751
|
+
assurance: SubjectAssurance;
|
|
752
|
+
}
|
|
753
|
+
/**
|
|
754
|
+
* `data` of `subject.deleted`. A delete through the subjects API carries
|
|
755
|
+
* `subjectId`; a right-to-erasure request carries the tokenized `subjectRef`
|
|
756
|
+
* (with `orgId` / `env`) instead — never the national number.
|
|
757
|
+
* @public
|
|
758
|
+
*/
|
|
759
|
+
interface SubjectDeletedEventData {
|
|
760
|
+
subjectId?: string;
|
|
761
|
+
subjectRef?: string;
|
|
762
|
+
orgId?: string;
|
|
763
|
+
env?: SekyroEnvironment;
|
|
764
|
+
}
|
|
765
|
+
/** Subject lifecycle: a revoked subject cannot be reused. @public */
|
|
766
|
+
type SubjectStatus = "active" | "revoked";
|
|
767
|
+
/**
|
|
768
|
+
* How strongly a subject's identity was established: the reference photo
|
|
769
|
+
* came from the national registry, the document's chip (`chip_biometric`, a
|
|
770
|
+
* passed chip read plus a face match) or the document, and a face match passed
|
|
771
|
+
* (`*_biometric`) or the session had no face match (`*_only`). `supplied_*`:
|
|
772
|
+
* partner-supplied identity data (`input.suppliedIdentity`), with
|
|
773
|
+
* (`supplied_biometric`) or without (`supplied_only`) a face match against its photo.
|
|
774
|
+
* @public
|
|
775
|
+
*/
|
|
776
|
+
type SubjectAssurance = "registry_biometric" | "chip_biometric" | "document_biometric" | "registry_only" | "document_only" | "supplied_biometric" | "supplied_only";
|
|
777
|
+
/**
|
|
778
|
+
* Origin of a subject's stored reference photo, best first (`chip`: the document chip's portrait;
|
|
779
|
+
* `org_supplied`: the photo of your partner-supplied identity data).
|
|
780
|
+
* @public
|
|
781
|
+
*/
|
|
782
|
+
type SubjectReferenceSource = "registry" | "doc_registry" | "chip" | "org_supplied" | "document";
|
|
783
|
+
/** One session linked to a subject. @public */
|
|
784
|
+
interface SubjectSession {
|
|
785
|
+
sessionId: string;
|
|
786
|
+
appId: string | null;
|
|
787
|
+
/** ISO 8601 — when the session was linked. */
|
|
788
|
+
at: string;
|
|
482
789
|
status: SessionStatus;
|
|
483
790
|
outcome: SessionOutcome | null;
|
|
484
791
|
}
|
|
792
|
+
/**
|
|
793
|
+
* A subject (the same person across your apps), as `GET /subjects/:id`
|
|
794
|
+
* returns it. Never contains photo keys or URLs.
|
|
795
|
+
* @public
|
|
796
|
+
*/
|
|
797
|
+
interface Subject {
|
|
798
|
+
id: string;
|
|
799
|
+
status: SubjectStatus;
|
|
800
|
+
/** ISO 8601 — present only when revoked. */
|
|
801
|
+
revokedAt?: string;
|
|
802
|
+
sessions: SubjectSession[];
|
|
803
|
+
externalRefs: string[];
|
|
804
|
+
/** ISO 8601. */
|
|
805
|
+
firstSeenAt: string;
|
|
806
|
+
/** ISO 8601. */
|
|
807
|
+
lastSeenAt: string;
|
|
808
|
+
/** ISO 8601, or `null` before the first approved session. */
|
|
809
|
+
lastPassedAt: string | null;
|
|
810
|
+
/** ISO 8601 of the last approved full or returning session, or `null`. */
|
|
811
|
+
lastVerifiedAt: string | null;
|
|
812
|
+
/** The stored reference photo's origin and date — `null` until one is stored. */
|
|
813
|
+
reference: {
|
|
814
|
+
source: SubjectReferenceSource;
|
|
815
|
+
capturedAt: string;
|
|
816
|
+
} | null;
|
|
817
|
+
assurance: SubjectAssurance | null;
|
|
818
|
+
/**
|
|
819
|
+
* A returning-user session can be created now: active, a reference photo is
|
|
820
|
+
* stored, and the last FULL verification (returning-user sessions do not
|
|
821
|
+
* reset it) is within your app's
|
|
822
|
+
* `reuse.maxAgeMonths` (when set).
|
|
823
|
+
*/
|
|
824
|
+
returningReady: boolean;
|
|
825
|
+
/** The verified name / birth date of the latest approved session. */
|
|
826
|
+
display?: {
|
|
827
|
+
name?: string;
|
|
828
|
+
birthDate?: string;
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
/** Result of {@link SubjectsApi.delete}. @public */
|
|
832
|
+
interface DeletedSubject {
|
|
833
|
+
id: string;
|
|
834
|
+
deleted: true;
|
|
835
|
+
}
|
|
836
|
+
/** Options of {@link SubjectsApi.revoke}. @public */
|
|
837
|
+
interface RevokeSubjectInput {
|
|
838
|
+
/** Kept on the audit trail only (≤ 500 characters). Do not put personal data here. */
|
|
839
|
+
reason?: string;
|
|
840
|
+
}
|
|
485
841
|
/**
|
|
486
842
|
* `data` of `subject.suspicious_activity` — a device already linked to
|
|
487
843
|
* ANOTHER subject was used for a session of this subject. `count` is the
|
|
@@ -510,6 +866,12 @@ interface SessionStepCompletedEventData {
|
|
|
510
866
|
* different subject than `subjectId` — the subjects are never merged.
|
|
511
867
|
*/
|
|
512
868
|
subjectConflict?: boolean;
|
|
869
|
+
/** `true` on a returning-user session (liveness + face match against the stored photo). */
|
|
870
|
+
returning?: true;
|
|
871
|
+
/** On a returning-user session: the subject (person) it re-verifies. */
|
|
872
|
+
reuseOf?: string;
|
|
873
|
+
/** When the passed check is `phone_otp` / `email_otp`: that one verified contact. */
|
|
874
|
+
verifiedContacts?: VerifiedContacts;
|
|
513
875
|
}
|
|
514
876
|
/**
|
|
515
877
|
* `data` of `session.review_decided` — a human (or the review-timeout sweep)
|
|
@@ -531,6 +893,12 @@ interface SessionReviewDecidedEventData {
|
|
|
531
893
|
* different subject than `subjectId` — the subjects are never merged.
|
|
532
894
|
*/
|
|
533
895
|
subjectConflict?: boolean;
|
|
896
|
+
/** `true` on a returning-user session (liveness + face match against the stored photo). */
|
|
897
|
+
returning?: true;
|
|
898
|
+
/** On a returning-user session: the subject (person) it re-verifies. */
|
|
899
|
+
reuseOf?: string;
|
|
900
|
+
/** ID mode only: the ICAO portrait can be fetched with {@link SessionsApi.portrait}. */
|
|
901
|
+
portraitAvailable?: boolean;
|
|
534
902
|
}
|
|
535
903
|
/**
|
|
536
904
|
* Event type → the shape of its `data`. Session events are typed; the
|
|
@@ -547,10 +915,10 @@ interface WebhookEventDataMap {
|
|
|
547
915
|
"session.rejected": SessionLifecycleEventData;
|
|
548
916
|
"session.expired": SessionLifecycleEventData;
|
|
549
917
|
"session.failed": SessionLifecycleEventData;
|
|
550
|
-
"subject.enrolled":
|
|
918
|
+
"subject.enrolled": SubjectEnrolledEventData;
|
|
551
919
|
"subject.updated": SubjectUpdatedEventData;
|
|
552
920
|
"subject.suspicious_activity": SubjectSuspiciousActivityEventData;
|
|
553
|
-
"subject.deleted":
|
|
921
|
+
"subject.deleted": SubjectDeletedEventData;
|
|
554
922
|
"aml.match_flagged": Record<string, unknown>;
|
|
555
923
|
"payment.received": Record<string, unknown>;
|
|
556
924
|
"invoice.generated": Record<string, unknown>;
|
|
@@ -638,7 +1006,7 @@ declare class SessionsApi {
|
|
|
638
1006
|
* surface on purpose (only its bound `call` crosses this boundary).
|
|
639
1007
|
* @internal
|
|
640
1008
|
*/
|
|
641
|
-
constructor(call: <T>(method: "GET" | "POST", path: string, body?: unknown, idempotencyKey?: string) => Promise<T>);
|
|
1009
|
+
constructor(call: <T>(method: "GET" | "POST" | "DELETE", path: string, body?: unknown, idempotencyKey?: string) => Promise<T>);
|
|
642
1010
|
/**
|
|
643
1011
|
* `POST /sessions`. Returns the one-time `clientToken` — hand it to the
|
|
644
1012
|
* browser, never persist it. Pass an `idempotencyKey` so a retried call
|
|
@@ -654,6 +1022,47 @@ declare class SessionsApi {
|
|
|
654
1022
|
selectMethod(id: string, method: IdentityMethod): Promise<Session>;
|
|
655
1023
|
/** `GET /sessions/:id` — the whitelisted view (no client token). */
|
|
656
1024
|
get(id: string): Promise<Session>;
|
|
1025
|
+
/**
|
|
1026
|
+
* `GET /sessions/:id/portrait?format=url` — ID mode: a 5-minute presigned
|
|
1027
|
+
* link to the 480×640 ICAO portrait (JPEG). Needs the `portrait:read` scope
|
|
1028
|
+
* (keys minted from the dashboard carry it). `404 portrait_not_available`
|
|
1029
|
+
* until the session's `portrait_icao` check has passed (`portraitAvailable`).
|
|
1030
|
+
*/
|
|
1031
|
+
portrait(id: string): Promise<SessionPortraitLink>;
|
|
1032
|
+
}
|
|
1033
|
+
/**
|
|
1034
|
+
* `sekyro.subjects` — read and manage subjects (the same person across your
|
|
1035
|
+
* apps). Reads need the `subjects:read` scope, `revoke` / `delete` the
|
|
1036
|
+
* `subjects:write` scope (keys minted from the dashboard carry both; an older
|
|
1037
|
+
* key answers `403 insufficient_scope`). A foreign or unknown id answers
|
|
1038
|
+
* `404 subject_not_found`.
|
|
1039
|
+
*
|
|
1040
|
+
* Type-only export, like {@link SessionsApi}: obtained through
|
|
1041
|
+
* {@link Sekyro.subjects}.
|
|
1042
|
+
* @public
|
|
1043
|
+
*/
|
|
1044
|
+
declare class SubjectsApi {
|
|
1045
|
+
private readonly call;
|
|
1046
|
+
/** @internal */
|
|
1047
|
+
constructor(call: <T>(method: "GET" | "POST" | "DELETE", path: string, body?: unknown, idempotencyKey?: string) => Promise<T>);
|
|
1048
|
+
/** `GET /subjects/:id` — the subject, its sessions and its returning-user readiness. */
|
|
1049
|
+
get(id: string): Promise<Subject>;
|
|
1050
|
+
/** `GET /subjects?externalRef=…` — the subjects carrying your own id (newest first, at most 50). */
|
|
1051
|
+
list(query: {
|
|
1052
|
+
externalRef: string;
|
|
1053
|
+
}): Promise<Subject[]>;
|
|
1054
|
+
/**
|
|
1055
|
+
* `POST /subjects/:id/revoke` — the subject can no longer be used for
|
|
1056
|
+
* returning-user sessions. Idempotent: revoking again returns the same view.
|
|
1057
|
+
* Emits `subject.updated` with `status: 'revoked'`.
|
|
1058
|
+
*/
|
|
1059
|
+
revoke(id: string, input?: RevokeSubjectInput, opts?: RequestOptions): Promise<Subject>;
|
|
1060
|
+
/**
|
|
1061
|
+
* `DELETE /subjects/:id` — deletes the subject's stored photos, face
|
|
1062
|
+
* templates and identifiers, and unlinks its sessions. Emits
|
|
1063
|
+
* `subject.deleted`. Cannot be undone; a second call answers `404`.
|
|
1064
|
+
*/
|
|
1065
|
+
delete(id: string): Promise<DeletedSubject>;
|
|
657
1066
|
}
|
|
658
1067
|
/**
|
|
659
1068
|
* Sekyro AI partner API client. Server-side only: it carries your API key.
|
|
@@ -671,6 +1080,7 @@ declare class SessionsApi {
|
|
|
671
1080
|
*/
|
|
672
1081
|
declare class Sekyro {
|
|
673
1082
|
readonly sessions: SessionsApi;
|
|
1083
|
+
readonly subjects: SubjectsApi;
|
|
674
1084
|
constructor(opts: SekyroOptions);
|
|
675
1085
|
}
|
|
676
1086
|
|
|
@@ -687,7 +1097,7 @@ declare class SekyroWebhookError extends Error {
|
|
|
687
1097
|
constructor(code: SekyroWebhookErrorCode, message?: string);
|
|
688
1098
|
}
|
|
689
1099
|
/** Why the {@link Sekyro} constructor rejected its options. @public */
|
|
690
|
-
type SekyroConfigErrorCode = "missing_api_key" | "invalid_base_url";
|
|
1100
|
+
type SekyroConfigErrorCode = "missing_api_key" | "invalid_base_url" | "invalid_registry_record";
|
|
691
1101
|
/**
|
|
692
1102
|
* Thrown synchronously by `new Sekyro(...)` for an unusable configuration —
|
|
693
1103
|
* before any request is made. Extends `TypeError` so existing
|
|
@@ -731,6 +1141,61 @@ declare class SekyroApiError extends Error {
|
|
|
731
1141
|
constructor(init: SekyroApiErrorInit);
|
|
732
1142
|
}
|
|
733
1143
|
|
|
1144
|
+
/**
|
|
1145
|
+
* The raw ANRPTS `getPersonne` answer your server received with your own
|
|
1146
|
+
* access: `{ personne, photo }`, where `photo` is a base64 JPEG (optionally
|
|
1147
|
+
* data-URL prefixed). Only the fields the mapping reads are typed.
|
|
1148
|
+
* @public
|
|
1149
|
+
*/
|
|
1150
|
+
interface AnrptsPersonneResponse {
|
|
1151
|
+
personne?: {
|
|
1152
|
+
nni?: string | undefined;
|
|
1153
|
+
prenomFr?: string | undefined;
|
|
1154
|
+
patronymeFr?: string | undefined;
|
|
1155
|
+
perePrenomFr?: string | undefined;
|
|
1156
|
+
prenomAr?: string | undefined;
|
|
1157
|
+
patronymeAr?: string | undefined;
|
|
1158
|
+
perePrenomAr?: string | undefined;
|
|
1159
|
+
/** ISO date or date-time (`1990-01-01T00:00:00.000Z`), or `DD/MM/YYYY`. */
|
|
1160
|
+
dateNaissance?: string | undefined;
|
|
1161
|
+
lieuNaissanceFr?: string | undefined;
|
|
1162
|
+
lieuNaissanceAr?: string | undefined;
|
|
1163
|
+
sexeCode?: string | undefined;
|
|
1164
|
+
nationalities?: string[] | undefined;
|
|
1165
|
+
[key: string]: unknown;
|
|
1166
|
+
};
|
|
1167
|
+
photo?: string | undefined;
|
|
1168
|
+
datePhoto?: string | undefined;
|
|
1169
|
+
[key: string]: unknown;
|
|
1170
|
+
}
|
|
1171
|
+
/** Options of {@link registryFromAnrpts}. @public */
|
|
1172
|
+
interface RegistryFromAnrptsOptions {
|
|
1173
|
+
/**
|
|
1174
|
+
* When YOUR system received this ANRPTS answer (not "now" when you map a cached
|
|
1175
|
+
* answer). Required: records older than 24 h are refused at session create.
|
|
1176
|
+
*/
|
|
1177
|
+
fetchedAt: Date | string;
|
|
1178
|
+
}
|
|
1179
|
+
/**
|
|
1180
|
+
* Convert an ANRPTS `getPersonne` answer that YOUR server already received,
|
|
1181
|
+
* with your own access, into the `input.suppliedIdentity` record of
|
|
1182
|
+
* `sessions.create` (partner-supplied identity data). A pure, local mapping:
|
|
1183
|
+
* it makes no network call, and Sekyro AI never sees, receives or stores any
|
|
1184
|
+
* ANRPTS key — only the record and photo you pass.
|
|
1185
|
+
*
|
|
1186
|
+
* ```ts
|
|
1187
|
+
* const anrpts = await myAnrptsClient.getPersonne(nni); // your call, your key
|
|
1188
|
+
* const suppliedIdentity = registryFromAnrpts(anrpts, { fetchedAt: receivedAt });
|
|
1189
|
+
* await sekyro.sessions.create({ input: { nni, suppliedIdentity } });
|
|
1190
|
+
* ```
|
|
1191
|
+
*
|
|
1192
|
+
* Throws {@link SekyroConfigError} (`invalid_registry_record`) when a required
|
|
1193
|
+
* field (NNI, French and Arabic first and last names, birth date, photo) is
|
|
1194
|
+
* missing. The message names the field, never its value.
|
|
1195
|
+
* @public
|
|
1196
|
+
*/
|
|
1197
|
+
declare function registryFromAnrpts(response: AnrptsPersonneResponse, options: RegistryFromAnrptsOptions): SuppliedIdentityRecord;
|
|
1198
|
+
|
|
734
1199
|
/**
|
|
735
1200
|
* The HTTP header carrying the webhook signature:
|
|
736
1201
|
* `t=<unix seconds>,v1=<hex>[,v1=<hex>]`.
|
|
@@ -787,4 +1252,4 @@ interface VerifyWebhookOptions {
|
|
|
787
1252
|
*/
|
|
788
1253
|
declare function verifyWebhook(rawBody: string, header: string | null | undefined, secret: string, opts?: VerifyWebhookOptions): WebhookEnvelope;
|
|
789
1254
|
|
|
790
|
-
export { type CheckState, type CheckType, type CreateSessionInput, type CreatedSession, DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, type DecisionReason, type DeepPartial, type DeliverOptions, type EkycProfileOverride, type EkycProfileSettings, type EligibilityReason, type FetchLike, type IdentityMethod, LEGACY_SIGNATURE_HEADER, type Locale, type MatchReason, type PolicyFailureReason, type ProfileDocumentType, type RequestOptions, SEKYRO_SIGNATURE_HEADER, Sekyro, SekyroApiError, type SekyroApiErrorInit, type SekyroClientErrorCode, SekyroConfigError, type SekyroConfigErrorCode, type SekyroEnvironment, type SekyroOptions, SekyroWebhookError, type SekyroWebhookErrorCode, type Session, type SessionDevice, type SessionDeviceSignal, type SessionEventData, type SessionFailureReason, type SessionLifecycleEventData, type SessionNetwork, type SessionNetworkEvent, type SessionOutcome, type SessionReviewDecidedEventData, type SessionStatus, type SessionStep, type SessionStepCompletedEventData, type SessionSubjectInput, SessionsApi, type SubjectSuspiciousActivityEventData, type SubjectUpdatedEventData, type VerifyWebhookOptions, type WebhookEnvelope, type WebhookEnvelopeOf, type WebhookEventDataMap, type WebhookEventType, signatureFromHeaders, verifyWebhook };
|
|
1255
|
+
export { type AnrptsPersonneResponse, type CheckState, type CheckType, type CreateSessionInput, type CreatedSession, DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, type DecisionReason, type DeepPartial, type DeletedSubject, type DeliverOptions, type EidResult, type EkycProfileOverride, type EkycProfileSettings, type EligibilityReason, type FetchLike, type IdentityMethod, LEGACY_SIGNATURE_HEADER, type Locale, type MatchReason, type PolicyFailureReason, type PortraitReportEntry, type ProbeBindingReason, type ProbeQuality, type ProfileDocumentType, type ProfileEmail, type RegistryFromAnrptsOptions, type RequestOptions, type RevokeSubjectInput, SEKYRO_SIGNATURE_HEADER, Sekyro, SekyroApiError, type SekyroApiErrorInit, type SekyroClientErrorCode, SekyroConfigError, type SekyroConfigErrorCode, type SekyroEnvironment, type SekyroOptions, SekyroWebhookError, type SekyroWebhookErrorCode, type Session, type SessionDevice, type SessionDeviceSignal, type SessionEventData, type SessionFailureReason, type SessionLifecycleEventData, type SessionNetwork, type SessionNetworkEvent, type SessionOutcome, type SessionPortraitLink, type SessionReviewDecidedEventData, type SessionStatus, type SessionStep, type SessionStepCompletedEventData, type SessionSubjectInput, SessionsApi, type Subject, type SubjectAssurance, type SubjectDeletedEventData, type SubjectEnrolledEventData, type SubjectReferenceSource, type SubjectReuseTarget, type SubjectSession, type SubjectStatus, type SubjectSuspiciousActivityEventData, type SubjectUpdatedEventData, SubjectsApi, type SuppliedIdentityRecord, type VerifiedContacts, type VerifyWebhookOptions, type WebhookEnvelope, type WebhookEnvelopeOf, type WebhookEventDataMap, type WebhookEventType, registryFromAnrpts, signatureFromHeaders, verifyWebhook };
|