Monkeypatch XMLHttpRequest so http uploads work without CORS headers
This commit is contained in:
parent
799cd242f8
commit
2070696639
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,5 @@
|
|||||||
.idea
|
.idea
|
||||||
target
|
target
|
||||||
|
*.map
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
312
dist/index.html
vendored
312
dist/index.html
vendored
@ -20,106 +20,234 @@
|
|||||||
<noscript>You need to enable JavaScript to run the Converse.js chat app.</noscript>
|
<noscript>You need to enable JavaScript to run the Converse.js chat app.</noscript>
|
||||||
<div id="conversejs-bg"></div>
|
<div id="conversejs-bg"></div>
|
||||||
<script>
|
<script>
|
||||||
// access the pre-bundled global API functions
|
// access the pre-bundled global API functions
|
||||||
const { invoke } = window.__TAURI__.tauri;
|
const { invoke } = window.__TAURI__.tauri;
|
||||||
const { getClient, ResponseType } = window.__TAURI__.http;
|
const { getClient, ResponseType, Body } = window.__TAURI__.http;
|
||||||
const tauriFetch = window.__TAURI__.http.fetch;
|
const tauriFetch = window.__TAURI__.http.fetch;
|
||||||
|
|
||||||
const realFetch = window.fetch;
|
const realFetch = window.fetch;
|
||||||
|
|
||||||
// this is clearly not a complete fetch implementation
|
// this is clearly not a complete fetch implementation
|
||||||
// but it's enough for the omemo downloadFile() function...
|
// but it's enough for the omemo downloadFile() function...
|
||||||
window.fetch = async function(url) {
|
window.fetch = async function (url) {
|
||||||
console.log("fetching url: " + url);
|
console.log("fetching url: " + url);
|
||||||
|
|
||||||
const client = await getClient();
|
const client = await getClient();
|
||||||
let response = await await client.get(
|
let response = await await client.get(url, {
|
||||||
url, {
|
timeout: 30,
|
||||||
timeout: 30,
|
responseType: ResponseType.Binary,
|
||||||
responseType: ResponseType.Binary
|
|
||||||
});
|
|
||||||
|
|
||||||
let data = new Uint8Array(response.data).buffer;
|
|
||||||
|
|
||||||
response.arrayBuffer = async function() {
|
|
||||||
return data;
|
|
||||||
};
|
|
||||||
|
|
||||||
return response;
|
|
||||||
};
|
|
||||||
|
|
||||||
function addCredentials (login, password) {
|
|
||||||
localStorage.setItem('login', login);
|
|
||||||
localStorage.setItem('password', password);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCredentials () {
|
|
||||||
const credentials = {}
|
|
||||||
credentials.login = localStorage.getItem('login') || '';
|
|
||||||
if (credentials.login) {
|
|
||||||
credentials.password = localStorage.getItem('password');
|
|
||||||
}
|
|
||||||
|
|
||||||
return credentials;
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeCredentials () {
|
|
||||||
localStorage.removeItem('login');
|
|
||||||
localStorage.removeItem('password');
|
|
||||||
}
|
|
||||||
|
|
||||||
converse.plugins.add('converse-desktop-credentials', {
|
|
||||||
initialize () {
|
|
||||||
console.log("converse-desktop-credentials - initialize");
|
|
||||||
|
|
||||||
const { _converse } = this;
|
|
||||||
const { api } = _converse;
|
|
||||||
|
|
||||||
api.listen.on('afterResourceBinding', () => {
|
|
||||||
console.log("converse-desktop-credentials - afterResourceBinding");
|
|
||||||
if (_converse.connection.pass) {
|
|
||||||
addCredentials(
|
|
||||||
_converse.bare_jid,
|
|
||||||
_converse.connection.pass
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
api.listen.on('logout', () => {
|
|
||||||
console.log("converse-desktop-credentials - logout");
|
|
||||||
removeCredentials();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const { login, password } = getCredentials();
|
let data = new Uint8Array(response.data).buffer;
|
||||||
console.log('login: ' + login);
|
|
||||||
|
|
||||||
invoke('proxy_port').then((port) => {
|
response.arrayBuffer = async function () {
|
||||||
console.log('proxy_port: ' + port);
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
converse.initialize({
|
return response;
|
||||||
auto_login: login && password,
|
};
|
||||||
jid: login,
|
|
||||||
password: password,
|
// this is clearly not a complete XMLHttpRequest implementation
|
||||||
authentication: 'login',
|
// but it's enough for http upload and gif download
|
||||||
auto_away: 300,
|
const realXMLHttpRequest = window.XMLHttpRequest;
|
||||||
auto_reconnect: true,
|
|
||||||
websocket_url: 'ws://127.0.0.1:' + port + '/xmpp-websocket/',
|
function fXMLHttpRequest() {
|
||||||
assets_path: './dist/',
|
//this._xhr = new realXMLHttpRequest();
|
||||||
discover_connection_methods: false,
|
this.upload = {};
|
||||||
message_archiving: 'always',
|
this.upload.addEventListener = function (type, listener, useCapture) {
|
||||||
play_sounds: false,
|
console.log("fake XMLHttpRequest.upload.addEventListener()");
|
||||||
view_mode: 'fullscreen',
|
};
|
||||||
//loglevel: 'debug',
|
}
|
||||||
muc_respect_autojoin: true,
|
|
||||||
muc_show_logs_before_join: true,
|
// Constructor
|
||||||
whitelisted_plugins: ['converse-desktop-credentials']
|
function cXMLHttpRequest() {
|
||||||
}).catch((reason) => {
|
return new fXMLHttpRequest();
|
||||||
document.body.innerText = "error starting converse: " + reason;
|
}
|
||||||
console.log(document.body.innerText);
|
|
||||||
|
cXMLHttpRequest.prototype = fXMLHttpRequest.prototype;
|
||||||
|
|
||||||
|
cXMLHttpRequest.DONE = 4;
|
||||||
|
|
||||||
|
cXMLHttpRequest.prototype.open = function (sMethod, sUrl, bAsync, sUser, sPassword) {
|
||||||
|
this._method = sMethod;
|
||||||
|
this._url = sUrl;
|
||||||
|
this._async = bAsync;
|
||||||
|
// Delete headers, required when object is reused
|
||||||
|
delete this._headers;
|
||||||
|
};
|
||||||
|
|
||||||
|
cXMLHttpRequest.prototype.setRequestHeader = function (sName, sValue) {
|
||||||
|
if (!this._headers) {
|
||||||
|
this._headers = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
this._headers[sName] = sValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
cXMLHttpRequest.prototype.overrideMimeType = function (mimeType) {
|
||||||
|
this._mimeType = mimeType;
|
||||||
|
};
|
||||||
|
|
||||||
|
cXMLHttpRequest.prototype.send = function (vData) {
|
||||||
|
const realThis = this;
|
||||||
|
/*
|
||||||
|
const xhr = new realXMLHttpRequest();
|
||||||
|
//xhr.onreadystatechange = this.onreadystatechange;
|
||||||
|
xhr.onreadystatechange = async () => {
|
||||||
|
if (xhr.readyState === XMLHttpRequest.DONE) {
|
||||||
|
realThis.status = xhr.status;
|
||||||
|
realThis.readyState = xhr.readyState;
|
||||||
|
realThis.responseText = xhr.responseText;
|
||||||
|
realThis.response = xhr.response;
|
||||||
|
|
||||||
|
//console.log("xhr status: " + realThis.status}`);
|
||||||
|
|
||||||
|
console.log(`xhr status: ${realThis.status}`);
|
||||||
|
console.log(`xhr readyState: ${realThis.readyState}`);
|
||||||
|
console.log(`xhr responseText: ${realThis.responseText}`);
|
||||||
|
console.log(`xhr response: ${realThis.response}`);
|
||||||
|
|
||||||
|
if (realThis.onreadystatechange !== undefined) {
|
||||||
|
realThis.onreadystatechange();
|
||||||
|
}
|
||||||
|
if (realThis.onload !== undefined) {
|
||||||
|
realThis.onload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console.log(`open(${this._method}, ${this._url}, ${this._async})`);
|
||||||
|
xhr.open(this._method, this._url, this._async);
|
||||||
|
if (this._mimeType !== undefined) {
|
||||||
|
console.log(`overrideMimeType(${this._mimeType})`);
|
||||||
|
xhr.overrideMimeType(this._mimeType);
|
||||||
|
}
|
||||||
|
for (const key in realThis._headers) {
|
||||||
|
console.log(`setRequestHeader(${key}: ${realThis._headers[key]})`);
|
||||||
|
xhr.setRequestHeader(key, realThis._headers[key]);
|
||||||
|
}
|
||||||
|
console.log(`send(${vData})`);
|
||||||
|
xhr.send(vData);
|
||||||
|
*/
|
||||||
|
|
||||||
|
(async function () {
|
||||||
|
let response = null;
|
||||||
|
|
||||||
|
if (realThis._method == "PUT") {
|
||||||
|
const filePromise = new Promise((resolve, reject) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = function (e) {
|
||||||
|
resolve(reader.result);
|
||||||
|
};
|
||||||
|
reader.readAsArrayBuffer(vData);
|
||||||
|
});
|
||||||
|
|
||||||
|
let buffer = await filePromise;
|
||||||
|
|
||||||
|
const client = await getClient();
|
||||||
|
response = await await client.put(realThis._url, Body.bytes(buffer), {
|
||||||
|
timeout: 30,
|
||||||
|
responseType: ResponseType.Text,
|
||||||
|
headers: realThis._headers,
|
||||||
|
});
|
||||||
|
} else if (realThis._method == "GET") {
|
||||||
|
const client = await getClient();
|
||||||
|
response = await await client.get(realThis._url, {
|
||||||
|
timeout: 30,
|
||||||
|
responseType: ResponseType.Text,
|
||||||
|
headers: realThis._headers,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
realThis.status = response.status;
|
||||||
|
realThis.readyState = XMLHttpRequest.DONE;
|
||||||
|
realThis.responseText = response.data;
|
||||||
|
realThis.response = response.data;
|
||||||
|
|
||||||
|
if (realThis.onreadystatechange !== undefined) {
|
||||||
|
realThis.onreadystatechange();
|
||||||
|
}
|
||||||
|
if (realThis.onload !== undefined) {
|
||||||
|
realThis.onload();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
|
||||||
|
window.XMLHttpRequest = cXMLHttpRequest;
|
||||||
|
|
||||||
|
function addCredentials(login, password) {
|
||||||
|
localStorage.setItem("login", login);
|
||||||
|
localStorage.setItem("password", password);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCredentials() {
|
||||||
|
const credentials = {};
|
||||||
|
credentials.login = localStorage.getItem("login") || "";
|
||||||
|
if (credentials.login) {
|
||||||
|
credentials.password = localStorage.getItem("password");
|
||||||
|
}
|
||||||
|
|
||||||
|
return credentials;
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeCredentials() {
|
||||||
|
localStorage.removeItem("login");
|
||||||
|
localStorage.removeItem("password");
|
||||||
|
}
|
||||||
|
|
||||||
|
converse.plugins.add("converse-desktop-credentials", {
|
||||||
|
initialize() {
|
||||||
|
console.log("converse-desktop-credentials - initialize");
|
||||||
|
|
||||||
|
const { _converse } = this;
|
||||||
|
const { api } = _converse;
|
||||||
|
|
||||||
|
api.listen.on("afterResourceBinding", () => {
|
||||||
|
console.log("converse-desktop-credentials - afterResourceBinding");
|
||||||
|
if (_converse.connection.pass) {
|
||||||
|
addCredentials(_converse.bare_jid, _converse.connection.pass);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}).catch((reason) => {
|
|
||||||
|
api.listen.on("logout", () => {
|
||||||
|
console.log("converse-desktop-credentials - logout");
|
||||||
|
removeCredentials();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { login, password } = getCredentials();
|
||||||
|
console.log("login: " + login);
|
||||||
|
|
||||||
|
invoke("proxy_port")
|
||||||
|
.then((port) => {
|
||||||
|
console.log("proxy_port: " + port);
|
||||||
|
|
||||||
|
converse
|
||||||
|
.initialize({
|
||||||
|
auto_login: login && password,
|
||||||
|
jid: login,
|
||||||
|
password: password,
|
||||||
|
authentication: "login",
|
||||||
|
auto_away: 300,
|
||||||
|
auto_reconnect: true,
|
||||||
|
//websocket_url: 'ws://127.0.0.1:' + port + '/xmpp-websocket/',
|
||||||
|
websocket_url: "wss://burtrum.org/xmpp-websocket/",
|
||||||
|
assets_path: "./dist/",
|
||||||
|
discover_connection_methods: false,
|
||||||
|
message_archiving: "always",
|
||||||
|
play_sounds: false,
|
||||||
|
view_mode: "fullscreen",
|
||||||
|
//loglevel: 'debug',
|
||||||
|
muc_respect_autojoin: true,
|
||||||
|
muc_show_logs_before_join: true,
|
||||||
|
whitelisted_plugins: ["converse-desktop-credentials"],
|
||||||
|
})
|
||||||
|
.catch((reason) => {
|
||||||
|
document.body.innerText = "error starting converse: " + reason;
|
||||||
|
console.log(document.body.innerText);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((reason) => {
|
||||||
document.body.innerText = "error starting proxy: " + reason;
|
document.body.innerText = "error starting proxy: " + reason;
|
||||||
console.log(document.body.innerText);
|
console.log(document.body.innerText);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user