Outer function being called before xmlhttprequest being done - javascript

room.onPlayerChat is an outer event i have no control on it, When i try to use it i need to process something on message and checking player role through xmlhttprequest and wait for response then send message to room chat but it doesn't wait for it(xmlhttprequest) to return the player's role and send the normal message (normal player role), how to hang that outer event (room.onPlayerChat) and its needed to handle any room chat source.
const makeRequest = (method, url, data = {}) => {
const xhr = new XMLHttpRequest();
return new Promise(resolve => {
xhr.open(method, url, true);
xhr.onload = () => resolve({
status: xhr.status,
response: xhr.responseText
});
xhr.onerror = () => resolve({
status: xhr.status,
response: xhr.responseText
});
if (method != 'GET') xhr.setRequestHeader('Content-Type', 'application/json');
data != {} ? xhr.send(JSON.stringify(data)) : xhr.send();
})
}
room.onPlayerChat = async function (player,message) {
let request = await makeRequest("GET", 'URL/TO/CHECK/PLAYER/ADMIN/ROLE' + player.name);
if (request.response == "YES")
{
room.sendmessage("ADMIN" + player.name + message);
return false;
}
}

Related

Testing an AJAX function with xhr-mock fails

I'm trying to test the following function from my network.js:
export function post (data) {
return new Promise(function (resolve, reject) {
// need to log to the root
var url = window.location.protocol + '//' + window.location.hostname
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 204) {
resolve(null)
} else {
reject(new Error('an error ocurred whilst sending the request'))
}
}
}
xhr.open('POST', url, true)
xhr.setRequestHeader('Content-type', 'application/json')
xhr.send(JSON.stringify(data))
})
}
My test case looks like this:
import xhrMock from 'xhr-mock'
import * as network from '../src/network'
describe('Payload networking test suite', function () {
beforeEach(() => xhrMock.setup())
afterEach(() => xhrMock.teardown())
test('POSTs JSON string', async () => {
expect.assertions(1)
xhrMock.post(window.location.protocol + '//' + window.location.hostname, (req, res) => {
expect(req.header('Content-Type')).toEqual('application/json')
return res.status(204)
})
await network.post({})
})
})
When running my test suite I'm getting:
xhr-mock: No handler returned a response for the request.
POST http://localhost/ HTTP/1.1
content-type: application/json
{}
This is mostly based on the documentation and I don't understand why its failing
Solution
add a trailing / to the url you are giving xhrMock.post()
Error Details
The url is http://localhost.
That turns into a req.url() of
{
protocol: 'http',
host: 'localhost',
path: '/',
query: {}
}
Calling toString() on that object returns 'http://localhost/'
xhr-mock compares the URLs by doing req.url().toString() === url
'http://localhost/' === 'http://localhost' returns false so xhr-mock is returning an error that no handler returned a response.
I found I had some problems as well and using the following module was a better alternative for me:
https://github.com/berniegp/mock-xmlhttprequest
Usage is pretty straight forward:
const MockXMLHttpRequest = require('mock-xmlhttprequest');
const MockXhr = MockXMLHttpRequest.newMockXhr();
// Mock JSON response
MockXhr.onSend = (xhr) => {
const responseHeaders = { 'Content-Type': 'application/json' };
const response = '{ "message": "Success!" }';
xhr.respond(200, responseHeaders, response);
};
// Install in the global context so "new XMLHttpRequest()" uses the XMLHttpRequest mock
global.XMLHttpRequest = MockXhr;

Recover public address from a typed signature

I am implementing an application, on which it is necessary to confirm your Ethereum wallet. In order to do so, I am currently writing a basic HTML and Javascript Web page.
This is my javascript code.
const msgParams = [
{
type: 'uint',
name: 'Please verify your generated key',
value: ''
}
]
var signeddata = ''
function sanitizeData (data) {
const sanitizedData = {}
for (const key in TYPED_MESSAGE_SCHEMA.properties) {
data[key] && (sanitizedData[key] = data[key])
}
return sanitizedData
}
window.onload = function() {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://plapla.pla/initializeVerification', true);
// If specified, responseType must be empty string or "text"
xhr.responseType = 'json';
xhr.onreadystatechange = function () {
if (xhr.readyState === xhr.DONE) {
if (xhr.status === 200) {
msgParams[0].value = xhr.response.key;
console.log(msgParams);
}
}
};
console.log('!');
xhr.send(null);
}
function verify() {
let web3 = window.web3;
console.log(web3);
// Checking if Web3 has been injected by the browser (Mist/MetaMask)
if (typeof web3 !== 'undefined') {
// Use the browser's ethereum provider
web3 = new Web3(web3.currentProvider);
console.log(web3);
} else {
console.log('No web3? You should consider trying MetaMask!')
}
//Login tracken
web3.currentProvider.publicConfigStore.on('update', callback => {
console.log(callback);
//Login tracken
});
console.log(web3.eth.accounts);
web3.eth.getCoinbase(function(error, result){
if(!error) {
console.log("params: "+msgParams[0]);
var fromAddress = result;
web3.currentProvider.sendAsync({
method: 'eth_signTypedData',
params: [msgParams, fromAddress],
from: fromAddress,
}, function (err, result) {
if (err) return console.error(err);
if (result.error) {
return console.error(result.error.message)
}
var sign = {};
sign.data =[{
type:msgParams[0].type,
name:msgParams[0].name,
value:msgParams[0].value
}];
sign.sig = result.result
var json = JSON.stringify(sign);
console.log("Do JSON"+json);
var xhr = new XMLHttpRequest();
console.log("Fa: "+fromAddress);
xhr.open('POST', 'https://plapla.pla/addWallet', true);
xhr.setRequestHeader('Content-type','application/json; charset=utf-8');
// If specified, responseType must be empty string or "text"
xhr.responseType = 'text';
xhr.onreadystatechange = function () {
if (xhr.readyState === xhr.DONE) {
if (xhr.status === 200) {
console.log(xhr.response);
}
}
};
xhr.send(json);
});
}
});
};
I am retrieving a random number from my backend on load and want the User to sign this Code with Metamask. I then send it again to my firebase backend, which receives the data as well as the signature.
Firebase handles it as Follows:
exports.addWallet = functions.https.onRequest((req, res) => {
cors(req, res, () => {
const signed = req.body;
console.log(signed);
const recovered = sigUtil.recoverTypedSignature(signed);
return recovered;
})
});
As you can see, I am using the eth-sig-util library: https://github.com/MetaMask/eth-sig-util
But I always get this error from firebase:
TypeError: Cannot read property 'EIP712Domain' of undefined
at Object.findTypeDependencies (/user_code/node_modules/eth-sig-util/index.js:97:47)
at Object.encodeType (/user_code/node_modules/eth-sig-util/index.js:76:21)
at Object.hashType (/user_code/node_modules/eth-sig-util/index.js:127:30)
at Object.encodeData (/user_code/node_modules/eth-sig-util/index.js:42:33)
at Object.hashStruct (/user_code/node_modules/eth-sig-util/index.js:116:30)
at Object.sign (/user_code/node_modules/eth-sig-util/index.js:153:21)
at Object.recoverTypedSignature (/user_code/node_modules/eth-sig-util/index.js:235:36)
at cors (/user_code/index.js:29:31)
at cors (/user_code/node_modules/cors/lib/index.js:188:7)
at /user_code/node_modules/cors/lib/index.js:224:17
So I figured out, that the problem is with the library... Do I send the wrong parameters to the function? Is there any other way to recover the public address from the signer?
You need to use object data, can check code here:
https://github.com/MetaMask/eth-sig-util/blob/master/index.js#L234
{
data: '', // the data you signed
sig: '' // the r, s, v concated string
}
Or you can use ethereumjs-util to recover the public key if you know the signed data.

Get status code from any website

I'd like to ensure that a url sent to my server is an actual website (heroku app) rather than validating for htp://fooxbvgf5766.herokuapp.com. A status code of 200 would tell me that url is an actual website.
Been searching and found this.
checkValidWebsite(appName) {
const url = `https://${appName}.herokuapp.com`
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
resolve(xhr.response);
} else {
reject({
status: this.status,
statusText: xhr.statusText
});
}
};
xhr.onerror = function () {
reject({
status: this.status,
statusText: xhr.statusText
});
};
xhr.send();
});
}
Running the function:
checkValidWebsite('foo')
.then(resp => {
console.log(resp)
})
.catch(e => {
console.log('Error:', e)
})
Checking for https://foo.herokuapp.com I get cors errors. Is there a way to detect that a url is an actual website?

How to get all Files Save in Dropbox to my HTML Page

i have save Images in Dropbox using Javascript like that
document.forms.newsletter.addEventListener('submit', function
cb(evt) {
//evt.preventDefault()
// API key from here: https://dropbox.github.io/dropbox-api-v2-
explorer/#files_upload
// need to consider how this gets secured
var TOKEN = ''
var dir = 'blackground/'
var file = document.getElementById('file').files[0]
var promise = new Promise(function (resolve, reject) {
// Dropbox requires application/octet-stream
var xhr = new XMLHttpRequest();
xhr.onload = function() {
if (xhr.status === 200) {
resolve(JSON.parse(xhr.response));
}
else {
reject(xhr.response || 'Unable to upload file');
}
};
xhr.open('POST',
'https://content.dropboxapi.com/2/files/upload');
xhr.setRequestHeader('Authorization', 'Bearer ' + TOKEN);
xhr.setRequestHeader('Content-Type', 'application/octet-
stream');
xhr.setRequestHeader('Dropbox-API-Arg', JSON.stringify({
path: '/' + dir + file.name,
mode: 'add',
autorename: true,
mute: false
}));
xhr.send(file);
})
promise
.then(function (result) {
// Save dropbox response to form
document.getElementById('dropbox').value =
JSON.stringify(result)
// Submit form on successful upload
evt.target.submit()
})
.catch(function (err) {
console.log('a');
})
return false
})
It works fine. But i want to retrieve each Image using Javascript and ajax to display it in my Web Page. How to make it?
I read this Documentation https://www.dropbox.com/developers-v1/core/docs#files-GET that we can make it with Get Verb.
I have make a Get for the API to get All Image like so
$.ajax({
method: "GET",
url: "https://content.dropboxapi.com/1/files/auto/blackground",
dataType: "json",
ContentType:"application/octet-stream",
Authorization:"Bearer token"
});
i get this Error
{error: "Authentication failed"}
error
:
"Authentication failed"
blackground is the folder where are all the Images
Something can help please
It works fine now. I make it like so. Token is my Token for Dropbox.
var token = '';
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var imageUrl = (window.URL || window.webkitURL).createObjectURL(xhr.response);
// display, assuming <img id="image"> somewhere
document.getElementById('image').src = imageUrl;
// download via the download attribute: limited browser support
var a = document.createElement('a');
//a.download = 'test.png';
//a.href = imageUrl;
//a.click();
}
};
xhr.open('POST', 'https://content.dropboxapi.com/2/files/download');
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
xhr.setRequestHeader('Dropbox-API-Arg', JSON.stringify({ path: '/blackground/blackground_logo.jpg' }));
xhr.send();

xhr timeout gives invalid state error in ie11

Am trying to set timeout in XMLHttpRequest but it shows invalid state error, here's the code
function get(url, options) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
// headers
if (options && options.headers) {
for (let header in options.headers) {
if (options.headers.hasOwnProperty(header)) {
xhr.setRequestHeader(header, options.headers[header]);
}
}
}
xhr.open('GET', url);
// FIXME: Why is IE11 failing on "xhr.timeout?
// xhr.timeout = 10000;
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
try {
const data = JSON.parse(xhr.responseText);
resolve(data);
} catch (ex) {
reject({
status: this.status,
statusText: xhr.statusText
});
}
} else {
reject({
status: this.status,
statusText: xhr.statusText
});
}
};
xhr.ontimeout = function () {
reject({
status: this.status,
statusText: xhr.statusText
});
};
xhr.onerror = function () {
reject({
status: this.status,
statusText: xhr.statusText
});
};
xhr.send();
});
}
export default { get };
I had a look at following links link1 link2 link3 and specifically kept xhr.timeout between xhr.open and xhr.send
I even tried this
xhr.onreadystatechange = function () {
if(xhr.readyState == 1 ) {
xhr.timeout = 5000;
}
};
But no luck
Add xhr.timeout after the xhr.open method.
You should set xhr.timeout only when you call xhr.open() in asynchronous mode, otherwise MSIE will rise an exception INVALID_STATE_ERR.
Example:
xhr.open("POST", url, true);
ps. Strangely, i don't see this issue in FF & Chrome.

Categories

Resources