Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 44 additions & 9 deletions src/lib/providers/weex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ import { PROVIDER_TIMEOUT_MS } from "@/lib/data/content";
import { stripCURPs } from "@/lib/sanitize";
import type { LineResult } from "@/types";

export async function loookupCURPINWeeex(curp: string): Promise<LineResult> {
const validationBody = {
documentType: 1,
searchData: curp,
};
// documentType, as used by weex.mx/consultalineas.html: 1 = CURP, 2 = passport,
// 3 = RFC.
const DOCUMENT_TYPE_CURP = 1;

type WeexResponse = {
obj?: { dnActiveByCurpRfc?: Array<{ msisdn?: string; provider?: string }> };
error?: { code?: number; message?: string; retry?: number };
};

export async function loookupCURPINWeeex(curp: string): Promise<LineResult> {
const validationResponse = await fetch(
"https://app.weex.mx/ServiceLayer/Legislacion?ex=getDnActiveLines",
{
Expand All @@ -16,7 +20,10 @@ export async function loookupCURPINWeeex(curp: string): Promise<LineResult> {
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(validationBody),
body: JSON.stringify({
documentType: DOCUMENT_TYPE_CURP,
searchData: curp,
}),
},
);

Expand All @@ -26,16 +33,44 @@ export async function loookupCURPINWeeex(curp: string): Promise<LineResult> {
validationResponse.statusText,
);

// A WAF block or a rate limit is not a lookup that failed, it's a lookup
// that never ran — the user should be told to check the portal, not that
// Weex is broken.
const blocked =
validationResponse.status === 403 || validationResponse.status === 429;

return {
company: "Weex",
lines: [],
error: "Failed to validate CURP with Weex",
temporaryUnavailable: blocked,
error: blocked ? undefined : "Failed to validate CURP with Weex",
};
}

const validationData = await validationResponse.json();
const validationData = (await validationResponse
.json()
.catch(() => null)) as WeexResponse | null;

// Weex answers 200 with an envelope: { obj, error: { code, message, retry } }.
// Their own portal treats any non-zero error.code as a service failure rather
// than an empty result, and the array comes back empty (or absent) in that
// case. Reading that empty array as "no lines" tells the user nothing is
// registered to their CURP when the lookup never actually happened.
if (
validationData?.error?.code !== undefined &&
validationData.error.code !== 0
) {
console.error(
`[weex] business error ${validationData.error.code}: ${validationData.error.message ?? ""}`,
);
return { company: "Weex", lines: [], temporaryUnavailable: true };
}

// Optional chaining on purpose: an unexpected envelope must not throw and
// take the whole provider down with it.
const found = validationData?.obj?.dnActiveByCurpRfc ?? [];

if (validationData.obj.dnActiveByCurpRfc.length === 0) {
if (found.length === 0) {
return {
company: "Weex",
lines: [],
Expand Down