@vitalbox-health/auth-sdk
v1.0.6-beta.1
Published
SDK de autenticacion 'Sign in with Vitalbox' — integra OIDC/OAuth2 de Vitalbox en cualquier web o app
Maintainers
Readme
@vitalbox-health/auth-sdk
SDK de autenticacion "Sign in with Vitalbox" — integra OAuth2/OpenID Connect (OIDC) de Vitalbox en cualquier aplicacion web o movil.
Requisitos previos: credenciales de Vitalbox
Para usar este SDK debes haber solicitado a Vitalbox tus credenciales de aplicacion. Sin ellas el SDK no podra autenticar usuarios.
| Credencial | Descripcion | Donde se usa |
|------------|-------------|--------------|
| client_id | Identifica tu aplicacion ante Vitalbox | Frontend (SDK) y backend |
| client_secret | Secreto de tu aplicacion (confidencial) | Solo backend — jamas en el frontend |
| origin | Dominio(s) de tu web, autorizado(s) en tu client | Configurado por Vitalbox en tu aplicacion |
Para obtenerlas, contacta al equipo de Vitalbox indicando el/los dominio(s) de tu web. Sin un
client_idemitido por Vitalbox (y suoriginautorizado), el flujo devolverainvalid_client/origin no autorizado.
Importante — ambiente: el SDK se encuentra actualmente en fase beta y conecta al ambiente de test de Vitalbox. No uses estas URLs en produccion.
Instalacion
Opcion A: CDN (script tag) — para cualquier web
IMPORTANTE: NO uses
async defer— el script inline que inicializa el SDK se ejecutaria antes de que cargue y dariaVitalboxAuth is not defined. Carga el SDK de forma síncrona.
<script src="https://multiplataforma.myvitalbox.com/sdk/vitalbox-auth.min.js"></script>
<button id="vitalbox-btn"></button>
<script>
VitalboxAuth.initialize({
client_id: 'TU_CLIENT_ID', // emitido por Vitalbox
popup_url: 'https://multiplataforma.myvitalbox.com/auth/oidc/popup', // IMPORTANTE: URL absoluta
callback: function (resp) {
console.log('id_token:', resp.credential); // JWT RS256 firmado por Vitalbox
}
});
VitalboxAuth.renderButton(document.getElementById('vitalbox-btn'), {
theme: 'dark', // 'dark' | 'light'
size: 'large' // 'small' | 'medium' | 'large'
});
</script>IMPORTANTE — dominio: si tu web es de un dominio distinto al de Vitalbox, configura SIEMPRE
popup_urlcon la URL absoluta del ambiente de test (https://multiplataforma.myvitalbox.com/auth/oidc/popup). Si lo omites, el popup intentara abrir en TU dominio y fallara.
Opcion B: NPM — para React, Vue, Angular, Svelte, Next.js
npm install @vitalbox-health/auth-sdkimport VitalboxAuth from '@vitalbox-health/auth-sdk';
// o: import { VitalboxAuth } from '@vitalbox-health/auth-sdk';
VitalboxAuth.initialize({
client_id: 'TU_CLIENT_ID', // emitido por Vitalbox
popup_url: 'https://multiplataforma.myvitalbox.com/auth/oidc/popup', // ambiente de test
callback: (resp) => {
console.log('id_token:', resp.credential);
},
});
// Renderizar el boton
VitalboxAuth.renderButton(document.getElementById('vitalbox-btn'), { theme: 'dark' });
// O flujo programatico
const session = await VitalboxAuth.signIn();
console.log(session.profile); // perfil del usuario decodificadoIncluye el "apartado visual": el boton se renderiza automaticamente en el contenedor que le pases a
renderButton()— no necesitas crear tu propio HTML/CSS. Al hacer clic se abre el popup de autenticacion de Vitalbox y el SDK resuelve la sesion. Funciona en cualquier framework: pasa elref/Elementque tu framework te da (ver ejemplos abajo).
Uso visual en cada framework
El SDK es agnostico de framework: renderButton(container) crea y monta el boton en el elemento que le indiques. El clic abre el popup de auth por si solo.
React
import { useEffect, useRef } from 'react';
import VitalboxAuth from '@vitalbox-health/auth-sdk';
function LoginButton() {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
VitalboxAuth.initialize({
client_id: 'TU_CLIENT_ID',
popup_url: 'https://multiplataforma.myvitalbox.com/auth/oidc/popup',
callback: (resp) => console.log('id_token:', resp.credential),
});
VitalboxAuth.renderButton(ref.current!, { theme: 'dark', size: 'large' });
}, []);
return <div ref={ref} />;
}Angular
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import VitalboxAuth from '@vitalbox-health/auth-sdk';
@Component({ selector: 'app-login', template: '<div #btn></div>' })
export class LoginComponent implements OnInit {
@ViewChild('btn', { static: true }) btnRef!: ElementRef;
ngOnInit(): void {
VitalboxAuth.initialize({
client_id: 'TU_CLIENT_ID',
popup_url: 'https://multiplataforma.myvitalbox.com/auth/oidc/popup',
});
VitalboxAuth.renderButton(this.btnRef.nativeElement, { theme: 'dark' });
}
}Vue
<template>
<div ref="btn"></div>
</template>
<script setup>
import { onMounted, ref } from 'vue';
import VitalboxAuth from '@vitalbox-health/auth-sdk';
const btn = ref();
onMounted(() => {
VitalboxAuth.initialize({
client_id: 'TU_CLIENT_ID',
popup_url: 'https://multiplataforma.myvitalbox.com/auth/oidc/popup',
});
VitalboxAuth.renderButton(btn.value, { theme: 'dark' });
});
</script>Estilos del boton (CSS opcional)
Ademas de las opciones de renderButton(), el paquete incluye una hoja de estilos base exportable:
// React / Vite / Angular
import '@vitalbox-health/auth-sdk/vitalbox-auth.css';<!-- HTML -->
<link rel="stylesheet" href="https://.../vitalbox-auth.css">El boton renderizado lleva la clase .vitalbox-btn (mas la clase extra que pases en options.className). Puedes sobreescribir su apariencia desde tu propio CSS.
API
| Metodo | Descripcion |
|--------|-------------|
| initialize(config) | Inicializa el SDK con el client_id y configuracion |
| renderButton(container, opts) | Renderiza el boton "Sign in with Vitalbox" |
| signIn(): Promise<Session> | Abre el popup de auth y resuelve con la sesion |
| abort() | Aborta el flujo en curso (cierra popup y rechaza la promesa) |
| signOut() | Cierra sesion y limpia el almacenamiento |
| getUser(): User \| null | Devuelve el perfil del usuario logueado |
| getCredential(): string \| null | Devuelve el id_token actual |
| getSession(): Session \| null | Devuelve la sesion completa |
| on(event, handler) | Suscribe eventos: auth, auth_cancel, auth_change |
| decodeJwtPayload(token) | Decodifica un JWT (sin verificar firma). Disponible en instancia y como estatico (VitalboxAuth.decodeJwtPayload) |
decodeJwtPayloadesta disponible tanto sobre la instancia (VitalboxAuth.decodeJwtPayload(token)) como como metodo estatico de la clase (VitalboxAuth.decodeJwtPayload(token)), por lo que funciona igual en el CDN y en npm.
signIn() siempre abre un flujo nuevo (no devuelve la sesion cacheada). Para leer el estado de autenticacion usa
getUser()/getCredential()/getSession()o el eventoauth. Si ya hay un flujo en curso,signIn()devuelve la misma promesa pendiente en lugar de abrir un segundo popup.
Configuracion
interface VitalboxAuthConfig {
client_id: string; // obligatorio — emitido por Vitalbox
popup_url?: string; // default '/auth/oidc/popup' (relativo). Para webs terceras usa la URL absoluta del ambiente de test
redirect_uri?: string;
scope?: string; // default 'openid email profile'
nonce?: string | null; // auto-generado y rotado por flujo si se omite
timeoutMs?: number; // timeout del flujo de auth en ms (default: 300000)
storage?: boolean; // default true (sessionStorage)
callback?: (resp: VitalboxCredentialResponse) => void;
autoLogin?: boolean; // default false — abre/redirige a la plataforma ya logueado
autoLoginMode?: 'new_tab' | 'redirect'; // default 'new_tab'
platformUrl?: string; // URL base de la plataforma (default: origin de popup_url)
}popup_url (ambiente de test / beta)
| Ambiente | popup_url (para webs terceras) |
|----------|-------------------------------|
| Test (beta) | https://multiplataforma.myvitalbox.com/auth/oidc/popup |
Cuando Vitalbox libere el ambiente de produccion, se publicaran las URLs correspondientes.
Auto-login / redireccion a la plataforma
Opcionalmente, tras autenticarse el SDK puede entrar al usuario directamente en la plataforma Vitalbox ya logueado, sin pedirle un segundo inicio de sesion. Se controla con tres opciones de configuracion (todas opcionales y retrocompatibles: si no las usas, el SDK se comporta igual que antes).
| Opcion | Tipo | Default | Descripcion |
|--------|------|---------|-------------|
| autoLogin | boolean | false | Si es true, tras una auth exitosa el SDK ademas abre/redirige a la plataforma Vitalbox ya logueado |
| autoLoginMode | 'new_tab' \| 'redirect' | 'new_tab' | Como se entra a la plataforma: pestana nueva o navegando la ventana actual |
| platformUrl | string | origin de popup_url | URL base de la plataforma Vitalbox (sin barra final). Obligatoria cuando el popup no esta en el dominio de Vitalbox |
Ejemplo CDN
<script src="https://multiplataforma.myvitalbox.com/sdk/vitalbox-auth.min.js"></script>
<button id="vitalbox-btn"></button>
<script>
VitalboxAuth.initialize({
client_id: 'TU_CLIENT_ID',
popup_url: 'https://multiplataforma.myvitalbox.com/auth/oidc/popup',
autoLogin: true, // entrar a la plataforma ya logueado
autoLoginMode: 'new_tab', // 'new_tab' (default) | 'redirect'
platformUrl: 'https://multiplataforma.myvitalbox.com',
callback: function (resp) {
console.log('id_token:', resp.credential); // la sesion se entrega igual
}
});
VitalboxAuth.renderButton(document.getElementById('vitalbox-btn'));
</script>Ejemplo npm / TypeScript
import VitalboxAuth from '@vitalbox-health/auth-sdk';
VitalboxAuth.initialize({
client_id: 'TU_CLIENT_ID',
popup_url: 'https://multiplataforma.myvitalbox.com/auth/oidc/popup',
autoLogin: true,
autoLoginMode: 'redirect', // navega la ventana actual a la plataforma
platformUrl: 'https://multiplataforma.myvitalbox.com',
});
const session = await VitalboxAuth.signIn();
console.log(session.profile); // misma sesion de siempreModos de auto-login
| autoLoginMode | Comportamiento |
|-----------------|----------------|
| new_tab (default) | Abre una pestana/ventana nueva en la plataforma Vitalbox ya logueado. Tu web permanece abierta en la pestana original. Usa window.open(url, '_blank', 'noopener,noreferrer'). |
| redirect | Navega la ventana actual hacia la plataforma (window.location.assign(url)). Tu web se descarga y el usuario queda en la plataforma. |
Notas
platformUrles necesario cuando el popup no esta en el dominio de Vitalbox (webs terceras): si no lo configuras, el SDK no puede derivarlo delpopup_urlcuando este es relativo. Si falta, el auto-login se omite y se registra unconsole.warn, pero la autenticacion sigue siendo valida.- El
callbacky la promesa designIn()siguen resolviendose con la misma sesion (credential,access_token,profile,state). El auto-login nunca altera la sesion devuelta ni provoca rechazos. - El auto-login se dispara despues de guardar la sesion y de emitir el evento
auth, y antes de resolver la promesa. - Si el navegador bloquea el popup (o si
autoLoginno aplica porque no hayaccess_token), el SDK lo registra comoconsole.warny el flujo continua con normalidad.
Flujo
- El usuario hace clic en el boton
- Se abre un popup hacia el dominio de Vitalbox (
/auth/oidc/popup) - El usuario se autentica en el popup (o se registra)
- Vitalbox genera un
id_tokenJWT firmado con RS256 - El popup lo envia al sitio de la app via
window.postMessage - El SDK llama al
callbackcon{ credential: id_token }
Seguridad (validaciones del SDK)
El SDK valida cada mensaje postMessage antes de aceptar la sesion:
event.source— el mensaje debe venir EXACTAMENTE del popup que el SDK abrio (ignora iframes/mensajes de otros remitentes).event.origin— debe coincidir con el origin depopup_url.state(anti-CSRF) — se genera y rota por cadasignIn(), se envia en la URL del popup y debe devolverse intacto. Si no coincide, el flujo se rechaza.nonce— se genera y rota por cadasignIn()(nunca se reutiliza entre flujos).credential— un mensajeSUCCESSsin id_token valido se rechaza.- Timeout — si el usuario no completa la auth en
timeoutMs(default 5 min), el flujo se aborta. Tambien puedes llamarabort().
Verificacion del token (backend del cliente)
El id_token debe verificarse en el backend de la app cliente (NUNCA confiar solo en el frontend):
- Obtener la llave publica (ambiente de test):
GET https://multiplataforma.myvitalbox.com/api/auth/oidc/jwks - Verificar la firma RS256 del
id_tokencontra esa llave - Verificar claims:
iss,aud(client_id),exp,nonce
El
client_secretse usa EXCLUSIVAMENTE en tu backend. NUNCA lo coloques en el frontend ni en el SDK: el SDK solo usa elclient_id. Si unclient_secretse filtra en un repo o chat, rotalo inmediatamente desde el panel de OAuth clients.
Personalizacion del boton
El boton es totalmente parametrizable via renderButton(container, options):
VitalboxAuth.renderButton(document.getElementById('vitalbox-btn'), {
// Logo
logoType: 'cube', // 'cube' | 'full' | 'none' (default: cube)
logoMode: 'dark', // 'dark' | 'light' (para logo completo)
logoColor: '#1a85e1', // color del cubo (SVG)
logoSize: 20, // tamano del logo en px
showLogo: true, // mostrar logo
// Colores
backgroundColor: '#0f172a', // color de fondo
textColor: '#ffffff', // color del texto
borderColor: '#1a85e1', // color del borde (opcional)
borderWidth: 1, // ancho del borde en px
// Tamano y forma
size: 'medium', // 'small' | 'medium' | 'large'
borderRadius: 6, // radio de esquinas en %
fontSize: 16, // tamano del texto en px
height: 46, // alto en px (opcional)
width: '100%', // ancho (px o '100%', opcional)
padding: '11px 20px', // padding CSS (opcional)
fontWeight: 500, // peso del texto
// Texto
text: 'Iniciar sesion con Vitalbox'
});Tipos de logo
| logoType | Descripcion |
|------------|-------------|
| cube | Cubo Vitalbox (SVG embebido, color parametrizable via logoColor) |
| full | Logo completo (usa /images/logo/logo-negativo.svg en modo dark, /images/logo/logo.svg en light) |
| none | Sin logo (solo texto) |
Nota: para
logoType: 'full'desde una web tercero, las URLs de los logos son relativas al dominio de Vitalbox. Si el SDK se sirve desde tu propio dominio, configuralogoUrlcon la URL absoluta del logo.
Colores por defecto segun tema
Si no configuras backgroundColor, textColor ni logoColor, el SDK usa los colores del tema:
| Propiedad | Tema oscuro (dark) | Tema claro (light) |
|-----------|---------------------|----------------------|
| backgroundColor | #1e293b | #ffffff |
| textColor | #ffffff | #1f2937 |
| logoColor | #ffffff | #1a85e1 |
Usa el boton Auto en el playground (o simplemente omite la propiedad en el codigo) para restaurar los colores del tema.
Texto vacio
Si pasas text: '', el boton muestra solo el logo centrado (sin texto por defecto).
Presets de tamano
| size | Padding | Font size |
|--------|---------|-----------|
| small | 8px 14px | 14px |
| medium | 11px 20px | 16px |
| large | 14px 26px | 18px |
Los valores explicitos (padding, fontSize, height, width) sobrescriben los presets.
Desarrollo
npm install
npm run build # genera dist/ (ESM + CJS + IIFE + types)
npm run typecheckBuild outputs
| Archivo | Formato | Uso |
|---------|---------|-----|
| dist/vitalbox-auth.min.js | IIFE (CDN) | <script src="..."> → window.VitalboxAuth |
| dist/index.js | ESM | Bundlers modernos (import) |
| dist/index.cjs | CJS | Node.js (require) |
| dist/index.d.ts | Types | Autocompletado TypeScript |
