Skip to main content

Seguridad y orígenes

Solo conexiones Web Chat​

El token del widget es el de una conexión del CRM. El backend (WidgetService) solo atiende tokens de una conexión con channelType web y estado connected; el fallback a tokens de tenant legacy fue eliminado. Cualquier otro token provoca un error y el widget no se monta automáticamente. Ver Conexiones.

Whitelist de dominios​

isOriginAllowed (backend, connection/helpers/origin.helper.ts) compara el Origin de la request (o, en los endpoints HTTP, el Referer si no hay Origin) contra webConfig.allowedDomains:

  • Ambos lados se normalizan a origin (esquema, host y puerto) con new URL.
  • Sin Origin/Referer (por ejemplo curl o llamadas servidor a servidor) se rechaza.
  • La comprobación aplica a los endpoints públicos del widget y al handshake del socket del chat (se lee client.handshake.headers.origin).

Para que el widget funcione en un sitio, ese origin debe estar en allowedDomains de la conexión Web Chat.

Origin del CRM fijo​

El widget siempre habla con el backend escrito en CRM_ORIGIN. No se deriva del script ni puede sobreescribirse desde el sitio: el anfitrión no elige contra qué CRM apunta.

Identidad​

  • Con requiresAuth verdadero, la identidad (externalId, username) la declara el sitio anfitrión desde su sesión. El widget no la verifica criptográficamente: la confianza se apoya en el token y en la whitelist de dominios, por lo que quien controle una página permitida puede declarar cualquier externalId.
  • Con requiresAuth falso, el visitante es anónimo y el id se guarda en localStorage bajo el token.
  • Los datos opcionales (email, phone, fullName) se persisten en el Contact; los ausentes se ignoran.

Aislamiento entre sesiones​

  • Las claves de localStorage incluyen token y externalId, de modo que un cambio de cuenta no hereda badge ni posición.
  • destroyWidget aborta subidas y grabaciones en curso para evitar fugas entre visitantes.
  • El token viaja en la query string (?token=) de las requests HTTP, codificado con encodeURIComponent.

Contenido​

El cuerpo de los mensajes se arma con nodos de texto; appendRichText solo interpreta el marcador **negrita** (que el backend usa en mensajes de sistema) y nunca usa innerHTML. En cambio, si buttonIcon empieza con < se inserta como HTML (innerHTML): debe provenir del sitio anfitrión, nunca de entrada de usuario.