Files
cbsnexora-backend/scripts/mock-dip-lookup-service.js
T
keshav a8ca7dd948
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-5) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (main, build-core) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (main, cucumber) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (progressive-loan, build-progressive-loan) (push) Canceled after 0s
Fineract Docker Builds / build (false, docker-compose-postgresql.yml, postgresql) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-5) (push) Canceled after 0s
Fineract Docker Builds / build (true, docker-compose.yml, mariadb) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 1 of 10) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-5) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-4) (push) Canceled after 0s
Fineract Documentation build / build (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 10 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 2 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 3 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 4 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 5 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 6 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 7 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 8 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 9 of 10) (push) Canceled after 0s
Fineract Liquibase Only mode - PostgreSQL / test (push) Canceled after 0s
Fineract Messaging Smoke Tests / Smoke Test with ActiveMQ (push) Canceled after 0s
Fineract Messaging Smoke Tests / Smoke Test with Kafka (push) Canceled after 0s
feat: implement DIP/MNRL lookups and enhance Sanctions screening workflows
- Implement DIP/MNRL lookup logs table, filtering, and detail review under reports.
- Integrate DIP verification gating on client creation, allowing officers to record PROCEEDED/REJECTED decisions with reasons.
- Upgrade Sanctions verification dialog to support comparing Name, DOB, and Nationality particulars.
- Add Sanctions disposition recording (FALSE_POSITIVE / CONFIRMED_MATCH) awaiting Principal Officer approval.
- Add sanctions-alert-review-dialog for reviewers to assess and escalate/clear flagged names.
- Enforce strict screening reset logic on client name changes, preventing bypass of existing blocks.
- Update routes and shell menu navigation to include DIP/MNRL Lookups and Sanctions Logs.
2026-08-14 10:46:59 +05:30

168 lines
5.4 KiB
JavaScript

/*
* LOCAL TEST DIP/MNRL LOOKUP SERVICE — NOT A REAL DoT ENDPOINT.
*
* This stands in for the Department of Telecommunications Digital Intelligence Platform so the
* client-onboarding flow can be exercised end to end without a live DoT connection. It invents
* its answers. NOTHING HERE IS A REAL DIP OR MNRL CHECK.
*
* Mirrors scripts/mock-sms-gateway.js in intent: an unconfigured external provider gets a local
* stand-in rather than a dangling URL, and every response is stamped so it can never be mistaken
* for a genuine DoT result in the audit trail.
*
* Usage:
* node scripts/mock-dip-lookup-service.js # listens on 8090
* MOCK_DIP_PORT=9100 node scripts/mock-dip-lookup-service.js
*
* Point the backend at it:
* FINERACT_MOBILE_LOOKUP_BASE_URL=http://127.0.0.1:8090
*
* BEFORE PRODUCTION: point FINERACT_MOBILE_LOOKUP_BASE_URL at the real DIP/MNRL provider and do
* not run this. See the banner in application.properties.
*/
'use strict';
const http = require('http');
const { URL } = require('url');
const PORT = Number(process.env.MOCK_DIP_PORT || 8090);
/** Stamped into every response so a mock lookup is identifiable in the stored raw JSON. */
const PROVIDER = 'MOCK_DIP_LOOKUP_TEST_ONLY';
/*
* Fixed verdicts for numbers used in demos and manual testing. Anything not listed here comes
* back CLEAN — the common case, so an ordinary test number does not trip the flagged-number gate.
*
* These overlap deliberately with DEMO_SUSPECTED_NUMBERS in MobileLookupServiceImpl: those are
* short-circuited before the HTTP call ever happens, so they are here only to keep the two lists
* telling the same story if that short-circuit is ever removed.
*/
const SUSPECTED = new Set([
'9827123456', '9827456789', '9826234567',
'9826987654', '9893123456', '9893765432'
]);
const DISCONNECTED = new Set([
'9000000001', '9000000002'
]);
const SUSPECTED_AND_DISCONNECTED = new Set([
'9000000003'
]);
/** Strips a leading country code so 919827123456 and 9827123456 resolve alike. */
function normalise(raw) {
const digits = String(raw || '').replace(/\D/g, '');
if (digits.length > 10 && digits.startsWith('91')) {
return digits.slice(2);
}
return digits;
}
function suspectedDetail() {
return {
dipStatus: 'active',
reason: 'Reported in cyber-fraud complaints (mock data)',
reportedBy: PROVIDER
};
}
function disconnectedDetail() {
return {
disconnectionReason: 'Number revoked and listed on MNRL (mock data)',
operator: 'MOCK TELECOM'
};
}
/*
* The backend parser reads suspectedDetail/disconnectedDetail unconditionally and only guards
* with isJsonNull(), so both keys must always be present — an absent key would NPE there rather
* than surface as a clean parse failure.
*/
function verdictFor(mobileNumber) {
const n = normalise(mobileNumber);
if (SUSPECTED_AND_DISCONNECTED.has(n)) {
return {
status: 'SUSPECTED_AND_DISCONNECTED',
suspected: true,
disconnected: true,
suspectedDetail: suspectedDetail(),
disconnectedDetail: disconnectedDetail(),
message: 'Number is SUSPECTED and DISCONNECTED — found in both DIP and MNRL records'
};
}
if (SUSPECTED.has(n)) {
return {
status: 'SUSPECTED',
suspected: true,
disconnected: false,
suspectedDetail: suspectedDetail(),
disconnectedDetail: null,
message: 'Number is SUSPECTED — found in DIP records'
};
}
if (DISCONNECTED.has(n)) {
return {
status: 'DISCONNECTED',
suspected: false,
disconnected: true,
suspectedDetail: null,
disconnectedDetail: disconnectedDetail(),
message: 'Number is DISCONNECTED — found in MNRL records'
};
}
return {
status: 'CLEAN',
suspected: false,
disconnected: false,
suspectedDetail: null,
disconnectedDetail: null,
message: 'Number is CLEAN — not found in DIP or MNRL records'
};
}
const server = http.createServer((req, res) => {
const url = new URL(req.url, `http://${req.headers.host}`);
if (url.pathname !== '/api/v1/lookup/check') {
res.writeHead(404, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ success: false, message: 'Not found', provider: PROVIDER }));
return;
}
const mobileNumber = url.searchParams.get('mobileNumber');
if (!mobileNumber || !mobileNumber.trim()) {
res.writeHead(400, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ success: false, message: 'mobileNumber is required', provider: PROVIDER }));
return;
}
const verdict = verdictFor(mobileNumber);
const body = {
success: true,
message: verdict.message,
timestamp: new Date().toISOString(),
provider: PROVIDER,
data: {
mobileNumber: mobileNumber.trim(),
status: verdict.status,
suspected: verdict.suspected,
disconnected: verdict.disconnected,
suspectedDetail: verdict.suspectedDetail,
disconnectedDetail: verdict.disconnectedDetail
}
};
console.log(`[${PROVIDER}] ${mobileNumber} -> ${verdict.status}`);
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(body));
});
server.listen(PORT, '127.0.0.1', () => {
console.log(`${PROVIDER} listening on http://127.0.0.1:${PORT}`);
console.log('This is NOT a real DoT DIP/MNRL service. Responses are invented.');
console.log(`Set FINERACT_MOBILE_LOOKUP_BASE_URL=http://127.0.0.1:${PORT}`);
});