services/api/src/utils/phone.js

Overview

Este archivo centraliza la normalización, validación y huella criptográfica de teléfonos en el backend. Su foco es el formato E.164, que usa un + inicial y solo dígitos. Según los comentarios del propio código, este módulo reemplaza dos implementaciones paralelas anteriores en auth.validation.js y auth.service.js.

[!IMPORTANT] hashPhoneForRateLimit es determinista y usa SHA-256 sin salt. Su propósito es servir como key de rate limiting por teléfono.

How it works

El módulo sigue una secuencia simple de tratamiento del teléfono:

  • normalizePhoneE164 convierte la entrada a texto.
  • Elimina espacios y recorta extremos.
  • Conserva solo dígitos.
  • Mantiene el + inicial solo si estaba al comienzo.
  • isValidE164Phone verifica la cadena original contra una expresión regular E.164.
  • hashPhoneForRateLimit calcula un hash SHA-256 hexadecimal sobre el teléfono ya normalizado.
const normalized = normalizePhoneE164(inputPhone);

if (isValidE164Phone(normalized)) {
  const rateLimitKey = hashPhoneForRateLimit(normalized);
}

[!NOTE] Un + solo sobrevive si era el primer carácter. Cualquier otro + se trata como ruido de entrada.

Key components

{
    "title": "normalizePhoneE164",
    "content": "Normaliza un valor de entrada a una representaci\u00f3n de tel\u00e9fono basada en d\u00edgitos, preservando solo un '+' inicial si exist\u00eda al comienzo.",
    "type": "function",
    "filePath": "services/api/src/utils/phone.js",
    "badges": [
        "public"
    ]
}
{
    "title": "isValidE164Phone",
    "content": "Comprueba si un valor ya cumple el patr\u00f3n E.164 definido por `E164_PHONE_REGEX` y devuelve un booleano.",
    "type": "function",
    "filePath": "services/api/src/utils/phone.js",
    "badges": [
        "public"
    ]
}
{
    "title": "hashPhoneForRateLimit",
    "content": "Genera un hash SHA-256 hexadecimal determinista para un tel\u00e9fono normalizado. Se usa como key de rate limiting por tel\u00e9fono.",
    "type": "function",
    "filePath": "services/api/src/utils/phone.js",
    "badges": [
        "public"
    ]
}

Data & fields

  • E164_PHONE_REGEX [badge:read-only] RegExp — Valida teléfonos con formato E.164.

    • ^ ancla el inicio de la cadena.
    • \+ exige un + inicial.
    • [1-9] exige un primer dígito distinto de cero.
    • \d{7,14} acepta entre 7 y 14 dígitos adicionales.
    • $ ancla el final de la cadena.

    El formato completo exige entre 8 y 15 dígitos después del +.

Behaviors

  • normalizePhoneE164(value) — Devuelve una cadena normalizada. Si la entrada empieza con +, devuelve + seguido de los dígitos. Si no empieza con +, devuelve solo los dígitos.

  • isValidE164Phone(value) — Devuelve true solo si el valor original coincide con E164_PHONE_REGEX.

  • hashPhoneForRateLimit(phone) — Devuelve un digest SHA-256 en hexadecimal. El resultado es determinista para el mismo teléfono normalizado.

[!WARNING] isValidE164Phone no normaliza antes de validar. Si la entrada contiene espacios, guiones u այլ caracteres, fallará aunque luego pueda normalizarse.

  • auth.validation.js — El comentario indica que existía una implementación paralela anterior.
  • auth.service.js — El comentario indica que también contenía una limpieza de teléfono equivalente.
  • auth.routes.js — El hash del teléfono se usa como key de rate limiter, según el comentario del archivo.
  • utils/encryption.js — El comentario lo menciona como referencia de minimización de PII mediante derivePurgedIdentifierDigest.

[!NOTE] Este módulo no introduce rutas HTTP, modelos ni estado persistente. Su responsabilidad está limitada a utilidades de tratamiento de teléfonos.