Skip to content

Replace @randyd45/curp-validation with validate-curp - #296

Merged
ricardobcl merged 1 commit into
masterfrom
bugfix/restore-curp-check-digit-validation
Sep 7, 2026
Merged

ricardobcl merged 1 commit into
masterfrom
bugfix/restore-curp-check-digit-validation

Conversation

@ricardobcl

Copy link
Copy Markdown
Contributor

Description

v11.0.0 replaced the GPL-licensed curp lib with @randyd45/curp-validation (#287), but the two are not equivalent: curp.validar() validated the CURP check digit, while @randyd45/curp-validation's isFormatValid() only tests the format regex — the 18th character is matched by (\d) but never verified. Both libraries use the same regex, so the swap silently made the assert strictly more permissive.

Verified empirically — same 17-character prefix, all ten possible check digits:

CURP curp@1.2.3 @randyd45/curp-validation@1.0.4
SABC560626MDFLRN01 (correct digit) ✅ ✅
SABC560626MDFLRN00, 02…09 ❌ ✅

9 of 10 previously-rejected values pass v11. The check digit is a weighted mod-10 sum over the 17 preceding characters — it is what catches single-character typos and transpositions anywhere in the CURP.

This PR replaces @randyd45/curp-validation with validate-curp (MIT, same author as the validate-rfc lib already backing the RfcNumber assert), mirroring the RfcNumber assert one-to-one. validate-curp restores check-digit validation — its algorithm is identical to the original curp lib's (same 37-character dictionary, weights 18 - i, mod 10) — and additionally validates the state code (including NE) and RENAPO's forbidden-word list (identical to curp's 81-word malasPalabras list).

Behavioral notes:

  • Like validate-rfc, validate-curp normalizes input before validating (trim, uppercase, strip non-alphanumerics), so e.g. lowercase CURPs are now accepted — consistent with how RfcNumber behaves today.
  • The forbidden-word check is stricter than the original curp.validar(), which never checked it (only generar() substituted forbidden words). Genuine RENAPO-issued CURPs never carry those prefixes.

Also adds a check-digit negative test — the test that would have caught this in #287.

Related issues

Follow-up to #287. Affects uphold/backend#18451.

Impacted areas

  • CurpNumber assert.

Steps to reproduce or test

Development

yarn test

523/523 passing, including the new check-digit case.

QA

N/A

Checklist

  • Add label Breaking Change if it applies.
  • Commits are atomic and logically separated.
  • Performance implications have been considered.
  • Security implications have been considered.
  • The new and updated code has good coverage.
  • API documentation, if required, has been created or updated.
  • New dependencies have been added to package.json.
  • The README file, if required, has been updated.
  • Architectural diagram, if required, has been updated.

Deploy notes

Peer dependency change (@randyd45/curp-validation → validate-curp), so the next release should be a major (v12.0.0). Consumers must swap the optional peer dependency when upgrading.

@ricardobcl ricardobcl added the bug Something isn't working label Aug 31, 2026
@ricardobcl ricardobcl self-assigned this Aug 31, 2026
The curp lib validated the CURP check digit, but its replacement
@randyd45/curp-validation only checks the format regex, so 9 out of 10
possible check digits on any structurally-valid CURP were accepted.

validate-curp (MIT, same author as validate-rfc) restores check-digit
validation and additionally validates the state code and RENAPO's
forbidden-word list, matching the original curp lib's behavior.
@ricardobcl
ricardobcl force-pushed the bugfix/restore-curp-check-digit-validation branch from e27838d to c83f085 Compare August 31, 2026 15:32
@ricardobcl
ricardobcl marked this pull request as ready for review September 7, 2026 11:08
Copilot AI lite review requested due to automatic review settings September 7, 2026 11:08
@ricardobcl
ricardobcl requested review from a team as code owners September 7, 2026 11:08
@ricardobcl
ricardobcl merged commit 590db24 into master Sep 7, 2026
5 checks passed
@ricardobcl
ricardobcl deleted the bugfix/restore-curp-check-digit-validation branch September 7, 2026 11:08

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new validate-curp integration should defensively handle a possible null return to avoid runtime TypeError and ensure invalid CURPs consistently raise a Violation.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR restores strict Mexican CURP validation in the CurpNumber assert by switching from a format-only validator to validate-curp, aligning CURP validation behavior with the existing RfcNumber assert (including check-digit verification) and adding a regression test.

Changes:

  • Replace @randyd45/curp-validation with validate-curp across runtime docs/types and dependency declarations.
  • Update CurpNumber assert implementation to use validate-curp.
  • Add a negative test case for invalid CURP check digits.
File summaries
File Description
yarn.lock Removes @randyd45/curp-validation and adds validate-curp lock entry.
test/asserts/curp-number-assert.test.js Adds a regression test for invalid CURP check digit handling.
src/types/index.d.ts Updates the documented peer dependency for curpNumber().
src/asserts/curp-number-assert.js Switches CURP validation logic to validate-curp.
README.md Updates dependency table and link reference to validate-curp.
package.json Replaces old CURP validator with validate-curp in dev/peer/optional peer deps.
Review details
  • Files reviewed: 4/6 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +44 to 46
if (!validateCurp(value).isValid) {
throw new Violation(this, value, { value: 'must_be_a_valid_curp_number' });
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants