troubleshoot.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. function switchTo(type, newStatus) {
  2. var unknown = document.querySelector('#status-' + type + ' .status-unknown');
  3. if (unknown) {
  4. unknown.classList.add('hidden');
  5. }
  6. var test = document.querySelector('#status-' + type + ' .status-test')
  7. if (test) {
  8. test.classList.add('hidden');
  9. }
  10. document.querySelector('#status-' + type + ' .status-no').classList.add('hidden');
  11. document.querySelector('#status-' + type + ' .status-yes').classList.add('hidden');
  12. document.querySelector('#status-' + type + ' .status-' + newStatus).classList.remove('hidden');
  13. }
  14. function setupChecks() {
  15. var start = document.querySelector('#start');
  16. var helpText = document.querySelector('#help-text');
  17. var checks = document.querySelector('#checks');
  18. start.addEventListener('click', function(e) {
  19. start.classList.add('hidden');
  20. helpText.classList.add('hidden');
  21. checks.classList.remove('hidden');
  22. doChecks();
  23. });
  24. }
  25. function doChecks() {
  26. // Check for JS
  27. switchTo('js', 'yes');
  28. // Check for RTCPeerConnection
  29. if (window.RTCPeerConnection) {
  30. switchTo('pc', 'yes');
  31. } else {
  32. switchTo('pc', 'no');
  33. }
  34. // Check for RTCDataChannel
  35. if (window.RTCPeerConnection && (new RTCPeerConnection()).createDataChannel) {
  36. switchTo('dc', 'yes');
  37. switchTo('turn', 'test');
  38. } else {
  39. switchTo('dc', 'no');
  40. switchTo('turn', 'no');
  41. }
  42. // Check for LocalStorage
  43. function localStorageAvailable(){
  44. var test = 'test';
  45. try {
  46. localStorage.setItem(test, test);
  47. localStorage.removeItem(test);
  48. return true;
  49. } catch(e) {
  50. return false;
  51. }
  52. }
  53. if (localStorageAvailable()) {
  54. switchTo('ls', 'yes');
  55. } else {
  56. switchTo('ls', 'no');
  57. }
  58. // Check for desktop notifications
  59. if ('Notification' in window) {
  60. switchTo('dn', 'yes');
  61. } else {
  62. switchTo('dn', 'no');
  63. }
  64. // Check for TURN connectivity
  65. var timeout = null;
  66. function turnSuccess() {
  67. switchTo('turn', 'yes');
  68. clearTimeout(timeout);
  69. }
  70. function turnFail() {
  71. switchTo('turn', 'no');
  72. document.querySelector('#status-turn .results').classList.add('hidden');
  73. document.querySelector('#status-turn .status-no .small').classList.remove('hidden');
  74. }
  75. function testTurn() {
  76. timeout = setTimeout(function() {
  77. turnFail();
  78. }, 10000);
  79. var noop = function() {};
  80. var uagent = window.navigator.userAgent.toLowerCase();
  81. var isSafari = /safari/.test(uagent) && /applewebkit/.test(uagent) && !/chrome/.test(uagent);
  82. if (isSafari) {
  83. var iceServers = [
  84. 'turn:turn.threema.ch:443?transport=udp',
  85. 'turn:turn.threema.ch:443?transport=tcp',
  86. 'turns:turn.threema.ch:443',
  87. ];
  88. } else {
  89. var iceServers = [
  90. 'turn:ds-turn.threema.ch:443?transport=udp',
  91. 'turn:ds-turn.threema.ch:443?transport=tcp',
  92. 'turns:ds-turn.threema.ch:443',
  93. ];
  94. }
  95. console.debug('Using ICE servers: ' + iceServers);
  96. var pc = new RTCPeerConnection({iceServers: [{
  97. urls: iceServers,
  98. username: 'threema-angular-test',
  99. credential: 'VaoVnhxKGt2wD20F9bTOgiew6yHQmj4P7y7SE4lrahAjTQC0dpnG32FR4fnrlpKa',
  100. }]});
  101. document.querySelector('#status-turn .results').classList.remove('hidden');
  102. var resultData = document.querySelector('#status-turn .result-data');
  103. pc.createDataChannel('test');
  104. console.info('Creating offer...');
  105. pc.createOffer(function(sdp) { pc.setLocalDescription(sdp, noop, noop) }, noop);
  106. pc.onicecandidate = function(ice) {
  107. if (ice.candidate === null) {
  108. console.info('Done collecting candidates.');
  109. } else if (ice.candidate.candidate) {
  110. var candidate = SDPUtils.parseCandidate(ice.candidate.candidate);
  111. console.debug(candidate);
  112. if (candidate.type === 'relay') {
  113. var info = '[' + candidate.type + '] ' + candidate.ip + ':' + candidate.port + ' (' + candidate.protocol + ')';
  114. if (candidate.relatedAddress.indexOf(':') !== -1) {
  115. info += ' (ipv6)';
  116. } else if (candidate.relatedAddress.indexOf('.') !== -1) {
  117. info += ' (ipv4)';
  118. } else {
  119. info += ' (?)';
  120. }
  121. resultData.innerHTML += info + '<br>';
  122. turnSuccess();
  123. }
  124. } else {
  125. console.warn('Invalid candidate:', ice.candidate.candidate);
  126. }
  127. }
  128. }
  129. testTurn();
  130. }
  131. if (document.readyState != 'loading') {
  132. setupChecks();
  133. } else {
  134. document.addEventListener('DOMContentLoaded', setupChecks);
  135. }