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-otpen 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-authVerificar dentro del proyecto raíz si se tiene el archivo :
.npmrcSi 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=trueluego 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 .npmrcO si tienes el script configurado:
npm run vsts-authEsto 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
standaloney expone el componenteLibModalOtpComponenty el servicioLibModalOtpService.
3. Requisitos / peerDependencies
- Angular >= 18.2.0
@angular/common,@angular/core(compatibles con tu app)@angular/materialsi vas a usarMatDialog(se usaMatDialogModuley algunosmat-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 pordataal 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
datapasasemailophone, el campo correspondiente no se mostrará y se usará ese valor. defaultMethodpuede venir desdeOTP_CONFIGo desdedata.
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éfonosendEndpoint?: string— ruta relativa o absoluta para enviar OTP (si quieres sobreescribir)verifyEndpoint?: string— ruta para verificar OTPdefaultMethod?: 'email'|'sms'— método por defectotexts?: 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
setIntervalque decrementatimercada segundo. Al llegar a 0,isOtpDisabled = trueycanResend = true. - Formato visible del destinatario: para correo se muestra
usu***@dominio, para teléfono se muestra con máscara+57 310 *** 67(segúndisplayedRecipient). - 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:
isLoadingpara 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 }
}