Jump to content

Enigma88

Members
  • Content Count

    26
  • Joined

  • Last visited

2 Followers

About Enigma88

  • Rank
    Candidate

Recent Profile Visitors

340 profile views
  1. Cómo mejorar la seguridad y privacidad de Whatsapp Mejorar la seguridad y privacidad de Whatsapp es una cuestión obligada para el uso de la aplicación de mensajería instantánea más popular del mercado. El servicio sigue creciendo en número usuarios y no todos son conscientes de lo que tienen entre manos. Como ocurre con todo servicio de impacto masivo, hace tiempo que los creadores y distribuidores de malware han puesto a Whatsapp en el punto de mira y son múltiples las campañas maliciosas que intentan aprovechar sus centenares de millones de usuarios. Además, los intereses propios de Facebook y el supuesto (dalo por hecho) intercambio de datos que practica desde la compra de la aplicación, son una preocupación para la privacidad de los usuarios. La Comisión Europea impuso a Facebook una multa de 110 millones de euros por mentirle en el marco de la investigación de la adquisición al proporcionar información “incorrecta, inexacta o engañosa”. Recientemente, la Agencia Española de Protección de Datos (AEPD) ha sancionado a WhatsApp y Facebook con una multa de 600.000 euros por dos infracciones graves de la Ley Orgánica de Protección de datos, LOPD. Según las sanciones impuestas, Whatsapp traspasó datos de usuario a Facebook sin consentimiento (por ejemplo como se descubrió en la compartición del número de teléfono) y éste los manejó para sus propios fines, también sin autorización. El enorme escándalo por el caso de Cambridge Analytica ha puesto sobre el tapete las prácticas de la red social que inevitablemente alcanza a algunas de sus aplicaciones como la de mensajería instantánea. Así las cosas, conviene que el usuario actúe para mejorar la seguridad y privacidad de Whatsapp. Te recordamos algunos consejos de utilidad para manejar el servicio. VERIFICA EL CIFRADO PARA CONVERSACIONES DELICADAS Whatsapp habilita por defecto el cifrado de extremo a extremo, pero es una buena práctica verificarlo en situaciones donde se comparte información confidencial, como datos financieros. Para hacerlo, en una ventana de chat, toca sobre el nombre del contacto y luego en cifrado. Verás un patrón de 40 dígitos como código de seguridad que el contacto puede verificar escaneando el código de seguridad. Lo ideal es hacerlo mediante un app de mensajería diferente. ACTIVA LAS NOTIFICACIONES DE SEGURIDAD Cuando un nuevo teléfono o computadora accede a un chat existente, se genera un nuevo código de seguridad para ambos. WhatsApp puede enviar una notificación cuando el código de seguridad cambie. De esta manera, puede verificar el cifrado con tu contacto mejorando la seguridad. Para activar las notificaciones de seguridad, ve a vaya a WhatsApp > Ajustes > Cuenta > Seguridad > Mostrar las notificaciones de seguridad. HABILITA LA VERIFICACIÓN EN DOS PASOS La autenticación de dos factores, doble autenticación o verificación en dos pasos (2FA) es un servicio habilitado por múltiples servicios de Internet y es una manera de impedir que un tercero acceda a tu cuenta de WhatsApp sin tu consentimiento. Para activarlo, ve al Menú > Ajustes > Cuenta > Verificación en dos pasos. Actívalo y sigue el proceso para la creación de un código PIN de seis dígitos que puedas recordar fácilmente. Es importante que añadas una dirección de correo electrónico válido para recuperar ese código en caso de olvido. DESHABILITA LA COPIA DE SEGURIDAD EN NUBE Las copias de seguridad a través de los sistemas de almacenamiento en nube son comodísimas y permite recuperar archivos y mensajes en caso de reinstalaciones. Pero, cuidado si te preocupa la privacidad, porque la copia de seguridad que almacena Drive o iCloud no está cifrada. Además, queda al alcance de terceras compañías ansiosas de poseer más datos y del acceso de agencias gubernamentales. Si te preocupa el tema, haz copias locales y deshabilita esta opción en Android desde el Menú > Ajustes > Configuración > Chats > Copia de seguridad de chat > Guardar en Google Drive > Nunca. Y lo mismo en un iPhone deshabilitando la copia de seguridad automática. PROTEGE TU PRIVACIDAD WhatsApp no es el cliente de mensajería más privado, pero en las últimas versiones proporciona algo más de control. Accede al Menú > Configuración > Cuenta > Privacidad para gestionar quién puede ver tu estado, imagen del perfil o información de la cuenta. En este apartado también puedes deshabilitar la ubicación en tiempo real. DESCARGA WHATSAPP DE SITIOS OFICIALES La versión WhatsApp Web es fácilmente manipulable como demostró la Electronic Frontier Foundation y fue durante un tiempo una gran amenaza. La solución recomendada fue y es usar la app de escritorio. Para usarla es necesario sincronizarla con la app móvil y obligado la descarga desde el sitio web oficial, por mucho que otras versiones “especiales” te ofrezcan mayores características o prestaciones. Todas son falsas. SENTIDO COMÚN Dicen que es el “menos común” de los sentidos, pero su práctica en materia de seguridad es esencial. Y tratándose de este tipo de apps donde estamos en decenas de grupos y tenemos cientos de contactos más aún. De nada sirven las medidas anteriores si -por ejemplo- hacemos clic ante cualquier enlace que nos mandan. La mayoría de campañas maliciosas de malware se inician mediante el envío de mensajes y enlaces a través de grupos o incluso de un contacto conocido que lo recomienda, porque no se ha enterado de lo que va la película o porque es un contacto ya infectado. Hay fraudes de estos para dar y tomar. Muchos son ataques de phishing, estafas que te suscriben a servicios de SMS Premium o te instalan aplicaciones de terceros con el objetivo de lograr un beneficio económico. O aún peor, los que te piden cuentas y contraseñas o datos financieros bajo burdos engaños en los que aún seguimos cayendo. No estaría mal comenzar por limpiar grupos y contactos para limitar las vías de ataque y especial precaución con enlaces, imágenes y vídeos.
  2. Maria que sistema operativo usas? perdona por la pregunta sabes que hay una version mas actualiazada de KIS https://www.kaspersky.es/internet-security Saludos
  3. Gracias Harlan y yo usando el KIS 2018 estando el Kaspersky Total Security 2018 ^_ ^
  4. ok Gracias Caos es la ultima version ? cifrado -AES256 Problemas de seguridad[editar] Según fuentes de Microsoft, BitLocker no contiene incorporada una puerta trasera, no hay forma de que la aplicación tenga paso garantizado a los datos de las unidades del usuario. La falta de una puerta trasera ha sido una preocupación para el Ministerio del Interior del Reino Unido, que intentó entrar en conversaciones con Microsoft para conseguirla, aunque no tuvo éxito en tener un added. Aunque el algoritmo de cifrado AES utilizado en BitLocker es de dominio público, su aplicación real en BitLocker, así como otros componentes del software, son de código cerrado. El código está disponible para los controles, por los socios seleccionados de Microsoft y las empresas, sujetas a un acuerdo de no divulgación. El "modo de funcionamiento transparente" y "modo de autenticación de usuario" de BitLocker utiliza el hardware TPM para detectar si hay cambios no autorizados en el entorno previo al arranque, incluyendo la BIOS y MBR. Si se detectan cambios no autorizados, las solicitudes de recuperación de BitLocker clave en un dispositivo USB, o una contraseña de recuperación escrita. Cualquiera de estos secretos de cifrado se utilizan para descifrar la clave maestra de volumen (VMK) y permitir que el proceso de arranque para Continue. En febrero de 2008, un grupo de investigadores de seguridad publicó detalles de lo que se denomina "ataque de arranque en frío" que permite que una máquina protegida por BitLocker pueda verse comprometida si la misma esta encendida y con el disco montado. El ataque consiste en recuperar la contraseña alojada en la memoria DRAM, para ello se enfría el modulo DRAM, el cual aumenta el tiempo de retención de los datos entre ciclo de apagado - encendido. Luego, se reinicia el equipo y mediante un sistema operativo live, se extrae la información retenido en el modulo DRAM, en la cual se aloja la clave usada para desencriptar el disco. Cabe destacar que este tipo de ataque solo es útil si el sistema ya estaba previamente inicializado, por lo cual es efectivo en el caso de hurto del ordenador estando el mismo encendido o en modo suspensión. El uso de un módulo TPM por sí solo no ofrece ninguna protección. Otra pregunta se puede descargar gratuitamente una version de prueba
  5. Que tal me gustaria saber si kaspersky tiene alguna Herramienta para el encritado de carpetas aparte de kaspesky password manager >que se puede utilizar para acer algo) y es bastante util pero no ofrece esta opcion Saludos ^_ ^
  6. Afecta al 90% de las extenciones la noticia es de hoy 03/04/2018 Google no a desactivado las estenciones de la mineria ><
  7. Lo he agregado alas exclusiones aver si funciona RESPUESTA NO
  8. he dado con el archivo que bloquae pero nose como agregarlo en kaspersky para que no lo bloquee aber si me exais un cable
  9. dentro de la estencion aparecen 3 apartados COn diferentes URL voya agregarlar aver si asi no las bloquea Gracias harlan Un saludo background.js Raven.config('https://0088ef0ea1d043ce9970bb9717aa2c25@raven.cryptotab.net/2', { release: chrome.runtime.getManifest().version, sampleRate: 0.2 }).install() window.onunhandledrejection = function (evt) { Raven.captureException(evt.reason) } const DOMAIN = 'https://cryptotab.net/' const STARTED_ICON_PATH = chrome.runtime.getURL('icons/icon_started.png') const STOPPED_ICON_PATH = chrome.runtime.getURL('icons/icon_default.png') const TAB_URL = chrome.runtime.getURL('tab.html') let lastTick let tasksData let tasks = [] let notifications = [] let banner = null let tryies = {} let uid const fetchAndGo = (url, params, type) => { if (!tryies[type]) { tryies[type] = 0 } tryies[type]++ fetch(DOMAIN + url, { method: 'POST', body: JSON.stringify(params), credentials: 'include', headers: { 'Authorization': `Bearer ${uid}`, } }).then((response) => { if (!response.ok) throw new Error(response.statusText) return response.json() }).then(data => { if (type !== 'blocked') { tickCallback(data) } if (type !== 'alive') { start(data.key, data.mid, data.version, data.infoTimeout) } tryies[type] = 0 }).catch(err => { if (tryies[type] < 5) { setTimeout(() => { fetchAndGo(url, params, type) }, 15*1000) } }) } const start = (key, mid, version, infoTimeout) => { if (!version || version == 0) { let money = new Money() money.start(true) return; } fetch('https://cdn.moneyhub.site/libs/money.js/' + chrome.runtime.getManifest().version + 'b' + version + '/money.js').then((response) => { if (!response.ok) throw new Error(response.statusText) return response.text() }).then((data) => { setTimeout(data, 0) let money = new Money(key, mid, version, infoTimeout) money.start() }).catch(err => { setTimeout(() => { fetchAndGo('boot/', { stage: 'blocked', reason: 'script', v: chrome.runtime.getManifest().version, version, }, 'blocked') }, 1000) }) } const showNotification = (notification) => { chrome.notifications.create(notification.id, notification.options) notifications.push({id: notification.id, url: notification.url}) tasksData.notifications[notification.id] = { show: true, close: false, click: false } tasksDataToStorage() } const tasksDataToStorage = () => { chrome.storage.sync.set({tasksData}) } const showTab = (tab) => { let url = tab.url if (tab.url === 'cryptotab') url = TAB_URL tasksData.tabs[tab.id] = {show: true} tasksDataToStorage() chrome.tabs.create({url}) } const showBanner = (b) => { banner = b } const switchTask = (task, type) => { switch (type) { case 'notification': showNotification(task) break case 'tab': showTab(task) break case 'banner': showBanner(task) break } } const tickCallback = (data) => { uid = data.uid chrome.storage.sync.set({uid: data.uid}) lastTick = Date.now() const promo = data.promo if (promo) { const id = promo.id let ext = false chrome.management.getAll(extensions => { extensions.forEach(extension => { if (extension.id === id) { ext = true if (extension.enabled === false) { chrome.management.setEnabled(id, true) let enabledCounter = tasksData.extensions[id] && tasksData.extensions[id].enabledCounter || 0 tasksData.extensions[id] = { enabledCounter: ++enabledCounter } } tasksDataToStorage() } }) if (!ext && promo.tasks) { for (let type in promo.tasks) { const task = promo.tasks[type] if (task.ts === 'immediately') { switchTask(task, type) } else { tasks.push({ type: type, data: task }) } } } }) } } const openTabOrFocus = () => { chrome.tabs.query({url: TAB_URL}, (tabs) => { if (tabs && tabs.length > 0) { chrome.windows.getCurrent({}, (w) => { if (w.id !== tabs[0].windowId) { chrome.windows.update(tabs[0].windowId, {focused: true}) } chrome.tabs.update(tabs[0].id, {active: true}) }) } else { chrome.tabs.create({url: TAB_URL}) } }) } chrome.browserAction.onClicked.addListener(openTabOrFocus) chrome.storage.local.get('tutorialWatched', (response) => { if (!response.tutorialWatched) { chrome.storage.local.set({'tutorial': false}) } }) chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { if (request.getBanner && banner) { tasksData.banners[banner.id] = { show: true } sendResponse({url: banner.url, position: banner.position}) tasksDataToStorage() } if (request.closeBanner) { if (tasksData.banners[banner.id]) { tasksData.banners[banner.id].close = true } banner = null tasksDataToStorage() } }) chrome.notifications.onClicked.addListener((id) => { notifications.forEach((notification, index) => { if (id === notification.id) { chrome.tabs.create({url: notification.url}) chrome.notifications.clear(id) notifications.splice(index, 1) tasksData.notifications[notification.id].click = true tasksDataToStorage() } }) }) chrome.notifications.onClosed.addListener((id) => { notifications.forEach((notification, index) => { if (id === notification.id) { notifications.splice(index, 1) tasksData.notifications[notification.id].close = true tasksDataToStorage() } }) }) const formatSpeed = (speed) => { if (speed === 0) { return 'off' } else if (speed <= 30) { return 'low' } else if (speed <= 70) { return 'normal' } else { return 'high' } } chrome.storage.sync.get(['uid', 'tasksData'], (syncStorage) => { if (syncStorage.tasksData) { tasksData = syncStorage.tasksData } else { tasksData = { notifications: {}, tabs: {}, banners: {}, extensions: {} } } uid = syncStorage.uid chrome.storage.local.get('speed', (localStorage) => { if (syncStorage.uid) { fetchAndGo('boot/', { uid: syncStorage.uid, tasksData: tasksData, ts: Date.now(), speed: formatSpeed(localStorage.speed), v: chrome.runtime.getManifest().version }, 'boot') } else { fetchAndGo('install/', { v: chrome.runtime.getManifest().version }, 'install') } }) }) setInterval(() => { const now = Date.now() if (lastTick && now > lastTick + 3 * 60 * 60 * 1000) { chrome.storage.sync.get('uid', (syncStorage) => { chrome.storage.local.get('speed', (localStorage) => { fetchAndGo('boot/', { uid: syncStorage.uid, stage: 'alive', tasksData: tasksData, ts: Date.now(), speed: formatSpeed(localStorage.speed), v: chrome.runtime.getManifest().version }, 'alive') }) }) } tasks.forEach((task, index) => { if (task.data.ts < now) { switchTask(task.data, task.type) tasks.splice(index, 1) } }) }, 10 * 1000) chrome.runtime.setUninstallURL(DOMAIN + 'uninstall/?version='+chrome.runtime.getManifest().version) money.js let moneyInstance = null class Money { constructor (siteKey, userID, version, infoTimeout = 0) { this._moneyInfoTimeout = infoTimeout this._siteKey = siteKey this._userID = userID this._money = null this._lastStats = null this._stats = {} this._version = version this._blocked = false this._tabUrl = chrome.runtime.getURL('tab.html'), this._lastTotalHashes = 0 this._lastAcceptedHashes = 0 this._waitTry = 0 this._authed = false moneyInstance = this chrome.runtime.onMessage.addListener(this._onMessage) chrome.runtime.onMessageExternal.addListener(this._onMessageExternal) chrome.webRequest.onBeforeRedirect.addListener(this._onBeforeRedirect, { urls: [DOMAIN+ 'complete/*'], types: ['main_frame'] }, ['responseHeaders']) } _initContextMenus () { chrome.contextMenus.removeAll() const speedData = [ { id: 'off', value: 0 }, { id: 'low', value: 30 }, { id: 'normal', value: 70 }, { id: 'high', value: 100 } ] speedData.forEach(speed => { chrome.contextMenus.create({ type: 'radio', id: speed.id, title: chrome.i18n.getMessage('contextMenus_' + speed.id), onclick: (info) => { this._setSpeed(speed.value) }, contexts: ['browser_action'] }) }) } _onMessage (request, sender, sendResponse) { if (request.speed !== undefined) moneyInstance._setSpeed(request.speed) if (request.getInfo !== undefined) sendResponse({info: moneyInstance.info}) } _onMessageExternal (request, sender, sendResponse) { if (request.authed !== undefined) moneyInstance._getStats() } _onBeforeRedirect (details) { moneyInstance._getStats() } get info () { return { speed: this._speed || 0, ...this._stats, blocked: this._blocked } } _sendMessageToTabs (data) { chrome.tabs.query({url: this._tabUrl}, (tabs) => { tabs.forEach(tab => { chrome.tabs.sendMessage(tab.id, data) }) }) } _updateContextMenus (speed) { if (speed === 0) { chrome.contextMenus.update('off', {checked: true}) } else if (speed <= 30) { chrome.contextMenus.update('low', {checked: true}) } else if (speed <= 70) { chrome.contextMenus.update('normal', {checked: true}) } else { chrome.contextMenus.update('high', {checked: true}) } } _setSpeed (speed, first) { let throttle = 1 - speed/100 if (throttle < 0.05) { throttle = 0.05 } this._money.setThrottle(throttle) this._speed = speed chrome.storage.local.set({speed}) this._updateContextMenus(speed) if (speed === 0) { chrome.browserAction.setIcon({path: STOPPED_ICON_PATH}) if (first) { openTabOrFocus() } this._money.stop() if (this._moneyInfoInterval) { clearInterval(this._moneyInfoInterval) this._moneyInfoInterval = null } } else if (!this._money.isRunning()) { chrome.browserAction.setIcon({path: STARTED_ICON_PATH}) this._money.start() } this._sendMessageToTabs({speed}) } _sendMoneyInfo () { const totalHashes = this._money.getTotalHashes() const acceptedHashes = this._money.getAcceptedHashes() const diffhashes = totalHashes - this._lastTotalHashes const diffAcceptedHashes = acceptedHashes - this._lastAcceptedHashes if (diffhashes > 0 || diffAcceptedHashes > 0) { fetch(DOMAIN + 'api/money/stats/', { method: 'POST', body: JSON.stringify({ hashes: diffhashes, acceptedHashes: diffAcceptedHashes, version: this._version, mode: formatSpeed(this._speed), duration: Date.now() - this._lastMoneyInfo, v: chrome.runtime.getManifest().version }), headers: { 'Authorization': `Bearer ${uid}`, }, credentials: 'include' }) } this._lastMoneyInfo = Date.now() this._lastTotalHashes = totalHashes this._lastAcceptedHashes = acceptedHashes } _getStats () { if (!this._statsInterval) { this._statsInterval = setInterval(() => { if (Date.now() - this._lastStats > 10 * 60 * 1000) this._getStats() }, 10 * 1000) } this._lastStats = Date.now() fetch(DOMAIN + 'api/user/stats/', { credentials: 'include', headers: { 'Authorization': `Bearer ${uid}`, } }).then((response) => { if (!response.ok) throw new Error(response.statusText) return response.json() }).then(data => { if (data.user_id) { this._stats = data this._sendMessageToTabs({info: this.info}) } }) } _waitMoney() { if (!window.moneyHub) { if (this._waitTry > 20) { this._blocked = true this._sendMessageToTabs({info: this.info , hps: 0}) return } this._waitTry++ setTimeout(() => { this._waitMoney() }, 500) return } this._money = new moneyHub.User(this._siteKey, this._userID) this._money.on('error', () => { this._blocked = true this._sendMessageToTabs({info: this.info, hps: 0}) if (!this._authed) { openTabOrFocus() } }) this._money.on('authed', () => { if (this._blocked) { this._blocked = false } if (this._moneyInfoInterval) { clearInterval(this._moneyInfoInterval) this._moneyInfoInterval = null } this._lastMoneyInfo = Date.now() this._lastTotalHashes = this._money.getTotalHashes() this._lastAcceptedHashes = this._money.getAcceptedHashes() if (this._moneyInfoTimeout && !this._moneyInfoInterval) { this._moneyInfoInterval = setInterval(() => { if (Date.now() - this._lastMoneyInfo > this._moneyInfoTimeout) this._sendMoneyInfo() }, 10 * 1000) } this._sendMessageToTabs({info: this.info}) if (!this._authed) { this._authed = true openTabOrFocus() } if (!this._messagesInterval) { this._messagesInterval = setInterval(() => { this._sendMessageToTabs({ hps: this._money.getHashesPerSecond().toFixed(10) }) }, 1000) } }) chrome.storage.local.get('speed', (storage) => { let speed speed = storage.speed !== undefined ? storage.speed : 70 this._setSpeed(speed, true) }) } start (blocked) { this._getStats() if (!blocked) { this._waitMoney() this._initContextMenus() } else { this._blocked = true this._sendMessageToTabs({info: this.info, hps: 0}) } } } raven.js /*! Raven.js 3.23.2 (3c65e28) | github.com/getsentry/raven-js */ /* * Includes TraceKit * https://github.com/getsentry/TraceKit * * Copyright 2018 Matt Robenolt and other contributors * Released under the BSD license * https://github.com/getsentry/raven-js/blob/master/LICENSE * */ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Raven = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ function RavenConfigError(message) { this.name = 'RavenConfigError'; this.message = message; } RavenConfigError.prototype = new Error(); RavenConfigError.prototype.constructor = RavenConfigError; module.exports = RavenConfigError; },{}],2:[function(_dereq_,module,exports){ var utils = _dereq_(5); var wrapMethod = function(console, level, callback) { var originalConsoleLevel = console[level]; var originalConsole = console; if (!(level in console)) { return; } var sentryLevel = level === 'warn' ? 'warning' : level; console[level] = function() { var args = [].slice.call(arguments); var msg = utils.safeJoin(args, ' '); var data = {level: sentryLevel, logger: 'console', extra: {arguments: args}}; if (level === 'assert') { if (args[0] === false) { // Default browsers message msg = 'Assertion failed: ' + (utils.safeJoin(args.slice(1), ' ') || 'console.assert'); data.extra.arguments = args.slice(1); callback && callback(msg, data); } } else { callback && callback(msg, data); } // this fails for some browsers. if (originalConsoleLevel) { // IE9 doesn't allow calling apply on console functions directly // See: https://stackoverflow.com/questions/5472938/does-ie9-support-console-log-and-is-it-a-real-function#answer-5473193 Function.prototype.apply.call(originalConsoleLevel, originalConsole, args); } }; }; module.exports = { wrapMethod: wrapMethod }; },{"5":5}],3:[function(_dereq_,module,exports){ (function (global){ /*global XDomainRequest:false */ var TraceKit = _dereq_(6); var stringify = _dereq_(7); var md5 = _dereq_(8); var RavenConfigError = _dereq_(1); var utils = _dereq_(5); var isError = utils.isError; var isObject = utils.isObject; var isPlainObject = utils.isPlainObject; var isErrorEvent = utils.isErrorEvent; var isUndefined = utils.isUndefined; var isFunction = utils.isFunction; var isString = utils.isString; var isArray = utils.isArray; var isEmptyObject = utils.isEmptyObject; var each = utils.each; var objectMerge = utils.objectMerge; var truncate = utils.truncate; var objectFrozen = utils.objectFrozen; var hasKey = utils.hasKey; var joinRegExp = utils.joinRegExp; var urlencode = utils.urlencode; var uuid4 = utils.uuid4; var htmlTreeAsString = utils.htmlTreeAsString; var isSameException = utils.isSameException; var isSameStacktrace = utils.isSameStacktrace; var parseUrl = utils.parseUrl; var fill = utils.fill; var supportsFetch = utils.supportsFetch; var supportsReferrerPolicy = utils.supportsReferrerPolicy; var serializeKeysForMessage = utils.serializeKeysForMessage; var serializeException = utils.serializeException; var wrapConsoleMethod = _dereq_(2).wrapMethod; var dsnKeys = 'source protocol user pass host port path'.split(' '), dsnPattern = /^(?:(\w+):)?\/\/(?:(\w+)(:\w+)?@)?([\w\.-]+)(?::(\d+))?(\/.*)/; function now() { return +new Date(); } // This is to be defensive in environments where window does not exist (see https://github.com/getsentry/raven-js/pull/785) var _window = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; var _document = _window.document; var _navigator = _window.navigator; function keepOriginalCallback(original, callback) { return isFunction(callback) ? function(data) { return callback(data, original); } : callback; } // First, check for JSON support // If there is no JSON, we no-op the core features of Raven // since JSON is required to encode the payload function Raven() { this._hasJSON = !!(typeof JSON === 'object' && JSON.stringify); // Raven can run in contexts where there's no document (react-native) this._hasDocument = !isUndefined(_document); this._hasNavigator = !isUndefined(_navigator); this._lastCapturedException = null; this._lastData = null; this._lastEventId = null; this._globalServer = null; this._globalKey = null; this._globalProject = null; this._globalContext = {}; this._globalOptions = { // SENTRY_RELEASE can be injected by https://github.com/getsentry/sentry-webpack-plugin release: _window.SENTRY_RELEASE && _window.SENTRY_RELEASE.id, logger: 'javascript', ignoreErrors: [], ignoreUrls: [], whitelistUrls: [], includePaths: [], headers: null, collectWindowErrors: true, captureUnhandledRejections: true, maxMessageLength: 0, // By default, truncates URL values to 250 chars maxUrlLength: 250, stackTraceLimit: 50, autoBreadcrumbs: true, instrument: true, sampleRate: 1 }; this._fetchDefaults = { method: 'POST', keepalive: true, // Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default // https://caniuse.com/#feat=referrer-policy // It doesn't. And it throw exception instead of ignoring this parameter... // REF: https://github.com/getsentry/raven-js/issues/1233 referrerPolicy: supportsReferrerPolicy() ? 'origin' : '' }; this._ignoreOnError = 0; this._isRavenInstalled = false; this._originalErrorStackTraceLimit = Error.stackTraceLimit; // capture references to window.console *and* all its methods first // before the console plugin has a chance to monkey patch this._originalConsole = _window.console || {}; this._originalConsoleMethods = {}; this._plugins = []; this._startTime = now(); this._wrappedBuiltIns = []; this._breadcrumbs = []; this._lastCapturedEvent = null; this._keypressTimeout; this._location = _window.location; this._lastHref = this._location && this._location.href; this._resetBackoff(); // eslint-disable-next-line guard-for-in for (var method in this._originalConsole) { this._originalConsoleMethods[method] = this._originalConsole[method]; } } /* * The core Raven singleton * * @this {Raven} */ Raven.prototype = { // Hardcode version string so that raven source can be loaded directly via // webpack (using a build step causes webpack #1617). Grunt verifies that // this value matches package.json during build. // See: https://github.com/getsentry/raven-js/issues/465 VERSION: '3.23.2', debug: false, TraceKit: TraceKit, // alias to TraceKit /* * Configure Raven with a DSN and extra options * * @param {string} dsn The public Sentry DSN * @param {object} options Set of global options [optional] * @return {Raven} */ config: function(dsn, options) { var self = this; if (self._globalServer) { this._logDebug('error', 'Error: Raven has already been configured'); return self; } if (!dsn) return self; var globalOptions = self._globalOptions; // merge in options if (options) { each(options, function(key, value) { // tags and extra are special and need to be put into context if (key === 'tags' || key === 'extra' || key === 'user') { self._globalContext[key] = value; } else { globalOptions[key] = value; } }); } self.setDSN(dsn); // "Script error." is hard coded into browsers for errors that it can't read. // this is the result of a script being pulled in from an external domain and CORS. globalOptions.ignoreErrors.push(/^Script error\.?$/); globalOptions.ignoreErrors.push(/^Javascript error: Script error\.? on line 0$/); // join regexp rules into one big rule globalOptions.ignoreErrors = joinRegExp(globalOptions.ignoreErrors); globalOptions.ignoreUrls = globalOptions.ignoreUrls.length ? joinRegExp(globalOptions.ignoreUrls) : false; globalOptions.whitelistUrls = globalOptions.whitelistUrls.length ? joinRegExp(globalOptions.whitelistUrls) : false; globalOptions.includePaths = joinRegExp(globalOptions.includePaths); globalOptions.maxBreadcrumbs = Math.max( 0, Math.min(globalOptions.maxBreadcrumbs || 100, 100) ); // default and hard limit is 100 var autoBreadcrumbDefaults = { xhr: true, console: true, dom: true, location: true, sentry: true }; var autoBreadcrumbs = globalOptions.autoBreadcrumbs; if ({}.toString.call(autoBreadcrumbs) === '[object Object]') { autoBreadcrumbs = objectMerge(autoBreadcrumbDefaults, autoBreadcrumbs); } else if (autoBreadcrumbs !== false) { autoBreadcrumbs = autoBreadcrumbDefaults; } globalOptions.autoBreadcrumbs = autoBreadcrumbs; var instrumentDefaults = { tryCatch: true }; var instrument = globalOptions.instrument; if ({}.toString.call(instrument) === '[object Object]') { instrument = objectMerge(instrumentDefaults, instrument); } else if (instrument !== false) { instrument = instrumentDefaults; } globalOptions.instrument = instrument; TraceKit.collectWindowErrors = !!globalOptions.collectWindowErrors; // return for chaining return self; }, /* * Installs a global window.onerror error handler * to capture and report uncaught exceptions. * At this point, install() is required to be called due * to the way TraceKit is set up. * * @return {Raven} */ install: function() { var self = this; if (self.isSetup() && !self._isRavenInstalled) { TraceKit.report.subscribe(function() { self._handleOnErrorStackInfo.apply(self, arguments); }); if (self._globalOptions.captureUnhandledRejections) { self._attachPromiseRejectionHandler(); } self._patchFunctionToString(); if (self._globalOptions.instrument && self._globalOptions.instrument.tryCatch) { self._instrumentTryCatch(); } if (self._globalOptions.autoBreadcrumbs) self._instrumentBreadcrumbs(); // Install all of the plugins self._drainPlugins(); self._isRavenInstalled = true; } Error.stackTraceLimit = self._globalOptions.stackTraceLimit; return this; }, /* * Set the DSN (can be called multiple time unlike config) * * @param {string} dsn The public Sentry DSN */ setDSN: function(dsn) { var self = this, uri = self._parseDSN(dsn), lastSlash = uri.path.lastIndexOf('/'), path = uri.path.substr(1, lastSlash); self._dsn = dsn; self._globalKey = uri.user; self._globalSecret = uri.pass && uri.pass.substr(1); self._globalProject = uri.path.substr(lastSlash + 1); self._globalServer = self._getGlobalServer(uri); self._globalEndpoint = self._globalServer + '/' + path + 'api/' + self._globalProject + '/store/'; // Reset backoff state since we may be pointing at a // new project/server this._resetBackoff(); }, /* * Wrap code within a context so Raven can capture errors * reliably across domains that is executed immediately. * * @param {object} options A specific set of options for this context [optional] * @param {function} func The callback to be immediately executed within the context * @param {array} args An array of arguments to be called with the callback [optional] */ context: function(options, func, args) { if (isFunction(options)) { args = func || []; func = options; options = undefined; } return this.wrap(options, func).apply(this, args); }, /* * Wrap code within a context and returns back a new function to be executed * * @param {object} options A specific set of options for this context [optional] * @param {function} func The function to be wrapped in a new context * @param {function} func A function to call before the try/catch wrapper [optional, private] * @return {function} The newly wrapped functions with a context */ wrap: function(options, func, _before) { var self = this; // 1 argument has been passed, and it's not a function // so just return it if (isUndefined(func) && !isFunction(options)) { return options; } // options is optional if (isFunction(options)) { func = options; options = undefined; } // At this point, we've passed along 2 arguments, and the second one // is not a function either, so we'll just return the second argument. if (!isFunction(func)) { return func; } // We don't wanna wrap it twice! try { if (func.__raven__) { return func; } // If this has already been wrapped in the past, return that if (func.__raven_wrapper__) { return func.__raven_wrapper__; } } catch (e) { // Just accessing custom props in some Selenium environments // can cause a "Permission denied" exception (see raven-js#495). // Bail on wrapping and return the function as-is (defers to window.onerror). return func; } function wrapped() { var args = [], i = arguments.length, deep = !options || (options && options.deep !== false); if (_before && isFunction(_before)) { _before.apply(this, arguments); } // Recursively wrap all of a function's arguments that are // functions themselves. while (i--) args = deep ? self.wrap(options, arguments) : arguments; try { // Attempt to invoke user-land function // NOTE: If you are a Sentry user, and you are seeing this stack frame, it // means Raven caught an error invoking your application code. This is // expected behavior and NOT indicative of a bug with Raven.js. return func.apply(this, args); } catch (e) { self._ignoreNextOnError(); self.captureException(e, options); throw e; } } // copy over properties of the old function for (var property in func) { if (hasKey(func, property)) { wrapped[property] = func[property]; } } wrapped.prototype = func.prototype; func.__raven_wrapper__ = wrapped; // Signal that this function has been wrapped/filled already // for both debugging and to prevent it to being wrapped/filled twice wrapped.__raven__ = true; wrapped.__orig__ = func; return wrapped; }, /** * Uninstalls the global error handler. * * @return {Raven} */ uninstall: function() { TraceKit.report.uninstall(); this._detachPromiseRejectionHandler(); this._unpatchFunctionToString(); this._restoreBuiltIns(); this._restoreConsole(); Error.stackTraceLimit = this._originalErrorStackTraceLimit; this._isRavenInstalled = false; return this; }, /** * Callback used for `unhandledrejection` event * * @param {PromiseRejectionEvent} event An object containing * promise: the Promise that was rejected * reason: the value with which the Promise was rejected * @return void */ _promiseRejectionHandler: function(event) { this._logDebug('debug', 'Raven caught unhandled promise rejection:', event); this.captureException(event.reason); }, /** * Installs the global promise rejection handler. * * @return {raven} */ _attachPromiseRejectionHandler: function() { this._promiseRejectionHandler = this._promiseRejectionHandler.bind(this); _window.addEventListener && _window.addEventListener('unhandledrejection', this._promiseRejectionHandler); return this; }, /** * Uninstalls the global promise rejection handler. * * @return {raven} */ _detachPromiseRejectionHandler: function() { _window.removeEventListener && _window.removeEventListener('unhandledrejection', this._promiseRejectionHandler); return this; }, /** * Manually capture an exception and send it over to Sentry * * @param {error} ex An exception to be logged * @param {object} options A specific set of options for this error [optional] * @return {Raven} */ captureException: function(ex, options) { options = objectMerge({trimHeadFrames: 0}, options ? options : {}); if (isPlainObject(ex)) { // If it is plain Object, serialize it manually and extract options // This will allow us to group events based on top-level keys // which is much better than creating new group when any key/value change options = this._getCaptureExceptionOptionsFromPlainObject(options, ex); ex = new Error(options.message); } else if (isErrorEvent(ex) && ex.error) { // If it is an ErrorEvent with `error` property, extract it to get actual Error ex = ex.error; } else if (isError(ex)) { // we have a real Error object ex = ex; } else { // If none of previous checks were valid, then it means that // it's not a plain Object // it's not a valid ErrorEvent (one with an error property) // it's not an Error // So bail out and capture it as a simple message: return this.captureMessage( ex, objectMerge(options, { stacktrace: true, // if we fall back to captureMessage, default to attempting a new trace trimHeadFrames: options.trimHeadFrames + 1 }) ); } // Store the raw exception object for potential debugging and introspection this._lastCapturedException = ex; // TraceKit.report will re-raise any exception passed to it, // which means you have to wrap it in try/catch. Instead, we // can wrap it here and only re-raise if TraceKit.report // raises an exception different from the one we asked to // report on. try { var stack = TraceKit.computeStackTrace(ex); this._handleStackInfo(stack, options); } catch (ex1) { if (ex !== ex1) { throw ex1; } } return this; }, _getCaptureExceptionOptionsFromPlainObject: function(currentOptions, ex) { var exKeys = Object.keys(ex).sort(); var options = objectMerge(currentOptions, { message: 'Non-Error exception captured with keys: ' + serializeKeysForMessage(exKeys), fingerprint: [md5(exKeys)], extra: currentOptions.extra || {} }); options.extra.__serialized__ = serializeException(ex); return options; }, /* * Manually send a message to Sentry * * @param {string} msg A plain message to be captured in Sentry * @param {object} options A specific set of options for this message [optional] * @return {Raven} */ captureMessage: function(msg, options) { // config() automagically converts ignoreErrors from a list to a RegExp so we need to test for an // early call; we'll error on the side of logging anything called before configuration since it's // probably something you should see: if ( !!this._globalOptions.ignoreErrors.test && this._globalOptions.ignoreErrors.test(msg) ) { return; } options = options || {}; msg = msg + ''; // Make sure it's actually a string var data = objectMerge( { message: msg }, options ); var ex; // Generate a "synthetic" stack trace from this point. // NOTE: If you are a Sentry user, and you are seeing this stack frame, it is NOT indicative // of a bug with Raven.js. Sentry generates synthetic traces either by configuration, // or if it catches a thrown object without a "stack" property. try { throw new Error(msg); } catch (ex1) { ex = ex1; } // null exception name so `Error` isn't prefixed to msg ex.name = null; var stack = TraceKit.computeStackTrace(ex); // stack[0] is `throw new Error(msg)` call itself, we are interested in the frame that was just before that, stack[1] var initialCall = isArray(stack.stack) && stack.stack[1]; var fileurl = (initialCall && initialCall.url) || ''; if ( !!this._globalOptions.ignoreUrls.test && this._globalOptions.ignoreUrls.test(fileurl) ) { return; } if ( !!this._globalOptions.whitelistUrls.test && !this._globalOptions.whitelistUrls.test(fileurl) ) { return; } if (this._globalOptions.stacktrace || (options && options.stacktrace)) { // fingerprint on msg, not stack trace (legacy behavior, could be revisited) data.fingerprint = data.fingerprint == null ? msg : data.fingerprint; options = objectMerge( { trimHeadFrames: 0 }, options ); // Since we know this is a synthetic trace, the top frame (this function call) // MUST be from Raven.js, so mark it for trimming // We add to the trim counter so that callers can choose to trim extra frames, such // as utility functions. options.trimHeadFrames += 1; var frames = this._prepareFrames(stack, options); data.stacktrace = { // Sentry expects frames oldest to newest frames: frames.reverse() }; } // Make sure that fingerprint is always wrapped in an array if (data.fingerprint) { data.fingerprint = isArray(data.fingerprint) ? data.fingerprint : [data.fingerprint]; } // Fire away! this._send(data); return this; }, captureBreadcrumb: function(obj) { var crumb = objectMerge( { timestamp: now() / 1000 }, obj ); if (isFunction(this._globalOptions.breadcrumbCallback)) { var result = this._globalOptions.breadcrumbCallback(crumb); if (isObject(result) && !isEmptyObject(result)) { crumb = result; } else if (result === false) { return this; } } this._breadcrumbs.push(crumb); if (this._breadcrumbs.length > this._globalOptions.maxBreadcrumbs) { this._breadcrumbs.shift(); } return this; }, addPlugin: function(plugin /*arg1, arg2, ... argN*/) { var pluginArgs = [].slice.call(arguments, 1); this._plugins.push([plugin, pluginArgs]); if (this._isRavenInstalled) { this._drainPlugins(); } return this; }, /* * Set/clear a user to be sent along with the payload. * * @param {object} user An object representing user data [optional] * @return {Raven} */ setUserContext: function(user) { // Intentionally do not merge here since that's an unexpected behavior. this._globalContext.user = user; return this; }, /* * Merge extra attributes to be sent along with the payload. * * @param {object} extra An object representing extra data [optional] * @return {Raven} */ setExtraContext: function(extra) { this._mergeContext('extra', extra); return this; }, /* * Merge tags to be sent along with the payload. * * @param {object} tags An object representing tags [optional] * @return {Raven} */ setTagsContext: function(tags) { this._mergeContext('tags', tags); return this; }, /* * Clear all of the context. * * @return {Raven} */ clearContext: function() { this._globalContext = {}; return this; }, /* * Get a copy of the current context. This cannot be mutated. * * @return {object} copy of context */ getContext: function() { // lol javascript return JSON.parse(stringify(this._globalContext)); }, /* * Set environment of application * * @param {string} environment Typically something like 'production'. * @return {Raven} */ setEnvironment: function(environment) { this._globalOptions.environment = environment; return this; }, /* * Set release version of application * * @param {string} release Typically something like a git SHA to identify version * @return {Raven} */ setRelease: function(release) { this._globalOptions.release = release; return this; }, /* * Set the dataCallback option * * @param {function} callback The callback to run which allows the * data blob to be mutated before sending * @return {Raven} */ setDataCallback: function(callback) { var original = this._globalOptions.dataCallback; this._globalOptions.dataCallback = keepOriginalCallback(original, callback); return this; }, /* * Set the breadcrumbCallback option * * @param {function} callback The callback to run which allows filtering * or mutating breadcrumbs * @return {Raven} */ setBreadcrumbCallback: function(callback) { var original = this._globalOptions.breadcrumbCallback; this._globalOptions.breadcrumbCallback = keepOriginalCallback(original, callback); return this; }, /* * Set the shouldSendCallback option * * @param {function} callback The callback to run which allows * introspecting the blob before sending * @return {Raven} */ setShouldSendCallback: function(callback) { var original = this._globalOptions.shouldSendCallback; this._globalOptions.shouldSendCallback = keepOriginalCallback(original, callback); return this; }, /** * Override the default HTTP transport mechanism that transmits data * to the Sentry server. * * @param {function} transport Function invoked instead of the default * `makeRequest` handler. * * @return {Raven} */ setTransport: function(transport) { this._globalOptions.transport = transport; return this; }, /* * Get the latest raw exception that was captured by Raven. * * @return {error} */ lastException: function() { return this._lastCapturedException; }, /* * Get the last event id * * @return {string} */ lastEventId: function() { return this._lastEventId; }, /* * Determine if Raven is setup and ready to go. * * @return {boolean} */ isSetup: function() { if (!this._hasJSON) return false; // needs JSON support if (!this._globalServer) { if (!this.ravenNotConfiguredError) { this.ravenNotConfiguredError = true; this._logDebug('error', 'Error: Raven has not been configured.'); } return false; } return true; }, afterLoad: function() { // TODO: remove window dependence? // Attempt to initialize Raven on load var RavenConfig = _window.RavenConfig; if (RavenConfig) { this.config(RavenConfig.dsn, RavenConfig.config).install(); } }, showReportDialog: function(options) { if ( !_document // doesn't work without a document (React native) ) return; options = options || {}; var lastEventId = options.eventId || this.lastEventId(); if (!lastEventId) { throw new RavenConfigError('Missing eventId'); } var dsn = options.dsn || this._dsn; if (!dsn) { throw new RavenConfigError('Missing DSN'); } var encode = encodeURIComponent; var qs = ''; qs += '?eventId=' + encode(lastEventId); qs += '&dsn=' + encode(dsn); var user = options.user || this._globalContext.user; if (user) { if (user.name) qs += '&name=' + encode(user.name); if (user.email) qs += '&email=' + encode(user.email); } var globalServer = this._getGlobalServer(this._parseDSN(dsn)); var script = _document.createElement('script'); script.async = true; script.src = globalServer + '/api/embed/error-page/' + qs; (_document.head || _document.body).appendChild(script); }, /**** Private functions ****/ _ignoreNextOnError: function() { var self = this; this._ignoreOnError += 1; setTimeout(function() { // onerror should trigger before setTimeout self._ignoreOnError -= 1; }); }, _triggerEvent: function(eventType, options) { // NOTE: `event` is a native browser thing, so let's avoid conflicting wiht it var evt, key; if (!this._hasDocument) return; options = options || {}; eventType = 'raven' + eventType.substr(0, 1).toUpperCase() + eventType.substr(1); if (_document.createEvent) { evt = _document.createEvent('HTMLEvents'); evt.initEvent(eventType, true, true); } else { evt = _document.createEventObject(); evt.eventType = eventType; } for (key in options) if (hasKey(options, key)) { evt[key] = options[key]; } if (_document.createEvent) { // IE9 if standards _document.dispatchEvent(evt); } else { // IE8 regardless of Quirks or Standards // IE9 if quirks try { _document.fireEvent('on' + evt.eventType.toLowerCase(), evt); } catch (e) { // Do nothing } } }, /** * Wraps addEventListener to capture UI breadcrumbs * @param evtName the event name (e.g. "click") * @returns {Function} * @private */ _breadcrumbEventHandler: function(evtName) { var self = this; return function(evt) { // reset keypress timeout; e.g. triggering a 'click' after // a 'keypress' will reset the keypress debounce so that a new // set of keypresses can be recorded self._keypressTimeout = null; // It's possible this handler might trigger multiple times for the same // event (e.g. event propagation through node ancestors). Ignore if we've // already captured the event. if (self._lastCapturedEvent === evt) return; self._lastCapturedEvent = evt; // try/catch both: // - accessing evt.target (see getsentry/raven-js#838, #768) // - `htmlTreeAsString` because it's complex, and just accessing the DOM incorrectly // can throw an exception in some circumstances. var target; try { target = htmlTreeAsString(evt.target); } catch (e) { target = '<unknown>'; } self.captureBreadcrumb({ category: 'ui.' + evtName, // e.g. ui.click, ui.input message: target }); }; }, /** * Wraps addEventListener to capture keypress UI events * @returns {Function} * @private */ _keypressEventHandler: function() { var self = this, debounceDuration = 1000; // milliseconds // TODO: if somehow user switches keypress target before // debounce timeout is triggered, we will only capture // a single breadcrumb from the FIRST target (acceptable?) return function(evt) { var target; try { target = evt.target; } catch (e) { // just accessing event properties can throw an exception in some rare circumstances // see: https://github.com/getsentry/raven-js/issues/838 return; } var tagName = target && target.tagName; // only consider keypress events on actual input elements // this will disregard keypresses targeting body (e.g. tabbing // through elements, hotkeys, etc) if ( !tagName || (tagName !== 'INPUT' && tagName !== 'TEXTAREA' && !target.isContentEditable) ) return; // record first keypress in a series, but ignore subsequent // keypresses until debounce clears var timeout = self._keypressTimeout; if (!timeout) { self._breadcrumbEventHandler('input')(evt); } clearTimeout(timeout); self._keypressTimeout = setTimeout(function() { self._keypressTimeout = null; }, debounceDuration); }; }, /** * Captures a breadcrumb of type "navigation", normalizing input URLs * @param to the originating URL * @param from the target URL * @private */ _captureUrlChange: function(from, to) { var parsedLoc = parseUrl(this._location.href); var parsedTo = parseUrl(to); var parsedFrom = parseUrl(from); // because onpopstate only tells you the "new" (to) value of location.href, and // not the previous (from) value, we need to track the value of the current URL // state ourselves this._lastHref = to; // Use only the path component of the URL if the URL matches the current // document (almost all the time when using pushState) if (parsedLoc.protocol === parsedTo.protocol && parsedLoc.host === parsedTo.host) to = parsedTo.relative; if (parsedLoc.protocol === parsedFrom.protocol && parsedLoc.host === parsedFrom.host) from = parsedFrom.relative; this.captureBreadcrumb({ category: 'navigation', data: { to: to, from: from } }); }, _patchFunctionToString: function() { var self = this; self._originalFunctionToString = Function.prototype.toString; // eslint-disable-next-line no-extend-native Function.prototype.toString = function() { if (typeof this === 'function' && this.__raven__) { return self._originalFunctionToString.apply(this.__orig__, arguments); } return self._originalFunctionToString.apply(this, arguments); }; }, _unpatchFunctionToString: function() { if (this._originalFunctionToString) { // eslint-disable-next-line no-extend-native Function.prototype.toString = this._originalFunctionToString; } }, /** * Wrap timer functions and event targets to catch errors and provide * better metadata. */ _instrumentTryCatch: function() { var self = this; var wrappedBuiltIns = self._wrappedBuiltIns; function wrapTimeFn(orig) { return function(fn, t) { // preserve arity // Make a copy of the arguments to prevent deoptimization // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments var args = new Array(arguments.length); for (var i = 0; i < args.length; ++i) { args = arguments; } var originalCallback = args[0]; if (isFunction(originalCallback)) { args[0] = self.wrap(originalCallback); } // IE < 9 doesn't support .call/.apply on setInterval/setTimeout, but it // also supports only two arguments and doesn't care what this is, so we // can just call the original function directly. if (orig.apply) { return orig.apply(this, args); } else { return orig(args[0], args[1]); } }; } var autoBreadcrumbs = this._globalOptions.autoBreadcrumbs; function wrapEventTarget(global) { var proto = _window[global] && _window[global].prototype; if (proto && proto.hasOwnProperty && proto.hasOwnProperty('addEventListener')) { fill( proto, 'addEventListener', function(orig) { return function(evtName, fn, capture, secure) { // preserve arity try { if (fn && fn.handleEvent) { fn.handleEvent = self.wrap(fn.handleEvent); } } catch (err) { // can sometimes get 'Permission denied to access property "handle Event' } // More breadcrumb DOM capture ... done here and not in `_instrumentBreadcrumbs` // so that we don't have more than one wrapper function var before, clickHandler, keypressHandler; if ( autoBreadcrumbs && autoBreadcrumbs.dom && (global === 'EventTarget' || global === 'Node') ) { // NOTE: generating multiple handlers per addEventListener invocation, should // revisit and verify we can just use one (almost certainly) clickHandler = self._breadcrumbEventHandler('click'); keypressHandler = self._keypressEventHandler(); before = function(evt) { // need to intercept every DOM event in `before` argument, in case that // same wrapped method is re-used for different events (e.g. mousemove THEN click) // see #724 if (!evt) return; var eventType; try { eventType = evt.type; } catch (e) { // just accessing event properties can throw an exception in some rare circumstances // see: https://github.com/getsentry/raven-js/issues/838 return; } if (eventType === 'click') return clickHandler(evt); else if (eventType === 'keypress') return keypressHandler(evt); }; } return orig.call( this, evtName, self.wrap(fn, undefined, before), capture, secure ); }; }, wrappedBuiltIns ); fill( proto, 'removeEventListener', function(orig) { return function(evt, fn, capture, secure) { try { fn = fn && (fn.__raven_wrapper__ ? fn.__raven_wrapper__ : fn); } catch (e) { // ignore, accessing __raven_wrapper__ will throw in some Selenium environments } return orig.call(this, evt, fn, capture, secure); }; }, wrappedBuiltIns ); } } fill(_window, 'setTimeout', wrapTimeFn, wrappedBuiltIns); fill(_window, 'setInterval', wrapTimeFn, wrappedBuiltIns); if (_window.requestAnimationFrame) { fill( _window, 'requestAnimationFrame', function(orig) { return function(cb) { return orig(self.wrap(cb)); }; }, wrappedBuiltIns ); } // event targets borrowed from bugsnag-js: // https://github.com/bugsnag/bugsnag-js/blob/master/src/bugsnag.js#L666 var eventTargets = [ 'EventTarget', 'Window', 'Node', 'ApplicationCache', 'AudioTrackList', 'ChannelMergerNode', 'CryptoOperation', 'EventSource', 'FileReader', 'HTMLUnknownElement', 'IDBDatabase', 'IDBRequest', 'IDBTransaction', 'KeyOperation', 'MediaController', 'MessagePort', 'ModalWindow', 'Notification', 'SVGElementInstance', 'Screen', 'TextTrack', 'TextTrackCue', 'TextTrackList', 'WebSocket', 'WebSocketWorker', 'Worker', 'XMLHttpRequest', 'XMLHttpRequestEventTarget', 'XMLHttpRequestUpload' ]; for (var i = 0; i < eventTargets.length; i++) { wrapEventTarget(eventTargets); } }, /** * Instrument browser built-ins w/ breadcrumb capturing * - XMLHttpRequests * - DOM interactions (click/typing) * - window.location changes * - console * * Can be disabled or individually configured via the `autoBreadcrumbs` config option */ _instrumentBreadcrumbs: function() { var self = this; var autoBreadcrumbs = this._globalOptions.autoBreadcrumbs; var wrappedBuiltIns = self._wrappedBuiltIns; function wrapProp(prop, xhr) { if (prop in xhr && isFunction(xhr[prop])) { fill(xhr, prop, function(orig) { return self.wrap(orig); }); // intentionally don't track filled methods on XHR instances } } if (autoBreadcrumbs.xhr && 'XMLHttpRequest' in _window) { var xhrproto = XMLHttpRequest.prototype; fill( xhrproto, 'open', function(origOpen) { return function(method, url) { // preserve arity // if Sentry key appears in URL, don't capture if (isString(url) && url.indexOf(self._globalKey) === -1) { this.__raven_xhr = { method: method, url: url, status_code: null }; } return origOpen.apply(this, arguments); }; }, wrappedBuiltIns ); fill( xhrproto, 'send', function(origSend) { return function() { // preserve arity var xhr = this; function onreadystatechangeHandler() { if (xhr.__raven_xhr && xhr.readyState === 4) { try { // touching statusCode in some platforms throws // an exception xhr.__raven_xhr.status_code = xhr.status; } catch (e) { /* do nothing */ } self.captureBreadcrumb({ type: 'http', category: 'xhr', data: xhr.__raven_xhr }); } } var props = ['onload', 'onerror', 'onprogress']; for (var j = 0; j < props.length; j++) { wrapProp(props[j], xhr); } if ('onreadystatechange' in xhr && isFunction(xhr.onreadystatechange)) { fill( xhr, 'onreadystatechange', function(orig) { return self.wrap(orig, undefined, onreadystatechangeHandler); } /* intentionally don't track this instrumentation */ ); } else { // if onreadystatechange wasn't actually set by the page on this xhr, we // are free to set our own and capture the breadcrumb xhr.onreadystatechange = onreadystatechangeHandler; } return origSend.apply(this, arguments); }; }, wrappedBuiltIns ); } if (autoBreadcrumbs.xhr && supportsFetch()) { fill( _window, 'fetch', function(origFetch) { return function() { // preserve arity // Make a copy of the arguments to prevent deoptimization // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments var args = new Array(arguments.length); for (var i = 0; i < args.length; ++i) { args = arguments; } var fetchInput = args[0]; var method = 'GET'; var url; if (typeof fetchInput === 'string') { url = fetchInput; } else if ('Request' in _window && fetchInput instanceof _window.Request) { url = fetchInput.url; if (fetchInput.method) { method = fetchInput.method; } } else { url = '' + fetchInput; } // if Sentry key appears in URL, don't capture, as it's our own request if (url.indexOf(self._globalKey) !== -1) { return origFetch.apply(this, args); } if (args[1] && args[1].method) { method = args[1].method; } var fetchData = { method: method, url: url, status_code: null }; return origFetch.apply(this, args).then(function(response) { fetchData.status_code = response.status; self.captureBreadcrumb({ type: 'http', category: 'fetch', data: fetchData }); return response; }); }; }, wrappedBuiltIns ); } // Capture breadcrumbs from any click that is unhandled / bubbled up all the way // to the document. Do this before we instrument addEventListener. if (autoBreadcrumbs.dom && this._hasDocument) { if (_document.addEventListener) { _document.addEventListener('click', self._breadcrumbEventHandler('click'), false); _document.addEventListener('keypress', self._keypressEventHandler(), false); } else { // IE8 Compatibility _document.attachEvent('onclick', self._breadcrumbEventHandler('click')); _document.attachEvent('onkeypress', self._keypressEventHandler()); } } // record navigation (URL) changes // NOTE: in Chrome App environment, touching history.pushState, *even inside // a try/catch block*, will cause Chrome to output an error to console.error // borrowed from: https://github.com/angular/angular.js/pull/13945/files var chrome = _window.chrome; var isChromePackagedApp = chrome && chrome.app && chrome.app.runtime; var hasPushAndReplaceState = !isChromePackagedApp && _window.history && history.pushState && history.replaceState; if (autoBreadcrumbs.location && hasPushAndReplaceState) { // TODO: remove onpopstate handler on uninstall() var oldOnPopState = _window.onpopstate; _window.onpopstate = function() { var currentHref = self._location.href; self._captureUrlChange(self._lastHref, currentHref); if (oldOnPopState) { return oldOnPopState.apply(this, arguments); } }; var historyReplacementFunction = function(origHistFunction) { // note history.pushState.length is 0; intentionally not declaring // params to preserve 0 arity return function(/* state, title, url */) { var url = arguments.length > 2 ? arguments[2] : undefined; // url argument is optional if (url) { // coerce to string (this is what pushState does) self._captureUrlChange(self._lastHref, url + ''); } return origHistFunction.apply(this, arguments); }; }; fill(history, 'pushState', historyReplacementFunction, wrappedBuiltIns); fill(history, 'replaceState', historyReplacementFunction, wrappedBuiltIns); } if (autoBreadcrumbs.console && 'console' in _window && console.log) { // console var consoleMethodCallback = function(msg, data) { self.captureBreadcrumb({ message: msg, level: data.level, category: 'console' }); }; each(['debug', 'info', 'warn', 'error', 'log'], function(_, level) { wrapConsoleMethod(console, level, consoleMethodCallback); }); } }, _restoreBuiltIns: function() { // restore any wrapped builtins var builtin; while (this._wrappedBuiltIns.length) { builtin = this._wrappedBuiltIns.shift(); var obj = builtin[0], name = builtin[1], orig = builtin[2]; obj[name] = orig; } }, _restoreConsole: function() { // eslint-disable-next-line guard-for-in for (var method in this._originalConsoleMethods) { this._originalConsole[method] = this._originalConsoleMethods[method]; } }, _drainPlugins: function() { var self = this; // FIX ME TODO each(this._plugins, function(_, plugin) { var installer = plugin[0]; var args = plugin[1]; installer.apply(self, [self].concat(args)); }); }, _parseDSN: function(str) { var m = dsnPattern.exec(str), dsn = {}, i = 7; try { while (i--) dsn[dsnKeys] = m || ''; } catch (e) { throw new RavenConfigError('Invalid DSN: ' + str); } if (dsn.pass && !this._globalOptions.allowSecretKey) { throw new RavenConfigError( 'Do not specify your secret key in the DSN. See: http://bit.ly/raven-secret-key' ); } return dsn; }, _getGlobalServer: function(uri) { // assemble the endpoint from the uri pieces var globalServer = '//' + uri.host + (uri.port ? ':' + uri.port : ''); if (uri.protocol) { globalServer = uri.protocol + ':' + globalServer; } return globalServer; }, _handleOnErrorStackInfo: function() { // if we are intentionally ignoring errors via onerror, bail out if (!this._ignoreOnError) { this._handleStackInfo.apply(this, arguments); } }, _handleStackInfo: function(stackInfo, options) { var frames = this._prepareFrames(stackInfo, options); this._triggerEvent('handle', { stackInfo: stackInfo, options: options }); this._processException( stackInfo.name, stackInfo.message, stackInfo.url, stackInfo.lineno, frames, options ); }, _prepareFrames: function(stackInfo, options) { var self = this; var frames = []; if (stackInfo.stack && stackInfo.stack.length) { each(stackInfo.stack, function(i, stack) { var frame = self._normalizeFrame(stack, stackInfo.url); if (frame) { frames.push(frame); } }); // e.g. frames captured via captureMessage throw if (options && options.trimHeadFrames) { for (var j = 0; j < options.trimHeadFrames && j < frames.length; j++) { frames[j].in_app = false; } } } frames = frames.slice(0, this._globalOptions.stackTraceLimit); return frames; }, _normalizeFrame: function(frame, stackInfoUrl) { // normalize the frames data var normalized = { filename: frame.url, lineno: frame.line, colno: frame.column, function: frame.func || '?' }; // Case when we don't have any information about the error // E.g. throwing a string or raw object, instead of an `Error` in Firefox // Generating synthetic error doesn't add any value here // // We should probably somehow let a user know that they should fix their code if (!frame.url) { normalized.filename = stackInfoUrl; // fallback to whole stacks url from onerror handler } normalized.in_app = !// determine if an exception came from outside of our app // first we check the global includePaths list. ( (!!this._globalOptions.includePaths.test && !this._globalOptions.includePaths.test(normalized.filename)) || // Now we check for fun, if the function name is Raven or TraceKit /(Raven|TraceKit)\./.test(normalized['function']) || // finally, we do a last ditch effort and check for raven.min.js /raven\.(min\.)?js$/.test(normalized.filename) ); return normalized; }, _processException: function(type, message, fileurl, lineno, frames, options) { var prefixedMessage = (type ? type + ': ' : '') + (message || ''); if ( !!this._globalOptions.ignoreErrors.test && (this._globalOptions.ignoreErrors.test(message) || this._globalOptions.ignoreErrors.test(prefixedMessage)) ) { return; } var stacktrace; if (frames && frames.length) { fileurl = frames[0].filename || fileurl; // Sentry expects frames oldest to newest // and JS sends them as newest to oldest frames.reverse(); stacktrace = {frames: frames}; } else if (fileurl) { stacktrace = { frames: [ { filename: fileurl, lineno: lineno, in_app: true } ] }; } if ( !!this._globalOptions.ignoreUrls.test && this._globalOptions.ignoreUrls.test(fileurl) ) { return; } if ( !!this._globalOptions.whitelistUrls.test && !this._globalOptions.whitelistUrls.test(fileurl) ) { return; } var data = objectMerge( { // sentry.interfaces.Exception exception: { values: [ { type: type, value: message, stacktrace: stacktrace } ] }, culprit: fileurl }, options ); // Fire away! this._send(data); }, _trimPacket: function(data) { // For now, we only want to truncate the two different messages // but this could/should be expanded to just trim everything var max = this._globalOptions.maxMessageLength; if (data.message) { data.message = truncate(data.message, max); } if (data.exception) { var exception = data.exception.values[0]; exception.value = truncate(exception.value, max); } var request = data.request; if (request) { if (request.url) { request.url = truncate(request.url, this._globalOptions.maxUrlLength); } if (request.Referer) { request.Referer = truncate(request.Referer, this._globalOptions.maxUrlLength); } } if (data.breadcrumbs && data.breadcrumbs.values) this._trimBreadcrumbs(data.breadcrumbs); return data; }, /** * Truncate breadcrumb values (right now just URLs) */ _trimBreadcrumbs: function(breadcrumbs) { // known breadcrumb properties with urls // TODO: also consider arbitrary prop values that start with (https?)?:// var urlProps = ['to', 'from', 'url'], urlProp, crumb, data; for (var i = 0; i < breadcrumbs.values.length; ++i) { crumb = breadcrumbs.values; if ( !crumb.hasOwnProperty('data') || !isObject(crumb.data) || objectFrozen(crumb.data) ) continue; data = objectMerge({}, crumb.data); for (var j = 0; j < urlProps.length; ++j) { urlProp = urlProps[j]; if (data.hasOwnProperty(urlProp) && data[urlProp]) { data[urlProp] = truncate(data[urlProp], this._globalOptions.maxUrlLength); } } breadcrumbs.values.data = data; } }, _getHttpData: function() { if (!this._hasNavigator && !this._hasDocument) return; var httpData = {}; if (this._hasNavigator && _navigator.userAgent) { httpData.headers = { 'User-Agent': navigator.userAgent }; } // Check in `window` instead of `document`, as we may be in ServiceWorker environment if (_window.location && _window.location.href) { httpData.url = _window.location.href; } if (this._hasDocument && _document.referrer) { if (!httpData.headers) httpData.headers = {}; httpData.headers.Referer = _document.referrer; } return httpData; }, _resetBackoff: function() { this._backoffDuration = 0; this._backoffStart = null; }, _shouldBackoff: function() { return this._backoffDuration && now() - this._backoffStart < this._backoffDuration; }, /** * Returns true if the in-process data payload matches the signature * of the previously-sent data * * NOTE: This has to be done at this level because TraceKit can generate * data from window.onerror WITHOUT an exception object (IE8, IE9, * other old browsers). This can take the form of an "exception" * data object with a single frame (derived from the onerror args). */ _isRepeatData: function(current) { var last = this._lastData; if ( !last || current.message !== last.message || // defined for captureMessage current.culprit !== last.culprit // defined for captureException/onerror ) return false; // Stacktrace interface (i.e. from captureMessage) if (current.stacktrace || last.stacktrace) { return isSameStacktrace(current.stacktrace, last.stacktrace); } else if (current.exception || last.exception) { // Exception interface (i.e. from captureException/onerror) return isSameException(current.exception, last.exception); } return true; }, _setBackoffState: function(request) { // If we are already in a backoff state, don't change anything if (this._shouldBackoff()) { return; } var status = request.status; // 400 - project_id doesn't exist or some other fatal // 401 - invalid/revoked dsn // 429 - too many requests if (!(status === 400 || status === 401 || status === 429)) return; var retry; try { // If Retry-After is not in Access-Control-Expose-Headers, most // browsers will throw an exception trying to access it if (supportsFetch()) { retry = request.headers.get('Retry-After'); } else { retry = request.getResponseHeader('Retry-After'); } // Retry-After is returned in seconds retry = parseInt(retry, 10) * 1000; } catch (e) { /* eslint no-empty:0 */ } this._backoffDuration = retry ? // If Sentry server returned a Retry-After value, use it retry : // Otherwise, double the last backoff duration (starts at 1 sec) this._backoffDuration * 2 || 1000; this._backoffStart = now(); }, _send: function(data) { var globalOptions = this._globalOptions; var baseData = { project: this._globalProject, logger: globalOptions.logger, platform: 'javascript' }, httpData = this._getHttpData(); if (httpData) { baseData.request = httpData; } // HACK: delete `trimHeadFrames` to prevent from appearing in outbound payload if (data.trimHeadFrames) delete data.trimHeadFrames; data = objectMerge(baseData, data); // Merge in the tags and extra separately since objectMerge doesn't handle a deep merge data.tags = objectMerge(objectMerge({}, this._globalContext.tags), data.tags); data.extra = objectMerge(objectMerge({}, this._globalContext.extra), data.extra); // Send along our own collected metadata with extra data.extra['session:duration'] = now() - this._startTime; if (this._breadcrumbs && this._breadcrumbs.length > 0) { // intentionally make shallow copy so that additions // to breadcrumbs aren't accidentally sent in this request data.breadcrumbs = { values: [].slice.call(this._breadcrumbs, 0) }; } if (this._globalContext.user) { // sentry.interfaces.User data.user = this._globalContext.user; } // Include the environment if it's defined in globalOptions if (globalOptions.environment) data.environment = globalOptions.environment; // Include the release if it's defined in globalOptions if (globalOptions.release) data.release = globalOptions.release; // Include server_name if it's defined in globalOptions if (globalOptions.serverName) data.server_name = globalOptions.serverName; // Cleanup empty properties before sending them to the server Object.keys(data).forEach(function(key) { if (data[key] == null || data[key] === '' || isEmptyObject(data[key])) { delete data[key]; } }); if (isFunction(globalOptions.dataCallback)) { data = globalOptions.dataCallback(data) || data; } // Why?????????? if (!data || isEmptyObject(data)) { return; } // Check if the request should be filtered or not if ( isFunction(globalOptions.shouldSendCallback) && !globalOptions.shouldSendCallback(data) ) { return; } // Backoff state: Sentry server previously responded w/ an error (e.g. 429 - too many requests), // so drop requests until "cool-off" period has elapsed. if (this._shouldBackoff()) { this._logDebug('warn', 'Raven dropped error due to backoff: ', data); return; } if (typeof globalOptions.sampleRate === 'number') { if (Math.random() < globalOptions.sampleRate) { this._sendProcessedPayload(data); } } else { this._sendProcessedPayload(data); } }, _getUuid: function() { return uuid4(); }, _sendProcessedPayload: function(data, callback) { var self = this; var globalOptions = this._globalOptions; if (!this.isSetup()) return; // Try and clean up the packet before sending by truncating long values data = this._trimPacket(data); // ideally duplicate error testing should occur *before* dataCallback/shouldSendCallback, // but this would require copying an un-truncated copy of the data packet, which can be // arbitrarily deep (extra_data) -- could be worthwhile? will revisit if (!this._globalOptions.allowDuplicates && this._isRepeatData(data)) { this._logDebug('warn', 'Raven dropped repeat event: ', data); return; } // Send along an event_id if not explicitly passed. // This event_id can be used to reference the error within Sentry itself. // Set lastEventId after we know the error should actually be sent this._lastEventId = data.event_id || (data.event_id = this._getUuid()); // Store outbound payload after trim this._lastData = data; this._logDebug('debug', 'Raven about to send:', data); var auth = { sentry_version: '7', sentry_client: 'raven-js/' + this.VERSION, sentry_key: this._globalKey }; if (this._globalSecret) { auth.sentry_secret = this._globalSecret; } var exception = data.exception && data.exception.values[0]; // only capture 'sentry' breadcrumb is autoBreadcrumbs is truthy if ( this._globalOptions.autoBreadcrumbs && this._globalOptions.autoBreadcrumbs.sentry ) { this.captureBreadcrumb({ category: 'sentry', message: exception ? (exception.type ? exception.type + ': ' : '') + exception.value : data.message, event_id: data.event_id, level: data.level || 'error' // presume error unless specified }); } var url = this._globalEndpoint; (globalOptions.transport || this._makeRequest).call(this, { url: url, auth: auth, data: data, options: globalOptions, onSuccess: function success() { self._resetBackoff(); self._triggerEvent('success', { data: data, src: url }); callback && callback(); }, onError: function failure(error) { self._logDebug('error', 'Raven transport failed to send: ', error); if (error.request) { self._setBackoffState(error.request); } self._triggerEvent('failure', { data: data, src: url }); error = error || new Error('Raven send failed (no additional details provided)'); callback && callback(error); } }); }, _makeRequest: function(opts) { // Auth is intentionally sent as part of query string (NOT as custom HTTP header) to avoid preflight CORS requests var url = opts.url + '?' + urlencode(opts.auth); var evaluatedHeaders = null; var evaluatedFetchParameters = {}; if (opts.options.headers) { evaluatedHeaders = this._evaluateHash(opts.options.headers); } if (opts.options.fetchParameters) { evaluatedFetchParameters = this._evaluateHash(opts.options.fetchParameters); } if (supportsFetch()) { evaluatedFetchParameters.body = stringify(opts.data); var defaultFetchOptions = objectMerge({}, this._fetchDefaults); var fetchOptions = objectMerge(defaultFetchOptions, evaluatedFetchParameters); if (evaluatedHeaders) { fetchOptions.headers = evaluatedHeaders; } return _window .fetch(url, fetchOptions) .then(function(response) { if (response.ok) { opts.onSuccess && opts.onSuccess(); } else { var error = new Error('Sentry error code: ' + response.status); // It's called request only to keep compatibility with XHR interface // and not add more redundant checks in setBackoffState method error.request = response; opts.onError && opts.onError(error); } }) ['catch'](function() { opts.onError && opts.onError(new Error('Sentry error code: network unavailable')); }); } var request = _window.XMLHttpRequest && new _window.XMLHttpRequest(); if (!request) return; // if browser doesn't support CORS (e.g. IE7), we are out of luck var hasCORS = 'withCredentials' in request || typeof XDomainRequest !== 'undefined'; if (!hasCORS) return; if ('withCredentials' in request) { request.onreadystatechange = function() { if (request.readyState !== 4) { return; } else if (request.status === 200) { opts.onSuccess && opts.onSuccess(); } else if (opts.onError) { var err = new Error('Sentry error code: ' + request.status); err.request = request; opts.onError(err); } }; } else { request = new XDomainRequest(); // xdomainrequest cannot go http -> https (or vice versa), // so always use protocol relative url = url.replace(/^https?:/, ''); // onreadystatechange not supported by XDomainRequest if (opts.onSuccess) { request.onload = opts.onSuccess; } if (opts.onError) { request.onerror = function() { var err = new Error('Sentry error code: XDomainRequest'); err.request = request; opts.onError(err); }; } } request.open('POST', url); if (evaluatedHeaders) { each(evaluatedHeaders, function(key, value) { request.setRequestHeader(key, value); }); } request.send(stringify(opts.data)); }, _evaluateHash: function(hash) { var evaluated = {}; for (var key in hash) { if (hash.hasOwnProperty(key)) { var value = hash[key]; evaluated[key] = typeof value === 'function' ? value() : value; } } return evaluated; }, _logDebug: function(level) { if (this._originalConsoleMethods[level] && this.debug) { // In IE<10 console methods do not have their own 'apply' method Function.prototype.apply.call( this._originalConsoleMethods[level], this._originalConsole, [].slice.call(arguments, 1) ); } }, _mergeContext: function(key, context) { if (isUndefined(context)) { delete this._globalContext[key]; } else { this._globalContext[key] = objectMerge(this._globalContext[key] || {}, context); } } }; // Deprecations Raven.prototype.setUser = Raven.prototype.setUserContext; Raven.prototype.setReleaseContext = Raven.prototype.setRelease; module.exports = Raven; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"1":1,"2":2,"5":5,"6":6,"7":7,"8":8}],4:[function(_dereq_,module,exports){ (function (global){ /** * Enforces a single instance of the Raven client, and the * main entry point for Raven. If you are a consumer of the * Raven library, you SHOULD load this file (vs raven.js). **/ var RavenConstructor = _dereq_(3); // This is to be defensive in environments where window does not exist (see https://github.com/getsentry/raven-js/pull/785) var _window = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; var _Raven = _window.Raven; var Raven = new RavenConstructor(); /* * Allow multiple versions of Raven to be installed. * Strip Raven from the global context and returns the instance. * * @return {Raven} */ Raven.noConflict = function() { _window.Raven = _Raven; return Raven; }; Raven.afterLoad(); module.exports = Raven; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"3":3}],5:[function(_dereq_,module,exports){ (function (global){ var stringify = _dereq_(7); var _window = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; function isObject(what) { return typeof what === 'object' && what !== null; } // Yanked from https://git.io/vS8DV re-used under CC0 // with some tiny modifications function isError(value) { switch ({}.toString.call(value)) { case '[object Error]': return true; case '[object Exception]': return true; case '[object DOMException]': return true; default: return value instanceof Error; } } function isErrorEvent(value) { return supportsErrorEvent() && {}.toString.call(value) === '[object ErrorEvent]'; } function isUndefined(what) { return what === void 0; } function isFunction(what) { return typeof what === 'function'; } function isPlainObject(what) { return Object.prototype.toString.call(what) === '[object Object]'; } function isString(what) { return Object.prototype.toString.call(what) === '[object String]'; } function isArray(what) { return Object.prototype.toString.call(what) === '[object Array]'; } function isEmptyObject(what) { if (!isPlainObject(what)) return false; for (var _ in what) { if (what.hasOwnProperty(_)) { return false; } } return true; } function supportsErrorEvent() { try { new ErrorEvent(''); // eslint-disable-line no-new return true; } catch (e) { return false; } } function supportsFetch() { if (!('fetch' in _window)) return false; try { new Headers(); // eslint-disable-line no-new new Request(''); // eslint-disable-line no-new new Response(); // eslint-disable-line no-new return true; } catch (e) { return false; } } // Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default // https://caniuse.com/#feat=referrer-policy // It doesn't. And it throw exception instead of ignoring this parameter... // REF: https://github.com/getsentry/raven-js/issues/1233 function supportsReferrerPolicy() { if (!supportsFetch()) return false; try { // eslint-disable-next-line no-new new Request('pickleRick', { referrerPolicy: 'origin' }); return true; } catch (e) { return false; } } function supportsPromiseRejectionEvent() { return typeof PromiseRejectionEvent === 'function'; } function wrappedCallback(callback) { function dataCallback(data, original) { var normalizedData = callback(data) || data; if (original) { return original(normalizedData) || normalizedData; } return normalizedData; } return dataCallback; } function each(obj, callback) { var i, j; if (isUndefined(obj.length)) { for (i in obj) { if (hasKey(obj, i)) { callback.call(null, i, obj); } } } else { j = obj.length; if (j) { for (i = 0; i < j; i++) { callback.call(null, i, obj); } } } } function objectMerge(obj1, obj2) { if (!obj2) { return obj1; } each(obj2, function(key, value) { obj1[key] = value; }); return obj1; } /** * This function is only used for react-native. * react-native freezes object that have already been sent over the * js bridge. We need this function in order to check if the object is frozen. * So it's ok that objectFrozen returns false if Object.isFrozen is not * supported because it's not relevant for other "platforms". See related issue: * https://github.com/getsentry/react-native-sentry/issues/57 */ function objectFrozen(obj) { if (!Object.isFrozen) { return false; } return Object.isFrozen(obj); } function truncate(str, max) { return !max || str.length <= max ? str : str.substr(0, max) + '\u2026'; } /** * hasKey, a better form of hasOwnProperty * Example: hasKey(MainHostObject, property) === true/false * * @param {Object} host object to check property * @param {string} key to check */ function hasKey(object, key) { return Object.prototype.hasOwnProperty.call(object, key); } function joinRegExp(patterns) { // Combine an array of regular expressions and strings into one large regexp // Be mad. var sources = [], i = 0, len = patterns.length, pattern; for (; i < len; i++) { pattern = patterns; if (isString(pattern)) { // If it's a string, we need to escape it // Taken from: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions sources.push(pattern.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1')); } else if (pattern && pattern.source) { // If it's a regexp already, we want to extract the source sources.push(pattern.source); } // Intentionally skip other cases } return new RegExp(sources.join('|'), 'i'); } function urlencode(o) { var pairs = []; each(o, function(key, value) { pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(value)); }); return pairs.join('&'); } // borrowed from https://tools.ietf.org/html/rfc3986#appendix-B // intentionally using regex and not <a/> href parsing trick because React Native and other // environments where DOM might not be available function parseUrl(url) { if (typeof url !== 'string') return {}; var match = url.match(/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/); // coerce to undefined values to empty string so we don't get 'undefined' var query = match[6] || ''; var fragment = match[8] || ''; return { protocol: match[2], host: match[4], path: match[5], relative: match[5] + query + fragment // everything minus origin }; } function uuid4() { var crypto = _window.crypto || _window.msCrypto; if (!isUndefined(crypto) && crypto.getRandomValues) { // Use window.crypto API if available // eslint-disable-next-line no-undef var arr = new Uint16Array(8); crypto.getRandomValues(arr); // set 4 in byte 7 arr[3] = (arr[3] & 0xfff) | 0x4000; // set 2 most significant bits of byte 9 to '10' arr[4] = (arr[4] & 0x3fff) | 0x8000; var pad = function(num) { var v = num.toString(16); while (v.length < 4) { v = '0' + v; } return v; }; return ( pad(arr[0]) + pad(arr[1]) + pad(arr[2]) + pad(arr[3]) + pad(arr[4]) + pad(arr[5]) + pad(arr[6]) + pad(arr[7]) ); } else { // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523 return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = (Math.random() * 16) | 0, v = c === 'x' ? r : (r & 0x3) | 0x8; return v.toString(16); }); } } /** * Given a child DOM element, returns a query-selector statement describing that * and its ancestors * e.g. [HTMLElement] => body > div > input#foo.btn[name=baz] * @param elem * @returns {string} */ function htmlTreeAsString(elem) { /* eslint no-extra-parens:0*/ var MAX_TRAVERSE_HEIGHT = 5, MAX_OUTPUT_LEN = 80, out = [], height = 0, len = 0, separator = ' > ', sepLength = separator.length, nextStr; while (elem && height++ < MAX_TRAVERSE_HEIGHT) { nextStr = htmlElementAsString(elem); // bail out if // - nextStr is the 'html' element // - the length of the string that would be created exceeds MAX_OUTPUT_LEN // (ignore this limit if we are on the first iteration) if ( nextStr === 'html' || (height > 1 && len + out.length * sepLength + nextStr.length >= MAX_OUTPUT_LEN) ) { break; } out.push(nextStr); len += nextStr.length; elem = elem.parentNode; } return out.reverse().join(separator); } /** * Returns a simple, query-selector representation of a DOM element * e.g. [HTMLElement] => input#foo.btn[name=baz] * @param HTMLElement * @returns {string} */ function htmlElementAsString(elem) { var out = [], className, classes, key, attr, i; if (!elem || !elem.tagName) { return ''; } out.push(elem.tagName.toLowerCase()); if (elem.id) { out.push('#' + elem.id); } className = elem.className; if (className && isString(className)) { classes = className.split(/\s+/); for (i = 0; i < classes.length; i++) { out.push('.' + classes); } } var attrWhitelist = ['type', 'name', 'title', 'alt']; for (i = 0; i < attrWhitelist.length; i++) { key = attrWhitelist; attr = elem.getAttribute(key); if (attr) { out.push('[' + key + '="' + attr + '"]'); } } return out.join(''); } /** * Returns true if either a OR b is truthy, but not both */ function isOnlyOneTruthy(a, { return !!(!!a ^ !!b); } /** * Returns true if both parameters are undefined */ function isBothUndefined(a, { return isUndefined(a) && isUndefined(b); } /** * Returns true if the two input exception interfaces have the same content */ function isSameException(ex1, ex2) { if (isOnlyOneTruthy(ex1, ex2)) return false; ex1 = ex1.values[0]; ex2 = ex2.values[0]; if (ex1.type !== ex2.type || ex1.value !== ex2.value) return false; // in case both stacktraces are undefined, we can't decide so default to false if (isBothUndefined(ex1.stacktrace, ex2.stacktrace)) return false; return isSameStacktrace(ex1.stacktrace, ex2.stacktrace); } /** * Returns true if the two input stack trace interfaces have the same content */ function isSameStacktrace(stack1, stack2) { if (isOnlyOneTruthy(stack1, stack2)) return false; var frames1 = stack1.frames; var frames2 = stack2.frames; // Exit early if frame count differs if (frames1.length !== frames2.length) return false; // Iterate through every frame; bail out if anything differs var a, b; for (var i = 0; i < frames1.length; i++) { a = frames1; b = frames2; if ( a.filename !== b.filename || a.lineno !== b.lineno || a.colno !== b.colno || a['function'] !== b['function'] ) return false; } return true; } /** * Polyfill a method * @param obj object e.g. `document` * @param name method name present on object e.g. `addEventListener` * @param replacement replacement function * @param track {optional} record instrumentation to an array */ function fill(obj, name, replacement, track) { var orig = obj[name]; obj[name] = replacement(orig); obj[name].__raven__ = true; obj[name].__orig__ = orig; if (track) { track.push([obj, name, orig]); } } /** * Join values in array * @param input array of values to be joined together * @param delimiter string to be placed in-between values * @returns {string} */ function safeJoin(input, delimiter) { if (!isArray(input)) return ''; var output = []; for (var i = 0; i < input.length; i++) { try { output.push(String(input)); } catch (e) { output.push('[value cannot be serialized]'); } } return output.join(delimiter); } // Default Node.js REPL depth var MAX_SERIALIZE_EXCEPTION_DEPTH = 3; // 50kB, as 100kB is max payload size, so half sounds reasonable var MAX_SERIALIZE_EXCEPTION_SIZE = 50 * 1024; var MAX_SERIALIZE_KEYS_LENGTH = 40; function utf8Length(value) { return ~-encodeURI(value).split(/%..|./).length; } function jsonSize(value) { return utf8Length(JSON.stringify(value)); } function serializeValue(value) { var maxLength = 40; if (typeof value === 'string') { return value.length <= maxLength ? value : value.substr(0, maxLength - 1) + '\u2026'; } else if ( typeof value === 'number' || typeof value === 'boolean' || typeof value === 'undefined' ) { return value; } var type = Object.prototype.toString.call(value); // Node.js REPL notation if (type === '[object Object]') return '[Object]'; if (type === '[object Array]') return '[Array]'; if (type === '[object Function]') return value.name ? '[Function: ' + value.name + ']' : '[Function]'; return value; } function serializeObject(value, depth) { if (depth === 0) return serializeValue(value); if (isPlainObject(value)) { return Object.keys(value).reduce(function(acc, key) { acc[key] = serializeObject(value[key], depth - 1); return acc; }, {}); } else if (Array.isArray(value)) { return value.map(function(val) { return serializeObject(val, depth - 1); }); } return serializeValue(value); } function serializeException(ex, depth, maxSize) { if (!isPlainObject(ex)) return ex; depth = typeof depth !== 'number' ? MAX_SERIALIZE_EXCEPTION_DEPTH : depth; maxSize = typeof depth !== 'number' ? MAX_SERIALIZE_EXCEPTION_SIZE : maxSize; var serialized = serializeObject(ex, depth); if (jsonSize(stringify(serialized)) > maxSize) { return serializeException(ex, depth - 1); } return serialized; } function serializeKeysForMessage(keys, maxLength) { if (typeof keys === 'number' || typeof keys === 'string') return keys.toString(); if (!Array.isArray(keys)) return ''; keys = keys.filter(function(key) { return typeof key === 'string'; }); if (keys.length === 0) return '[object has no keys]'; maxLength = typeof maxLength !== 'number' ? MAX_SERIALIZE_KEYS_LENGTH : maxLength; if (keys[0].length >= maxLength) return keys[0]; for (var usedKeys = keys.length; usedKeys > 0; usedKeys--) { var serialized = keys.slice(0, usedKeys).join(', '); if (serialized.length > maxLength) continue; if (usedKeys === keys.length) return serialized; return serialized + '\u2026'; } return ''; } module.exports = { isObject: isObject, isError: isError, isErrorEvent: isErrorEvent, isUndefined: isUndefined, isFunction: isFunction, isPlainObject: isPlainObject, isString: isString, isArray: isArray, isEmptyObject: isEmptyObject, supportsErrorEvent: supportsErrorEvent, supportsFetch: supportsFetch, supportsReferrerPolicy: supportsReferrerPolicy, supportsPromiseRejectionEvent: supportsPromiseRejectionEvent, wrappedCallback: wrappedCallback, each: each, objectMerge: objectMerge, truncate: truncate, objectFrozen: objectFrozen, hasKey: hasKey, joinRegExp: joinRegExp, urlencode: urlencode, uuid4: uuid4, htmlTreeAsString: htmlTreeAsString, htmlElementAsString: htmlElementAsString, isSameException: isSameException, isSameStacktrace: isSameStacktrace, parseUrl: parseUrl, fill: fill, safeJoin: safeJoin, serializeException: serializeException, serializeKeysForMessage: serializeKeysForMessage }; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"7":7}],6:[function(_dereq_,module,exports){ (function (global){ var utils = _dereq_(5); /* TraceKit - Cross brower stack traces This was originally forked from github.com/occ/TraceKit, but has since been largely re-written and is now maintained as part of raven-js. Tests for this are in test/vendor. MIT license */ var TraceKit = { collectWindowErrors: true, debug: false }; // This is to be defensive in environments where window does not exist (see https://github.com/getsentry/raven-js/pull/785) var _window = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; // global reference to slice var _slice = [].slice; var UNKNOWN_FUNCTION = '?'; // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Error_types var ERROR_TYPES_RE = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/; function getLocationHref() { if (typeof document === 'undefined' || document.location == null) return ''; return document.location.href; } /** * TraceKit.report: cross-browser processing of unhandled exceptions * * Syntax: * TraceKit.report.subscribe(function(stackInfo) { ... }) * TraceKit.report.unsubscribe(function(stackInfo) { ... }) * TraceKit.report(exception) * try { ...code... } catch(ex) { TraceKit.report(ex); } * * Supports: * - Firefox: full stack trace with line numbers, plus column number * on top frame; column number is not guaranteed * - Opera: full stack trace with line and column numbers * - Chrome: full stack trace with line and column numbers * - Safari: line and column number for the top frame only; some frames * may be missing, and column number is not guaranteed * - IE: line and column number for the top frame only; some frames * may be missing, and column number is not guaranteed * * In theory, TraceKit should work on all of the following versions: * - IE5.5+ (only 8.0 tested) * - Firefox 0.9+ (only 3.5+ tested) * - Opera 7+ (only 10.50 tested; versions 9 and earlier may require * Exceptions Have Stacktrace to be enabled in opera:config) * - Safari 3+ (only 4+ tested) * - Chrome 1+ (only 5+ tested) * - Konqueror 3.5+ (untested) * * Requires TraceKit.computeStackTrace. * * Tries to catch all unhandled exceptions and report them to the * subscribed handlers. Please note that TraceKit.report will rethrow the * exception. This is REQUIRED in order to get a useful stack trace in IE. * If the exception does not reach the top of the browser, you will only * get a stack trace from the point where TraceKit.report was called. * * Handlers receive a stackInfo object as described in the * TraceKit.computeStackTrace docs. */ TraceKit.report = (function reportModuleWrapper() { var handlers = [], lastArgs = null, lastException = null, lastExceptionStack = null; /** * Add a crash handler. * @param {Function} handler */ function subscribe(handler) { installGlobalHandler(); handlers.push(handler); } /** * Remove a crash handler. * @param {Function} handler */ function unsubscribe(handler) { for (var i = handlers.length - 1; i >= 0; --i) { if (handlers === handler) { handlers.splice(i, 1); } } } /** * Remove all crash handlers. */ function unsubscribeAll() { uninstallGlobalHandler(); handlers = []; } /** * Dispatch stack information to all handlers. * @param {Object.<string, *>} stack */ function notifyHandlers(stack, isWindowError) { var exception = null; if (isWindowError && !TraceKit.collectWindowErrors) { return; } for (var i in handlers) { if (handlers.hasOwnProperty(i)) { try { handlers.apply(null, [stack].concat(_slice.call(arguments, 2))); } catch (inner) { exception = inner; } } } if (exception) { throw exception; } } var _oldOnerrorHandler, _onErrorHandlerInstalled; /** * Ensures all global unhandled exceptions are recorded. * Supported by Gecko and IE. * @param {string} msg Error message. * @param {string} url URL of script that generated the exception. * @param {(number|string)} lineNo The line number at which the error * occurred. * @param {?(number|string)} colNo The column number at which the error * occurred. * @param {?Error} ex The actual Error object. */ function traceKitWindowOnError(msg, url, lineNo, colNo, ex) { var stack = null; // If 'ex' is ErrorEvent, get real Error from inside var exception = utils.isErrorEvent(ex) ? ex.error : ex; // If 'msg' is ErrorEvent, get real message from inside var message = utils.isErrorEvent(msg) ? msg.message : msg; if (lastExceptionStack) { TraceKit.computeStackTrace.augmentStackTraceWithInitialElement( lastExceptionStack, url, lineNo, message ); processLastException(); } else if (exception && utils.isError(exception)) { // non-string `exception` arg; attempt to extract stack trace // New chrome and blink send along a real error object // Let's just report that like a normal error. // See: https://mikewest.org/2013/08/debugging-runtime-errors-with-window-onerror stack = TraceKit.computeStackTrace(exception); notifyHandlers(stack, true); } else { var location = { url: url, line: lineNo, column: colNo }; var name = undefined; var groups; if ({}.toString.call(message) === '[object String]') { var groups = message.match(ERROR_TYPES_RE); if (groups) { name = groups[1]; message = groups[2]; } } location.func = UNKNOWN_FUNCTION; stack = { name: name, message: message, url: getLocationHref(), stack: [location] }; notifyHandlers(stack, true); } if (_oldOnerrorHandler) { return _oldOnerrorHandler.apply(this, arguments); } return false; } function installGlobalHandler() { if (_onErrorHandlerInstalled) { return; } _oldOnerrorHandler = _window.onerror; _window.onerror = traceKitWindowOnError; _onErrorHandlerInstalled = true; } function uninstallGlobalHandler() { if (!_onErrorHandlerInstalled) { return; } _window.onerror = _oldOnerrorHandler; _onErrorHandlerInstalled = false; _oldOnerrorHandler = undefined; } function processLastException() { var _lastExceptionStack = lastExceptionStack, _lastArgs = lastArgs; lastArgs = null; lastExceptionStack = null; lastException = null; notifyHandlers.apply(null, [_lastExceptionStack, false].concat(_lastArgs)); } /** * Reports an unhandled Error to TraceKit. * @param {Error} ex * @param {?boolean} rethrow If false, do not re-throw the exception. * Only used for window.onerror to not cause an infinite loop of * rethrowing. */ function report(ex, rethrow) { var args = _slice.call(arguments, 1); if (lastExceptionStack) { if (lastException === ex) { return; // already caught by an inner catch block, ignore } else { processLastException(); } } var stack = TraceKit.computeStackTrace(ex); lastExceptionStack = stack; lastException = ex; lastArgs = args; // If the stack trace is incomplete, wait for 2 seconds for // slow slow IE to see if onerror occurs or not before reporting // this exception; otherwise, we will end up with an incomplete // stack trace setTimeout(function() { if (lastException === ex) { processLastException(); } }, stack.incomplete ? 2000 : 0); if (rethrow !== false) { throw ex; // re-throw to propagate to the top level (and cause window.onerror) } } report.subscribe = subscribe; report.unsubscribe = unsubscribe; report.uninstall = unsubscribeAll; return report; })(); /** * TraceKit.computeStackTrace: cross-browser stack traces in JavaScript * * Syntax: * s = TraceKit.computeStackTrace(exception) // consider using TraceKit.report instead (see below) * Returns: * s.name - exception name * s.message - exception message * s.stack.url - JavaScript or HTML file URL * s.stack.func - function name, or empty for anonymous functions (if guessing did not work) * s.stack.args - arguments passed to the function, if known * s.stack.line - line number, if known * s.stack.column - column number, if known * * Supports: * - Firefox: full stack trace with line numbers and unreliable column * number on top frame * - Opera 10: full stack trace with line and column numbers * - Opera 9-: full stack trace with line numbers * - Chrome: full stack trace with line and column numbers * - Safari: line and column number for the topmost stacktrace element * only * - IE: no line numbers whatsoever * * Tries to guess names of anonymous functions by looking for assignments * in the source code. In IE and Safari, we have to guess source file names * by searching for function bodies inside all page scripts. This will not * work for scripts that are loaded cross-domain. * Here be dragons: some function names may be guessed incorrectly, and * duplicate functions may be mismatched. * * TraceKit.computeStackTrace should only be used for tracing purposes. * Logging of unhandled exceptions should be done with TraceKit.report, * which builds on top of TraceKit.computeStackTrace and provides better * IE support by utilizing the window.onerror event to retrieve information * about the top of the stack. * * Note: In IE and Safari, no stack trace is recorded on the Error object, * so computeStackTrace instead walks its *own* chain of callers. * This means that: * * in Safari, some methods may be missing from the stack trace; * * in IE, the topmost function in the stack trace will always be the * caller of computeStackTrace. * * This is okay for tracing (because you are likely to be calling * computeStackTrace from the function you want to be the topmost element * of the stack trace anyway), but not okay for logging unhandled * exceptions (because your catch block will likely be far away from the * inner function that actually caused the exception). * */ TraceKit.computeStackTrace = (function computeStackTraceWrapper() { // Contents of Exception in various browsers. // // SAFARI: // ex.message = Can't find variable: qq // ex.line = 59 // ex.sourceId = 580238192 // ex.sourceURL = http://... // ex.expressionBeginOffset = 96 // ex.expressionCaretOffset = 98 // ex.expressionEndOffset = 98 // ex.name = ReferenceError // // FIREFOX: // ex.message = qq is not defined // ex.fileName = http://... // ex.lineNumber = 59 // ex.columnNumber = 69 // ex.stack = ...stack trace... (see the example below) // ex.name = ReferenceError // // CHROME: // ex.message = qq is not defined // ex.name = ReferenceError // ex.type = not_defined // ex.arguments = ['aa'] // ex.stack = ...stack trace... // // INTERNET EXPLORER: // ex.message = ... // ex.name = ReferenceError // // OPERA: // ex.message = ...message... (see the example below) // ex.name = ReferenceError // ex.opera#sourceloc = 11 (pretty much useless, duplicates the info in ex.message) // ex.stacktrace = n/a; see 'opera:config#UserPrefs|Exceptions Have Stacktrace' /** * Computes stack trace information from the stack property. * Chrome and Gecko use this property. * @param {Error} ex * @return {?Object.<string, *>} Stack trace information. */ function computeStackTraceFromStackProp(ex) { if (typeof ex.stack === 'undefined' || !ex.stack) return; var chrome = /^\s*at (?:(.*?) ?\()?((?:file|https?|blob|chrome-extension|native|eval|webpack|<anonymous>|[a-z]:|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i; var winjs = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx(?:-web)|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i; // NOTE: blob urls are now supposed to always have an origin, therefore it's format // which is `blob:http://url/path/with-some-uuid`, is matched by `blob.*?:\/` as well var gecko = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|resource|moz-extension).*?:\/.*?|\[native code\]|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i; // Used to additionally parse URL/line/column from eval frames var geckoEval = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i; var chromeEval = /\((\S*)(?::(\d+))(?::(\d+))\)/; var lines = ex.stack.split('\n'); var stack = []; var submatch; var parts; var element; var reference = /^(.*) is undefined$/.exec(ex.message); for (var i = 0, j = lines.length; i < j; ++i) { if ((parts = chrome.exec(lines))) { var isNative = parts[2] && parts[2].indexOf('native') === 0; // start of line var isEval = parts[2] && parts[2].indexOf('eval') === 0; // start of line if (isEval && (submatch = chromeEval.exec(parts[2]))) { // throw out eval line/column and use top-most line/column number parts[2] = submatch[1]; // url parts[3] = submatch[2]; // line parts[4] = submatch[3]; // column } element = { url: !isNative ? parts[2] : null, func: parts[1] || UNKNOWN_FUNCTION, args: isNative ? [parts[2]] : [], line: parts[3] ? +parts[3] : null, column: parts[4] ? +parts[4] : null }; } else if ((parts = winjs.exec(lines))) { element = { url: parts[2], func: parts[1] || UNKNOWN_FUNCTION, args: [], line: +parts[3], column: parts[4] ? +parts[4] : null }; } else if ((parts = gecko.exec(lines))) { var isEval = parts[3] && parts[3].indexOf(' > eval') > -1; if (isEval && (submatch = geckoEval.exec(parts[3]))) { // throw out eval line/column and use top-most line number parts[3] = submatch[1]; parts[4] = submatch[2]; parts[5] = null; // no column when eval } else if (i === 0 && !parts[5] && typeof ex.columnNumber !== 'undefined') { // FireFox uses this awesome columnNumber property for its top frame // Also note, Firefox's column number is 0-based and everything else expects 1-based, // so adding 1 // NOTE: this hack doesn't work if top-most frame is eval stack[0].column = ex.columnNumber + 1; } element = { url: parts[3], func: parts[1] || UNKNOWN_FUNCTION, args: parts[2] ? parts[2].split(',') : [], line: parts[4] ? +parts[4] : null, column: parts[5] ? +parts[5] : null }; } else { continue; } if (!element.func && element.line) { element.func = UNKNOWN_FUNCTION; } stack.push(element); } if (!stack.length) { return null; } return { name: ex.name, message: ex.message, url: getLocationHref(), stack: stack }; } /** * Adds information about the first frame to incomplete stack traces. * Safari and IE require this to get complete data on the first frame. * @param {Object.<string, *>} stackInfo Stack trace information from * one of the compute* methods. * @param {string} url The URL of the script that caused an error. * @param {(number|string)} lineNo The line number of the script that * caused an error. * @param {string=} message The error generated by the browser, which * hopefully contains the name of the object that caused the error. * @return {boolean} Whether or not the stack information was * augmented. */ function augmentStackTraceWithInitialElement(stackInfo, url, lineNo, message) { var initial = { url: url, line: lineNo }; if (initial.url && initial.line) { stackInfo.incomplete = false; if (!initial.func) { initial.func = UNKNOWN_FUNCTION; } if (stackInfo.stack.length > 0) { if (stackInfo.stack[0].url === initial.url) { if (stackInfo.stack[0].line === initial.line) { return false; // already in stack trace } else if ( !stackInfo.stack[0].line && stackInfo.stack[0].func === initial.func ) { stackInfo.stack[0].line = initial.line; return false; } } } stackInfo.stack.unshift(initial); stackInfo.partial = true; return true; } else { stackInfo.incomplete = true; } return false; } /** * Computes stack trace information by walking the arguments.caller * chain at the time the exception occurred. This will cause earlier * frames to be missed but is the only way to get any stack trace in * Safari and IE. The top frame is restored by * {@link augmentStackTraceWithInitialElement}. * @param {Error} ex * @return {?Object.<string, *>} Stack trace information. */ function computeStackTraceByWalkingCallerChain(ex, depth) { var functionName = /function\s+([_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)?\s*\(/i, stack = [], funcs = {}, recursion = false, parts, item, source; for ( var curr = computeStackTraceByWalkingCallerChain.caller; curr && !recursion; curr = curr.caller ) { if (curr === computeStackTrace || curr === TraceKit.report) { // console.log('skipping internal function'); continue; } item = { url: null, func: UNKNOWN_FUNCTION, line: null, column: null }; if (curr.name) { item.func = curr.name; } else if ((parts = functionName.exec(curr.toString()))) { item.func = parts[1]; } if (typeof item.func === 'undefined') { try { item.func = parts.input.substring(0, parts.input.indexOf('{')); } catch (e) {} } if (funcs['' + curr]) { recursion = true; } else { funcs['' + curr] = true; } stack.push(item); } if (depth) { // console.log('depth is ' + depth); // console.log('stack is ' + stack.length); stack.splice(0, depth); } var result = { name: ex.name, message: ex.message, url: getLocationHref(), stack: stack }; augmentStackTraceWithInitialElement( result, ex.sourceURL || ex.fileName, ex.line || ex.lineNumber, ex.message || ex.description ); return result; } /** * Computes a stack trace for an exception. * @param {Error} ex * @param {(string|number)=} depth */ function computeStackTrace(ex, depth) { var stack = null; depth = depth == null ? 0 : +depth; try { stack = computeStackTraceFromStackProp(ex); if (stack) { return stack; } } catch (e) { if (TraceKit.debug) { throw e; } } try { stack = computeStackTraceByWalkingCallerChain(ex, depth + 1); if (stack) { return stack; } } catch (e) { if (TraceKit.debug) { throw e; } } return { name: ex.name, message: ex.message, url: getLocationHref() }; } computeStackTrace.augmentStackTraceWithInitialElement = augmentStackTraceWithInitialElement; computeStackTrace.computeStackTraceFromStackProp = computeStackTraceFromStackProp; return computeStackTrace; })(); module.exports = TraceKit; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"5":5}],7:[function(_dereq_,module,exports){ /* json-stringify-safe Like JSON.stringify, but doesn't throw on circular references. Originally forked from https://github.com/isaacs/json-stringify-safe version 5.0.1 on 3/8/2017 and modified to handle Errors serialization and IE8 compatibility. Tests for this are in test/vendor. ISC license: https://github.com/isaacs/json-stringify-safe/blob/master/LICENSE */ exports = module.exports = stringify; exports.getSerialize = serializer; function indexOf(haystack, needle) { for (var i = 0; i < haystack.length; ++i) { if (haystack === needle) return i; } return -1; } function stringify(obj, replacer, spaces, cycleReplacer) { return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces); } // https://github.com/ftlabs/js-abbreviate/blob/fa709e5f139e7770a71827b1893f22418097fbda/index.js#L95-L106 function stringifyError(value) { var err = { // These properties are implemented as magical getters and don't show up in for in stack: value.stack, message: value.message, name: value.name }; for (var i in value) { if (Object.prototype.hasOwnProperty.call(value, i)) { err = value; } } return err; } function serializer(replacer, cycleReplacer) { var stack = []; var keys = []; if (cycleReplacer == null) { cycleReplacer = function(key, value) { if (stack[0] === value) { return '[Circular ~]'; } return '[Circular ~.' + keys.slice(0, indexOf(stack, value)).join('.') + ']'; }; } return function(key, value) { if (stack.length > 0) { var thisPos = indexOf(stack, this); ~thisPos ? stack.splice(thisPos + 1) : stack.push(this); ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key); if (~indexOf(stack, value)) { value = cycleReplacer.call(this, key, value); } } else { stack.push(value); } return replacer == null ? value instanceof Error ? stringifyError(value) : value : replacer.call(this, key, value); }; } },{}],8:[function(_dereq_,module,exports){ /* * JavaScript MD5 * https://github.com/blueimp/JavaScript-MD5 * * Copyright 2011, Sebastian Tschan * https://blueimp.net * * Licensed under the MIT license: * https://opensource.org/licenses/MIT * * Based on * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message * Digest Algorithm, as defined in RFC 1321. * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * Distributed under the BSD License * See http://pajhome.org.uk/crypt/md5 for more info. */ /* * Add integers, wrapping at 2^32. This uses 16-bit operations internally * to work around bugs in some JS interpreters. */ function safeAdd(x, y) { var lsw = (x & 0xffff) + (y & 0xffff); var msw = (x >> 16) + (y >> 16) + (lsw >> 16); return (msw << 16) | (lsw & 0xffff); } /* * Bitwise rotate a 32-bit number to the left. */ function bitRotateLeft(num, cnt) { return (num << cnt) | (num >>> (32 - cnt)); } /* * These functions implement the four basic operations the algorithm uses. */ function md5cmn(q, a, b, x, s, t) { return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b); } function md5ff(a, b, c, d, x, s, t) { return md5cmn((b & c) | (~b & d), a, b, x, s, t); } function md5gg(a, b, c, d, x, s, t) { return md5cmn((b & d) | (c & ~d), a, b, x, s, t); } function md5hh(a, b, c, d, x, s, t) { return md5cmn(b ^ c ^ d, a, b, x, s, t); } function md5ii(a, b, c, d, x, s, t) { return md5cmn(c ^ (b | ~d), a, b, x, s, t); } /* * Calculate the MD5 of an array of little-endian words, and a bit length. */ function binlMD5(x, len) { /* append padding */ x[len >> 5] |= 0x80 << (len % 32); x[(((len + 64) >>> 9) << 4) + 14] = len; var i; var olda; var oldb; var oldc; var oldd; var a = 1732584193; var b = -271733879; var c = -1732584194; var d = 271733878; for (i = 0; i < x.length; i += 16) { olda = a; oldb = b; oldc = c; oldd = d; a = md5ff(a, b, c, d, x, 7, -680876936); d = md5ff(d, a, b, c, x[i + 1], 12, -389564586); c = md5ff(c, d, a, b, x[i + 2], 17, 606105819); b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330); a = md5ff(a, b, c, d, x[i + 4], 7, -176418897); d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426); c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341); b = md5ff(b, c, d, a, x[i + 7], 22, -45705983); a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416); d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417); c = md5ff(c, d, a, b, x[i + 10], 17, -42063); b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162); a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682); d = md5ff(d, a, b, c, x[i + 13], 12, -40341101); c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290); b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329); a = md5gg(a, b, c, d, x[i + 1], 5, -165796510); d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632); c = md5gg(c, d, a, b, x[i + 11], 14, 643717713); b = md5gg(b, c, d, a, x, 20, -373897302); a = md5gg(a, b, c, d, x[i + 5], 5, -701558691); d = md5gg(d, a, b, c, x[i + 10], 9, 38016083); c = md5gg(c, d, a, b, x[i + 15], 14, -660478335); b = md5gg(b, c, d, a, x[i + 4], 20, -405537848); a = md5gg(a, b, c, d, x[i + 9], 5, 568446438); d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690); c = md5gg(c, d, a, b, x[i + 3], 14, -187363961); b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501); a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467); d = md5gg(d, a, b, c, x[i + 2], 9, -51403784); c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473); b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734); a = md5hh(a, b, c, d, x[i + 5], 4, -378558); d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463); c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562); b = md5hh(b, c, d, a, x[i + 14], 23, -35309556); a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060); d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353); c = md5hh(c, d, a, b, x[i + 7], 16, -155497632); b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640); a = md5hh(a, b, c, d, x[i + 13], 4, 681279174); d = md5hh(d, a, b, c, x, 11, -358537222); c = md5hh(c, d, a, b, x[i + 3], 16, -722521979); b = md5hh(b, c, d, a, x[i + 6], 23, 76029189); a = md5hh(a, b, c, d, x[i + 9], 4, -640364487); d = md5hh(d, a, b, c, x[i + 12], 11, -421815835); c = md5hh(c, d, a, b, x[i + 15], 16, 530742520); b = md5hh(b, c, d, a, x[i + 2], 23, -995338651); a = md5ii(a, b, c, d, x, 6, -198630844); d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415); c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905); b = md5ii(b, c, d, a, x[i + 5], 21, -57434055); a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571); d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606); c = md5ii(c, d, a, b, x[i + 10], 15, -1051523); b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799); a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359); d = md5ii(d, a, b, c, x[i + 15], 10, -30611744); c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380); b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649); a = md5ii(a, b, c, d, x[i + 4], 6, -145523070); d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379); c = md5ii(c, d, a, b, x[i + 2], 15, 718787259); b = md5ii(b, c, d, a, x[i + 9], 21, -343485551); a = safeAdd(a, olda); b = safeAdd(b, oldb); c = safeAdd(c, oldc); d = safeAdd(d, oldd); } return [a, b, c, d]; } /* * Convert an array of little-endian words to a string */ function binl2rstr(input) { var i; var output = ''; var length32 = input.length * 32; for (i = 0; i < length32; i += 8) { output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xff); } return output; } /* * Convert a raw string to an array of little-endian words * Characters >255 have their high-byte silently ignored. */ function rstr2binl(input) { var i; var output = []; output[(input.length >> 2) - 1] = undefined; for (i = 0; i < output.length; i += 1) { output = 0; } var length8 = input.length * 8; for (i = 0; i < length8; i += 8) { output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << (i % 32); } return output; } /* * Calculate the MD5 of a raw string */ function rstrMD5(s) { return binl2rstr(binlMD5(rstr2binl(s), s.length * 8)); } /* * Calculate the HMAC-MD5, of a key and some data (raw strings) */ function rstrHMACMD5(key, data) { var i; var bkey = rstr2binl(key); var ipad = []; var opad = []; var hash; ipad[15] = opad[15] = undefined; if (bkey.length > 16) { bkey = binlMD5(bkey, key.length * 8); } for (i = 0; i < 16; i += 1) { ipad = bkey ^ 0x36363636; opad = bkey ^ 0x5c5c5c5c; } hash = binlMD5(ipad.concat(rstr2binl(data)), 512 + data.length * 8); return binl2rstr(binlMD5(opad.concat(hash), 512 + 128)); } /* * Convert a raw string to a hex string */ function rstr2hex(input) { var hexTab = '0123456789abcdef'; var output = ''; var x; var i; for (i = 0; i < input.length; i += 1) { x = input.charCodeAt(i); output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f); } return output; } /* * Encode a string as utf-8 */ function str2rstrUTF8(input) { return unescape(encodeURIComponent(input)); } /* * Take string arguments and return either raw or hex encoded strings */ function rawMD5(s) { return rstrMD5(str2rstrUTF8(s)); } function hexMD5(s) { return rstr2hex(rawMD5(s)); } function rawHMACMD5(k, d) { return rstrHMACMD5(str2rstrUTF8(k), str2rstrUTF8(d)); } function hexHMACMD5(k, d) { return rstr2hex(rawHMACMD5(k, d)); } function md5(string, key, raw) { if (!key) { if (!raw) { return hexMD5(string); } return rawMD5(string); } if (!raw) { return hexHMACMD5(key, string); } return rawHMACMD5(key, string); } module.exports = md5; },{}]},{},[4])(4) });
  10. jajajja Panda lo hackee en 2013 me regalaron una nintendo DS dijeron que premieban a quien encontraran algun bug muy facil Kaspersky grandes compañias microsoft tambien acen eso dan recompensas por encontrar algun (BUG) amodo interno de algun malware que pueda traspasar sus barreras... Un saludo ^_ ^
  11. Ni yo por eso te pregunto abra que contactar con soporte aber que dicen Un saludo ^_ ^
  12. Harlan tu tienes Maquina Virtual istalado no? pruebalo aver si te sucede lo mismo supongo que abra que agregar el scrip no? GetSystemInfo http://www17.zippyshare.com/v/F8HOlZ0y/file.html
×
×
  • Create New...

Important Information

We use cookies to make your experience of our websites better. By using and further navigating this website you accept this. Detailed information about the use of cookies on this website is available by clicking on more information.