npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

lib-modal-otp

v0.0.1

Published

Angular library for reusable OTP validation

Readme

Librería: lib-modal-otp — Documentación

Documentación detallada para usar y configurar @iq-team/lib-modal-otp en tu aplicación Angular.

1. Introducción

@iq-team/lib-modal-otp es una librería standalone (Angular 18+) que expone un componente modal para enviar y verificar códigos OTP por correo o SMS. Está pensada para integrarse fácilmente en apps que usan MatDialog de Angular Material y un servicio HTTP (interno) que maneja las llamadas al backend.

Este documento explica cómo configurarla, cómo invocar el modal, los datos que acepta y las respuestas que retorna.


2. Instalación (nota rápida)

  • Desde artefactos de azure (TeamIQ):
npm install -g vsts-npm-auth

Verificar dentro del proyecto raíz si se tiene el archivo :

.npmrc

Si no lo tiene se debe crear con el nombre dicho .npmrc y dentro de archivo dejar esto:

#Para trabajar la libreria en proyectos externos o hacer instalacion de un libreria interna de IQTeam
@iq-team:registry=https://pkgs.dev.azure.com/iq-outsourcing/_packaging/TeamIQ/npm/registry/
//pkgs.dev.azure.com/iq-outsourcing/_packaging/TeamIQ/npm/registry/:always-auth=true
legacy-peer-deps=true

luego se debe ejecutar el comando en la terminar para autenticarse con las credenciales (estas son el correo y contraseña de iq)

Nota: aparecerá una ventana para iniciar sesión

vsts-npm-auth -config .npmrc

O si tienes el script configurado:

npm run vsts-auth

Esto generará las credenciales necesarias para acceder al feed privado de Azure Artifacts. para validar que toda haya sido correcto, se vuelve ejecutar el comando : vsts-npm-auth -config .npmrc y debe aparecer algo así.

  • Instalar libreria
npm install @iq-team/lib-modal-otp
  • Luego importa la librería desde tu proyecto donde uses MatDialog.

Importante: la librería es standalone y expone el componente LibModalOtpComponent y el servicio LibModalOtpService.


3. Requisitos / peerDependencies

  • Angular >= 18.2.0
  • @angular/common, @angular/core (compatibles con tu app)
  • @angular/material si vas a usar MatDialog (se usa MatDialogModule y algunos mat-icon)

En package.json de la librería aparece peerDependencies apuntando a Angular 18.2+. Asegúrate de tener versiones compatibles.


4. Proveedor global (OTP_CONFIG)

La librería exporta un InjectionToken llamado OTP_CONFIG para configuración global.

Interfaz:

export interface OtpConfig {
  apiBaseUrl: string;
  sendEndpoint?: string;   // default '/otp/send'
  verifyEndpoint?: string; // default '/otp/verify'
  defaultMethod?: 'email' | 'sms';
}

Registro en ApplicationConfig (ejemplo):

import { OTP_CONFIG } from '@iq-team/lib-modal-otp';

{ provide: OTP_CONFIG, useValue: {
    apiBaseUrl: environment.API_CLICKNGO,
    defaultMethod: 'email',
    // opcionales:
    // sendEndpoint: 'otp/send',
    // verifyEndpoint: 'otp/verify'
  }
}

Registro en bootstrapApplication - main.ts:

import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { App } from './app/app';
import { provideRouter } from '@angular/router';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { routes } from './app/app.routes';
import { authInterceptor } from './app/services/auth-interceptor';
import { OTP_CONFIG } from '@iq-team/lib-modal-otp';
bootstrapApplication(App, {
  providers: [
    provideRouter(routes),
    provideHttpClient(
      withInterceptors([authInterceptor])
    ),
    {
      provide: OTP_CONFIG, useValue: {
        apiBaseUrl: 'https://localhost:44344/api',
        sendEndpoint: '/otp/process-otp', verifyEndpoint: '/otp/validate', defaultMethod: 'email'
      }
    },
  ]
}).catch(err => console.error(err));

Si no registras OTP_CONFIG, la librería puede tener comportamientos indeseados o requerir que se pase todo por data al abrir el modal.


5. Uso — Abrir el modal desde un componente

La librería expone un componente standalone listo para abrir con MatDialog.

Ejemplo mínimo para abrir el modal:

openOtp() {
const dialogRef = this.dialog.open(LibModalOtpComponent, {
width: '400px',
disableClose: true,
data: {
sendEndpoint: 'otp/process-otp', // opcional, si quieres sobreescribir
defaultMethod: 'email', 
email: '[email protected]', // si envías un email ya registrado, el input no se mostrará
phone: '3101234567', // igual para teléfono
texts: { /* opcional: textos personalizados */ }
}
});
dialogRef.afterClosed().subscribe(result => {
if (result?.success) {
// resultado correcto
console.log('OTP validado', result);
} else {
console.log('Cancelado o fallo');
}
});
}

Notas:

  • Si en data pasas email o phone, el campo correspondiente no se mostrará y se usará ese valor.
  • defaultMethod puede venir desde OTP_CONFIG o desde data.

6. Opciones de data al abrir el modal

data puede contener:

  • email?: string — valor fijo si ya sabes el email del usuario (no se muestra el input)
  • phone?: string — idem para teléfono
  • sendEndpoint?: string — ruta relativa o absoluta para enviar OTP (si quieres sobreescribir)
  • verifyEndpoint?: string — ruta para verificar OTP
  • defaultMethod?: 'email'|'sms' — método por defecto
  • texts?: OtpTexts — objeto con textos personalizados

Ejemplo de texts:

texts: {
  introMessage: 'Texto introductorio',
  resendLabel: 'Reenviar',
  sendButton: 'Enviar código',
  verifyButton: 'Verificar',
  closeButton: 'Cerrar',
  sendingState: 'Enviando...'
}

7. Tipos y modelos esperados (DTOs / Interfaces)

export interface SendOtpDTO {
  recipient: string; // email o teléfono
  channel: NotificationChannelDTO; // Email = 0, Sms = 1
}

export enum NotificationChannelDTO { Email = 0, Sms = 1, Push = 2 }

export interface OtpEntryDTO { key: string; code: string; ttlSeconds: number }

export interface ResponseDTO<T = any> {
  success: boolean;
  message: string;
  statusCode: number;
  data?: T;
  errors?: Record<string, string[]>;
}

Payload enviado por la librería al backend

En handleSendOtp() la librería crea un SendOtpDTO como:

{ "recipient": "[email protected]", "channel": 0 }

Respuesta esperada del backend al enviar OTP

La librería espera un ResponseDTO con data que contenga key (request id) y ttlSeconds (tiempo de validez en segundos). Ejemplo:

{
  "success": true,
  "message": "OK",
  "statusCode": 200,
  "data": { "key": "abc123", "ttlSeconds": 180 }
}

Verificar OTP

Payload que la librería envía al verificar:

{ "key": "abc123", "code": "123456", "ttlSeconds": 0 }

Respuesta esperada: un ResponseDTO con success: true si el código es válido.


8. Comportamiento interno relevante

  • Timer y reenvío: cuando el envío es exitoso la librería arranca un setInterval que decrementa timer cada segundo. Al llegar a 0, isOtpDisabled = true y canResend = true.
  • Formato visible del destinatario: para correo se muestra usu***@dominio, para teléfono se muestra con máscara +57 310 *** 67 (según displayedRecipient).
  • Validaciones en cliente: correo usa regex simple; teléfono acepta solo dígitos (7-10). El código OTP espera longitud 6.
  • Estados de botón: isLoading para mostrar textos de envío/verificación y bloquear acciones.

9. Ejemplos completos de código

A) Registrar OTP_CONFIG en appConfig (Angular standalone providers)

import { OTP_CONFIG } from '@iq-team/lib-modal-otp';

{ provide: OTP_CONFIG, useValue: {
  apiBaseUrl: environment.API_CLICKNGO,
  defaultMethod: 'email'
}}

B) Abrir modal (componente que usa MatDialog)

import { MatDialog } from '@angular/material/dialog';
import { LibModalOtpComponent } from '@iq-team/lib-modal-otp';

constructor(private dialog: MatDialog) {}

openOtp() {
  const dialogRef = this.dialog.open(LibModalOtpComponent, {
    width: '420px',
    data: {
      defaultMethod: 'email',
      sendEndpoint: 'otp/process-otp',
      texts: { sendButton: 'Enviar', resendLabel: 'Volver a enviar' }
    }
  });

  dialogRef.afterClosed().subscribe(result => {
    if (result?.success) {
      // manejar éxito
    } else {
      // manejar cancelación o fallo
    }
  });
}

C) Ejemplo de respuesta desde backend al enviar OTP (sugerido)

{
  "success": true,
  "message": "Código enviado",
  "statusCode": 200,
  "data": { "key": "req_12345", "ttlSeconds": 180 }
}