vesant-sdk 1.5.2 → 1.6.1
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/dist/{client-BZxzOidG.d.mts → client-DW1Xiz6a.d.mts} +4 -2
- package/dist/{client-B8pFrXx_.d.ts → client-eLbtPRkh.d.ts} +4 -2
- package/dist/{client-CIon-bGS.d.mts → client-ePzhQKp9.d.mts} +2 -0
- package/dist/{client-CIon-bGS.d.ts → client-ePzhQKp9.d.ts} +2 -0
- package/dist/compliance/index.d.mts +18 -5
- package/dist/compliance/index.d.ts +18 -5
- package/dist/compliance/index.js +222 -42
- package/dist/compliance/index.js.map +1 -1
- package/dist/compliance/index.mjs +222 -42
- package/dist/compliance/index.mjs.map +1 -1
- package/dist/decisions/index.d.mts +1 -1
- package/dist/decisions/index.d.ts +1 -1
- package/dist/decisions/index.js +14 -1
- package/dist/decisions/index.js.map +1 -1
- package/dist/decisions/index.mjs +14 -1
- package/dist/decisions/index.mjs.map +1 -1
- package/dist/geolocation/index.d.mts +3 -3
- package/dist/geolocation/index.d.ts +3 -3
- package/dist/geolocation/index.js +14 -1
- package/dist/geolocation/index.js.map +1 -1
- package/dist/geolocation/index.mjs +14 -1
- package/dist/geolocation/index.mjs.map +1 -1
- package/dist/index.d.mts +6 -376
- package/dist/index.d.ts +6 -376
- package/dist/index.js +289 -251
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +289 -251
- package/dist/index.mjs.map +1 -1
- package/dist/kyc/core.d.mts +1 -1
- package/dist/kyc/core.d.ts +1 -1
- package/dist/kyc/core.js +14 -1
- package/dist/kyc/core.js.map +1 -1
- package/dist/kyc/core.mjs +14 -1
- package/dist/kyc/core.mjs.map +1 -1
- package/dist/kyc/index.d.mts +1 -1
- package/dist/kyc/index.d.ts +1 -1
- package/dist/kyc/index.js +14 -1
- package/dist/kyc/index.js.map +1 -1
- package/dist/kyc/index.mjs +14 -1
- package/dist/kyc/index.mjs.map +1 -1
- package/dist/react.d.mts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +1 -1
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +1 -1
- package/dist/react.mjs.map +1 -1
- package/dist/risk-profile/index.d.mts +1 -1
- package/dist/risk-profile/index.d.ts +1 -1
- package/dist/risk-profile/index.js +14 -1
- package/dist/risk-profile/index.js.map +1 -1
- package/dist/risk-profile/index.mjs +14 -1
- package/dist/risk-profile/index.mjs.map +1 -1
- package/dist/scores/index.d.mts +1 -1
- package/dist/scores/index.d.ts +1 -1
- package/dist/scores/index.js +14 -1
- package/dist/scores/index.js.map +1 -1
- package/dist/scores/index.mjs +14 -1
- package/dist/scores/index.mjs.map +1 -1
- package/dist/tax/index.d.mts +256 -0
- package/dist/tax/index.d.ts +256 -0
- package/dist/tax/index.js +652 -0
- package/dist/tax/index.js.map +1 -0
- package/dist/tax/index.mjs +650 -0
- package/dist/tax/index.mjs.map +1 -0
- package/package.json +1 -1
|
@@ -222,7 +222,7 @@ function createConsoleLogger() {
|
|
|
222
222
|
}
|
|
223
223
|
|
|
224
224
|
// src/core/version.ts
|
|
225
|
-
var SDK_VERSION = "1.
|
|
225
|
+
var SDK_VERSION = "1.6.1";
|
|
226
226
|
|
|
227
227
|
// src/shared/browser-utils.ts
|
|
228
228
|
function generateUUID() {
|
|
@@ -396,6 +396,19 @@ var BaseClient = class {
|
|
|
396
396
|
if (this.rateLimitTracker) {
|
|
397
397
|
this.rateLimitTracker.updateFromHeaders(response.headers);
|
|
398
398
|
}
|
|
399
|
+
if (requestOptions?.responseType === "arraybuffer") {
|
|
400
|
+
if (!response.ok) {
|
|
401
|
+
let errData = {};
|
|
402
|
+
try {
|
|
403
|
+
errData = await response.json();
|
|
404
|
+
} catch {
|
|
405
|
+
}
|
|
406
|
+
this.handleErrorResponse(response.status, errData, requestId);
|
|
407
|
+
}
|
|
408
|
+
this.circuitBreaker?.onSuccess();
|
|
409
|
+
const buffer = await response.arrayBuffer();
|
|
410
|
+
return buffer;
|
|
411
|
+
}
|
|
399
412
|
let data;
|
|
400
413
|
try {
|
|
401
414
|
data = await response.json();
|
|
@@ -1438,17 +1451,34 @@ var ComplianceClient = class {
|
|
|
1438
1451
|
const startTime = Date.now();
|
|
1439
1452
|
this.validateRegistrationRequest(request);
|
|
1440
1453
|
let geoVerification = null;
|
|
1454
|
+
let cipherTextResult;
|
|
1441
1455
|
try {
|
|
1442
1456
|
if (this.config.debug) {
|
|
1443
1457
|
this.logger.debug("Starting registration verification", { customerId: request.customerId });
|
|
1444
1458
|
}
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
}
|
|
1451
|
-
|
|
1459
|
+
const customerData = request.cipherText ? {
|
|
1460
|
+
full_name: request.fullName,
|
|
1461
|
+
email: request.emailAddress,
|
|
1462
|
+
phone: request.phoneNumber,
|
|
1463
|
+
date_of_birth: request.dateOfBirth
|
|
1464
|
+
} : void 0;
|
|
1465
|
+
[cipherTextResult, geoVerification] = await Promise.all([
|
|
1466
|
+
this.executeCipherTextValidation(
|
|
1467
|
+
request.cipherText,
|
|
1468
|
+
request.customerId,
|
|
1469
|
+
"registration",
|
|
1470
|
+
request.ipAddress,
|
|
1471
|
+
customerData,
|
|
1472
|
+
requestOptions
|
|
1473
|
+
),
|
|
1474
|
+
this.geoClient.verifyIP({
|
|
1475
|
+
ip_address: request.ipAddress,
|
|
1476
|
+
user_id: request.customerId,
|
|
1477
|
+
event_type: "registration",
|
|
1478
|
+
device_fingerprint: request.deviceFingerprint
|
|
1479
|
+
}, requestOptions)
|
|
1480
|
+
]);
|
|
1481
|
+
const blockReasons = this.evaluateRegistrationBlock(geoVerification, cipherTextResult);
|
|
1452
1482
|
if (blockReasons.length > 0) {
|
|
1453
1483
|
if (this.config.debug) {
|
|
1454
1484
|
this.logger.debug("Registration blocked at geo stage", { blockReasons });
|
|
@@ -1460,7 +1490,8 @@ var ComplianceClient = class {
|
|
|
1460
1490
|
requiresKYC: false,
|
|
1461
1491
|
requiresEDD: false,
|
|
1462
1492
|
blockReasons,
|
|
1463
|
-
processingTime: Date.now() - startTime
|
|
1493
|
+
processingTime: Date.now() - startTime,
|
|
1494
|
+
cipherTextValidation: cipherTextResult
|
|
1464
1495
|
};
|
|
1465
1496
|
}
|
|
1466
1497
|
const profile = await this.riskClient.createProfile({
|
|
@@ -1495,7 +1526,8 @@ var ComplianceClient = class {
|
|
|
1495
1526
|
requiresKYC,
|
|
1496
1527
|
requiresEDD,
|
|
1497
1528
|
blockReasons: [],
|
|
1498
|
-
processingTime: Date.now() - startTime
|
|
1529
|
+
processingTime: Date.now() - startTime,
|
|
1530
|
+
cipherTextValidation: cipherTextResult
|
|
1499
1531
|
};
|
|
1500
1532
|
} catch (error) {
|
|
1501
1533
|
if (this.config.debug) {
|
|
@@ -1523,7 +1555,7 @@ var ComplianceClient = class {
|
|
|
1523
1555
|
* @param geoVerification - Geolocation verification result
|
|
1524
1556
|
* @returns Array of block reasons (empty if allowed)
|
|
1525
1557
|
*/
|
|
1526
|
-
evaluateRegistrationBlock(geoVerification) {
|
|
1558
|
+
evaluateRegistrationBlock(geoVerification, cipherTextResult) {
|
|
1527
1559
|
const blockReasons = [];
|
|
1528
1560
|
if (geoVerification.is_blocked) {
|
|
1529
1561
|
blockReasons.push(...geoVerification.risk_reasons);
|
|
@@ -1557,6 +1589,20 @@ var ComplianceClient = class {
|
|
|
1557
1589
|
blockReasons.push("critical_risk_level");
|
|
1558
1590
|
}
|
|
1559
1591
|
}
|
|
1592
|
+
if (cipherTextResult) {
|
|
1593
|
+
if (!cipherTextResult.valid) {
|
|
1594
|
+
blockReasons.push("ciphertext_validation_failed");
|
|
1595
|
+
}
|
|
1596
|
+
if (cipherTextResult.risk?.is_blocked) {
|
|
1597
|
+
blockReasons.push(...cipherTextResult.risk.block_reasons || []);
|
|
1598
|
+
}
|
|
1599
|
+
if (cipherTextResult.risk?.location_mismatch) {
|
|
1600
|
+
blockReasons.push("gps_ip_location_mismatch");
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
if (geoVerification.gps_required && !cipherTextResult) {
|
|
1604
|
+
blockReasons.push("gps_verification_required");
|
|
1605
|
+
}
|
|
1560
1606
|
return [...new Set(blockReasons)];
|
|
1561
1607
|
}
|
|
1562
1608
|
/**
|
|
@@ -1687,7 +1733,15 @@ var ComplianceClient = class {
|
|
|
1687
1733
|
if (this.config.debug) {
|
|
1688
1734
|
this.logger.debug("Starting login verification", { customerId: request.customerId });
|
|
1689
1735
|
}
|
|
1690
|
-
const [geoVerification, profileResult] = await Promise.all([
|
|
1736
|
+
const [cipherTextResult, geoVerification, profileResult] = await Promise.all([
|
|
1737
|
+
this.executeCipherTextValidation(
|
|
1738
|
+
request.cipherText,
|
|
1739
|
+
request.customerId,
|
|
1740
|
+
"login",
|
|
1741
|
+
request.ipAddress,
|
|
1742
|
+
void 0,
|
|
1743
|
+
requestOptions
|
|
1744
|
+
),
|
|
1691
1745
|
this.geoClient.verifyIP({
|
|
1692
1746
|
ip_address: request.ipAddress,
|
|
1693
1747
|
user_id: request.customerId,
|
|
@@ -1696,10 +1750,23 @@ var ComplianceClient = class {
|
|
|
1696
1750
|
}, requestOptions),
|
|
1697
1751
|
this.riskClient.getProfile(request.customerId, requestOptions).catch(() => null)
|
|
1698
1752
|
]);
|
|
1753
|
+
const loginBlockReasons = this.getBlockReasons(geoVerification, profileResult, cipherTextResult);
|
|
1754
|
+
const isBlocked = !geoVerification.is_compliant || geoVerification.is_blocked || !!cipherTextResult?.risk?.is_blocked || cipherTextResult?.valid === false || geoVerification.gps_required && !cipherTextResult;
|
|
1755
|
+
if (isBlocked && !profileResult) {
|
|
1756
|
+
return {
|
|
1757
|
+
allowed: false,
|
|
1758
|
+
geolocation: geoVerification,
|
|
1759
|
+
profile: null,
|
|
1760
|
+
requiresStepUp: false,
|
|
1761
|
+
blockReasons: loginBlockReasons,
|
|
1762
|
+
processingTime: Date.now() - startTime,
|
|
1763
|
+
cipherTextValidation: cipherTextResult
|
|
1764
|
+
};
|
|
1765
|
+
}
|
|
1699
1766
|
let profile;
|
|
1700
1767
|
if (profileResult) {
|
|
1701
1768
|
profile = profileResult;
|
|
1702
|
-
if (this.shouldUpdateProfile(profile, geoVerification.location.city)) {
|
|
1769
|
+
if (!isBlocked && this.shouldUpdateProfile(profile, geoVerification.location.city)) {
|
|
1703
1770
|
profile = await this.riskClient.updateProfile(profile.id, {
|
|
1704
1771
|
last_recorded_activity: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1705
1772
|
location: `${geoVerification.location.city}, ${geoVerification.location.country}`,
|
|
@@ -1712,15 +1779,15 @@ var ComplianceClient = class {
|
|
|
1712
1779
|
}
|
|
1713
1780
|
profile = await this.createProfileFromGeo(request.customerId, geoVerification);
|
|
1714
1781
|
}
|
|
1715
|
-
const
|
|
1716
|
-
const requiresStepUp = geoVerification.risk_level === "high" || geoVerification.risk_level === "critical";
|
|
1782
|
+
const requiresStepUp = geoVerification.risk_level === "high" || geoVerification.risk_level === "critical" || cipherTextResult?.risk?.location_mismatch === true;
|
|
1717
1783
|
return {
|
|
1718
|
-
allowed:
|
|
1784
|
+
allowed: !isBlocked && profile.customer_status !== "suspended",
|
|
1719
1785
|
geolocation: geoVerification,
|
|
1720
1786
|
profile,
|
|
1721
1787
|
requiresStepUp,
|
|
1722
|
-
blockReasons: this.getBlockReasons(geoVerification, profile),
|
|
1723
|
-
processingTime: Date.now() - startTime
|
|
1788
|
+
blockReasons: isBlocked || profile.customer_status === "suspended" ? this.getBlockReasons(geoVerification, profile, cipherTextResult) : [],
|
|
1789
|
+
processingTime: Date.now() - startTime,
|
|
1790
|
+
cipherTextValidation: cipherTextResult
|
|
1724
1791
|
};
|
|
1725
1792
|
} catch (error) {
|
|
1726
1793
|
throw new ComplianceError("Login verification failed", error instanceof Error ? error.message : void 0);
|
|
@@ -1767,27 +1834,58 @@ var ComplianceClient = class {
|
|
|
1767
1834
|
currency: request.currency
|
|
1768
1835
|
});
|
|
1769
1836
|
}
|
|
1770
|
-
const [geoVerification,
|
|
1837
|
+
const [cipherTextResult, geoVerification, profileResult] = await Promise.all([
|
|
1838
|
+
this.executeCipherTextValidation(
|
|
1839
|
+
request.cipherText,
|
|
1840
|
+
request.customerId,
|
|
1841
|
+
"transaction",
|
|
1842
|
+
request.ipAddress,
|
|
1843
|
+
void 0,
|
|
1844
|
+
requestOptions
|
|
1845
|
+
),
|
|
1771
1846
|
this.geoClient.verifyIP({
|
|
1772
1847
|
ip_address: request.ipAddress,
|
|
1773
1848
|
user_id: request.customerId,
|
|
1774
1849
|
event_type: "transaction",
|
|
1775
1850
|
device_fingerprint: request.deviceFingerprint
|
|
1776
1851
|
}, requestOptions),
|
|
1777
|
-
this.riskClient.getProfile(request.customerId, requestOptions)
|
|
1852
|
+
this.riskClient.getProfile(request.customerId, requestOptions).catch(() => null)
|
|
1778
1853
|
]);
|
|
1854
|
+
const geoBlocked = !geoVerification.is_compliant || geoVerification.is_blocked || !!cipherTextResult?.risk?.is_blocked || cipherTextResult?.valid === false || geoVerification.gps_required && !cipherTextResult;
|
|
1855
|
+
if (geoBlocked && !profileResult) {
|
|
1856
|
+
return {
|
|
1857
|
+
allowed: false,
|
|
1858
|
+
geolocation: geoVerification,
|
|
1859
|
+
profile: null,
|
|
1860
|
+
transactionRisk: { score: 0, level: "low", factors: [], allowed: false, requiresManualReview: false },
|
|
1861
|
+
requiresApproval: false,
|
|
1862
|
+
blockReasons: this.getTransactionBlockReasons(
|
|
1863
|
+
geoVerification,
|
|
1864
|
+
{ score: 0, level: "low", factors: [], allowed: false, requiresManualReview: false },
|
|
1865
|
+
true,
|
|
1866
|
+
cipherTextResult
|
|
1867
|
+
),
|
|
1868
|
+
processingTime: Date.now() - startTime,
|
|
1869
|
+
cipherTextValidation: cipherTextResult
|
|
1870
|
+
};
|
|
1871
|
+
}
|
|
1872
|
+
if (!profileResult) {
|
|
1873
|
+
throw new ComplianceError("Customer profile not found", request.customerId);
|
|
1874
|
+
}
|
|
1875
|
+
const profile = profileResult;
|
|
1779
1876
|
const transactionRisk = this.calculateTransactionRisk(
|
|
1780
1877
|
request.amount,
|
|
1781
1878
|
request.currency,
|
|
1782
1879
|
geoVerification,
|
|
1783
|
-
profile
|
|
1880
|
+
profile,
|
|
1881
|
+
cipherTextResult
|
|
1784
1882
|
);
|
|
1785
1883
|
const jurisdictionAllowed = this.checkJurisdictionLimits(
|
|
1786
1884
|
request.amount,
|
|
1787
1885
|
request.currency,
|
|
1788
1886
|
geoVerification.jurisdiction
|
|
1789
1887
|
);
|
|
1790
|
-
const isAllowed =
|
|
1888
|
+
const isAllowed = !geoBlocked && jurisdictionAllowed && transactionRisk.allowed && profile.customer_status !== "suspended";
|
|
1791
1889
|
return {
|
|
1792
1890
|
allowed: isAllowed,
|
|
1793
1891
|
geolocation: geoVerification,
|
|
@@ -1797,9 +1895,11 @@ var ComplianceClient = class {
|
|
|
1797
1895
|
blockReasons: this.getTransactionBlockReasons(
|
|
1798
1896
|
geoVerification,
|
|
1799
1897
|
transactionRisk,
|
|
1800
|
-
jurisdictionAllowed
|
|
1898
|
+
jurisdictionAllowed,
|
|
1899
|
+
cipherTextResult
|
|
1801
1900
|
),
|
|
1802
|
-
processingTime: Date.now() - startTime
|
|
1901
|
+
processingTime: Date.now() - startTime,
|
|
1902
|
+
cipherTextValidation: cipherTextResult
|
|
1803
1903
|
};
|
|
1804
1904
|
} catch (error) {
|
|
1805
1905
|
throw new ComplianceError("Transaction verification failed", error instanceof Error ? error.message : void 0);
|
|
@@ -1814,12 +1914,22 @@ var ComplianceClient = class {
|
|
|
1814
1914
|
async verifyEvent(request, requestOptions) {
|
|
1815
1915
|
const startTime = Date.now();
|
|
1816
1916
|
this.validateEventRequest(request);
|
|
1817
|
-
const geoVerification = await
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1917
|
+
const [cipherTextResult, geoVerification] = await Promise.all([
|
|
1918
|
+
this.executeCipherTextValidation(
|
|
1919
|
+
request.cipherText,
|
|
1920
|
+
request.customerId,
|
|
1921
|
+
request.eventType,
|
|
1922
|
+
request.ipAddress,
|
|
1923
|
+
void 0,
|
|
1924
|
+
requestOptions
|
|
1925
|
+
),
|
|
1926
|
+
this.geoClient.verifyIP({
|
|
1927
|
+
ip_address: request.ipAddress,
|
|
1928
|
+
user_id: request.customerId,
|
|
1929
|
+
event_type: request.eventType,
|
|
1930
|
+
device_fingerprint: request.deviceFingerprint
|
|
1931
|
+
}, requestOptions)
|
|
1932
|
+
]);
|
|
1823
1933
|
if (this.config.autoCreateProfiles) {
|
|
1824
1934
|
try {
|
|
1825
1935
|
const profile = await this.riskClient.getProfile(request.customerId, requestOptions);
|
|
@@ -1832,11 +1942,26 @@ var ComplianceClient = class {
|
|
|
1832
1942
|
}
|
|
1833
1943
|
}
|
|
1834
1944
|
}
|
|
1945
|
+
const cipherTextBlocked = cipherTextResult ? !cipherTextResult.valid || cipherTextResult.risk?.is_blocked === true : false;
|
|
1946
|
+
const blockReasons = [...geoVerification.risk_reasons];
|
|
1947
|
+
if (cipherTextResult) {
|
|
1948
|
+
if (!cipherTextResult.valid) {
|
|
1949
|
+
blockReasons.push("ciphertext_validation_failed");
|
|
1950
|
+
}
|
|
1951
|
+
if (cipherTextResult.risk?.is_blocked) {
|
|
1952
|
+
blockReasons.push(...cipherTextResult.risk.block_reasons || []);
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1955
|
+
const gpsBlocked = geoVerification.gps_required && !cipherTextResult;
|
|
1956
|
+
if (gpsBlocked) {
|
|
1957
|
+
blockReasons.push("gps_verification_required");
|
|
1958
|
+
}
|
|
1835
1959
|
return {
|
|
1836
|
-
allowed: geoVerification.is_compliant && !geoVerification.is_blocked,
|
|
1960
|
+
allowed: geoVerification.is_compliant && !geoVerification.is_blocked && !cipherTextBlocked && !gpsBlocked,
|
|
1837
1961
|
geolocation: geoVerification,
|
|
1838
|
-
blockReasons:
|
|
1839
|
-
processingTime: Date.now() - startTime
|
|
1962
|
+
blockReasons: [...new Set(blockReasons)],
|
|
1963
|
+
processingTime: Date.now() - startTime,
|
|
1964
|
+
cipherTextValidation: cipherTextResult
|
|
1840
1965
|
};
|
|
1841
1966
|
}
|
|
1842
1967
|
// ============================================================================
|
|
@@ -1865,7 +1990,29 @@ var ComplianceClient = class {
|
|
|
1865
1990
|
kyc_status: "pending"
|
|
1866
1991
|
});
|
|
1867
1992
|
}
|
|
1868
|
-
|
|
1993
|
+
/**
|
|
1994
|
+
* Execute cipherText validation with graceful degradation.
|
|
1995
|
+
* Returns undefined if cipherText is not provided or validation fails.
|
|
1996
|
+
*/
|
|
1997
|
+
async executeCipherTextValidation(cipherText, userId, eventType, ipAddress, customerData, requestOptions) {
|
|
1998
|
+
if (!cipherText) return void 0;
|
|
1999
|
+
try {
|
|
2000
|
+
return await this.geoClient.validateCipherText(
|
|
2001
|
+
cipherText,
|
|
2002
|
+
userId,
|
|
2003
|
+
eventType,
|
|
2004
|
+
ipAddress,
|
|
2005
|
+
customerData,
|
|
2006
|
+
requestOptions
|
|
2007
|
+
);
|
|
2008
|
+
} catch (err) {
|
|
2009
|
+
this.logger.warn("CipherText validation failed, proceeding with IP-only", {
|
|
2010
|
+
error: err instanceof Error ? err.message : "Unknown error"
|
|
2011
|
+
});
|
|
2012
|
+
return void 0;
|
|
2013
|
+
}
|
|
2014
|
+
}
|
|
2015
|
+
calculateTransactionRisk(amount, currency, geoVerification, profile, cipherTextResult) {
|
|
1869
2016
|
if (!this._currencyRatesCustomized && !this._currencyRatesWarned) {
|
|
1870
2017
|
this._currencyRatesWarned = true;
|
|
1871
2018
|
this.logger.warn(
|
|
@@ -1898,6 +2045,15 @@ var ComplianceClient = class {
|
|
|
1898
2045
|
riskScore += 50;
|
|
1899
2046
|
factors.push("account_suspended");
|
|
1900
2047
|
}
|
|
2048
|
+
if (cipherTextResult) {
|
|
2049
|
+
if (cipherTextResult.risk?.location_mismatch) {
|
|
2050
|
+
riskScore += 20;
|
|
2051
|
+
factors.push("gps_ip_location_mismatch");
|
|
2052
|
+
}
|
|
2053
|
+
if (cipherTextResult.risk?.score) {
|
|
2054
|
+
riskScore += cipherTextResult.risk.score * 0.2;
|
|
2055
|
+
}
|
|
2056
|
+
}
|
|
1901
2057
|
return {
|
|
1902
2058
|
score: Math.min(riskScore, 100),
|
|
1903
2059
|
level: this.getRiskLevel(riskScore),
|
|
@@ -1923,20 +2079,33 @@ var ComplianceClient = class {
|
|
|
1923
2079
|
if (score >= 40) return "medium";
|
|
1924
2080
|
return "low";
|
|
1925
2081
|
}
|
|
1926
|
-
getBlockReasons(geoVerification, profile) {
|
|
2082
|
+
getBlockReasons(geoVerification, profile, cipherTextResult) {
|
|
1927
2083
|
const reasons = [];
|
|
1928
2084
|
if (geoVerification.is_blocked) {
|
|
1929
2085
|
reasons.push(...geoVerification.risk_reasons);
|
|
1930
2086
|
}
|
|
1931
|
-
if (profile
|
|
1932
|
-
|
|
2087
|
+
if (profile) {
|
|
2088
|
+
if (profile.customer_status === "suspended") {
|
|
2089
|
+
reasons.push("account_suspended");
|
|
2090
|
+
}
|
|
2091
|
+
if (profile.has_sanctions) {
|
|
2092
|
+
reasons.push("sanctions_match");
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
if (cipherTextResult) {
|
|
2096
|
+
if (!cipherTextResult.valid) {
|
|
2097
|
+
reasons.push("ciphertext_validation_failed");
|
|
2098
|
+
}
|
|
2099
|
+
if (cipherTextResult.risk?.is_blocked) {
|
|
2100
|
+
reasons.push(...cipherTextResult.risk.block_reasons || []);
|
|
2101
|
+
}
|
|
1933
2102
|
}
|
|
1934
|
-
if (
|
|
1935
|
-
reasons.push("
|
|
2103
|
+
if (geoVerification.gps_required && !cipherTextResult) {
|
|
2104
|
+
reasons.push("gps_verification_required");
|
|
1936
2105
|
}
|
|
1937
|
-
return reasons;
|
|
2106
|
+
return [...new Set(reasons)];
|
|
1938
2107
|
}
|
|
1939
|
-
getTransactionBlockReasons(geoVerification, transactionRisk, jurisdictionAllowed) {
|
|
2108
|
+
getTransactionBlockReasons(geoVerification, transactionRisk, jurisdictionAllowed, cipherTextResult) {
|
|
1940
2109
|
const reasons = [];
|
|
1941
2110
|
if (!geoVerification.is_compliant) {
|
|
1942
2111
|
reasons.push("non_compliant_jurisdiction");
|
|
@@ -1947,7 +2116,18 @@ var ComplianceClient = class {
|
|
|
1947
2116
|
if (!transactionRisk.allowed) {
|
|
1948
2117
|
reasons.push(...transactionRisk.factors);
|
|
1949
2118
|
}
|
|
1950
|
-
|
|
2119
|
+
if (cipherTextResult) {
|
|
2120
|
+
if (!cipherTextResult.valid) {
|
|
2121
|
+
reasons.push("ciphertext_validation_failed");
|
|
2122
|
+
}
|
|
2123
|
+
if (cipherTextResult.risk?.is_blocked) {
|
|
2124
|
+
reasons.push(...cipherTextResult.risk.block_reasons || []);
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
2127
|
+
if (geoVerification.gps_required && !cipherTextResult) {
|
|
2128
|
+
reasons.push("gps_verification_required");
|
|
2129
|
+
}
|
|
2130
|
+
return [...new Set(reasons)];
|
|
1951
2131
|
}
|
|
1952
2132
|
// ============================================================================
|
|
1953
2133
|
// Location Request Methods
|