find-webclient.js 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. async function tryConnect(server) {
  2. document.getElementById('connect-button').disabled = true;
  3. try {
  4. if (!server.startsWith("http")) {
  5. server = "http://" + server;
  6. }
  7. const url = new URL("/System/Info/Public", server);
  8. const response = await fetch(url);
  9. if (response.ok && (await response.json()).Id) {
  10. const htmlResponse = await fetch(server);
  11. if (!htmlResponse.ok) {
  12. throw new Error("Status not ok");
  13. }
  14. if (response.headers.get("content-security-policy")) {
  15. // Sigh... If we just navigate to the URL, the server's CSP will block us loading other resources.
  16. // So we have to parse the HTML, set a new base href, and then write it back to the page.
  17. // We also have to override the history functions to make sure they use the correct URL.
  18. console.log("Using CSP workaround");
  19. const webUrl = htmlResponse.url.replace(/\/[^\/]*$/, "/");
  20. const realUrl = window.location.href;
  21. const html = await htmlResponse.text();
  22. const parser = new DOMParser();
  23. const doc = parser.parseFromString(html, "text/html");
  24. const base = doc.createElement("base");
  25. base.href = webUrl
  26. doc.head.insertBefore(base, doc.head.firstChild);
  27. const oldPushState = window.history.pushState;
  28. window.history.pushState = function(state, title, url) {
  29. url = (new URL(url, realUrl)).toString();
  30. return oldPushState.call(window.history, state, title, url);
  31. };
  32. const oldReplaceState = window.history.replaceState;
  33. window.history.replaceState = function(state, title, url) {
  34. url = (new URL(url, realUrl)).toString();
  35. return oldReplaceState.call(window.history, state, title, url);
  36. };
  37. document.open();
  38. document.write((new XMLSerializer()).serializeToString(doc));
  39. document.close();
  40. } else {
  41. console.log("Using normal navigation");
  42. window.location = server;
  43. }
  44. await window.initCompleted;
  45. window.jmpInfo.settings.main.userWebClient = server;
  46. return true;
  47. }
  48. } catch (e) {
  49. console.error(e);
  50. document.getElementById('connect-button').disabled = false;
  51. return false;
  52. }
  53. }
  54. document.getElementById('connect-form').addEventListener('submit', async (e) => {
  55. e.preventDefault();
  56. const server = document.getElementById('address').value;
  57. const result = await tryConnect(server);
  58. if (!result) {
  59. document.getElementById('backdrop').style.display = 'block';
  60. }
  61. });
  62. document.getElementById('connect-fail-button').addEventListener('click', () => {
  63. document.getElementById('backdrop').style.display = 'none';
  64. });
  65. // load the server if we have one
  66. (async() => {
  67. const savedServer = window.jmpInfo.settings.main.userWebClient;
  68. if (!savedServer || !(await tryConnect(savedServer))) {
  69. document.getElementById('splash').style.display = 'none';
  70. document.getElementById('main').style.display = 'block';
  71. }
  72. })();