Error: credentials argument needs to implement signRequest method? - javascript

When I get the Azure Credentials using "ms-rest-azure" library.
let credentials = await msRestAzure.loginWithServicePrincipalSecret(id, secret, tanent);
let newCred = JSON.stringify(credentials);
let duplicateCred = JSON.parse(newCred); // Create duplicate credentials object
Now if I going to use the "duplicateCred" for my further Azure function call, then I'll get the above error.
But if I'm using "credentials", then all is well.
So how to I assign the "credentials" object to other variable? So that i'll use the variable for my future azure API call.
Example:
let credentials = await msRestAzure.loginWithServicePrincipalSecret(id, secret, tanent);
let newCred = JSON.stringify(credentials);
let duplicateCred = JSON.parse(newCred); // Create duplicate credentials object
// Okay, here I'm getting the proper client object. Because I am using "credentials" in the below line of code.
// I'm getting the results from the below lines of code.
const client = new MonitorManagementClient(credentials, subscription);
const results = await client.operations.list();
context.log('results==> ', results);
// Error, here not getting the proper client object. Because I am using "duplicateCred" as credentials in the below line of code.
// I'm not getting the results from the below lines of code.
// At the below line I'm getting the above error.
const client = new MonitorManagementClient(duplicateCred, subscription);
const results = await client.operations.list();
context.log('results==> ', results);
How do I create a duplicate credential object from actual credentials object ?

This is incorrect method to do so. Credentials returned by msRestAzure.loginWithServicePrincipalSecret call is not a plain object it's an instance of ApplicationTokenCredentials. When you call JSON.stringify you loose this class reference and convert the whole value to Object. So cloned credentials object looses prototype chain with ApplicationTokenCredentials methods.
Also ApplicationTokenCredentials has no cloning logic what could mean it shouldn't be cloned. Using your own cloning logic could conflict with future versions of Azure library. It's better to add an issue in the official Azure SDK repository if you need to have a cloning method.
Note! ⚠️ Such way of cloning could be dangerous and leads to unexpected behaviour. You should strongly avoid it, except of cases when you really need to erase value's prototype chain!

Related

TypeError: Class method is not a function, confused about binding this

I have this class Game.
class Game {
constructor(player) {
this.player1 = player;
}
getHost() {
// player has property nickname
return `Host: ${this.player1.nickname}`;
}
}
I believe the issue I am having is that getHost() is becoming unbound from it's context, however I'm not sure how to fix it. I'm learning JS and I'm pretty confused about this language's usage of this. I'm also using socket.io for the first time, so this adds a lot to the confusion for me.
My server script (the server works, just showing relevant parts):
io.on('connection', (socket) => {
// passed defined player
socket.on('host game', (player) => {
const game = new Game(player);
console.log(game.getHost()); // still works here
io.sockets.emit("game created", game);
});
});
Client:
socket.on("game created", (game) => {
const gameElement = document.createElement("li");
gameElement.innerHTML = game.getHost(); // ERROR
games.appendChild(gameElement);
});
On the above marked line, I get the Uncaught TypeError: game.getHost is not a function.
Sorry if the socket.io functions make it more confusing, basically just when the game is passed from server to client, it doesn't work anymore.
Thanks for the help
The issue is that socketio is serializing the object for you. Since a websocket is still just HTTP, you can't send an actual JS object over it. socketio handles serializing your object to JSON using JSON.stringify(game) behind the scenes. It will also convert that JSON string back into an object for you on the client side too.
Unfortunately when you do this you lose methods. For example:
let game = new Game({nickname: 'Bob Vance'});
game = JSON.stringify(game);
console.log(game) // will output {"player1":{"nickname":"Bob Vance"}}
You should see {"player1":{"nickname":"Bob Vance"}} in the console because serializing to JSON drops the methods but preserves properties. This is just normal JavaScript behaviour.
So what you have to do to get the methods back is create a new instance of a game on the client-side, and then use Object.assign() to build the object back up.
Example
let serializedGame= JSON.parse(game);
let newGameInstance = new Game({nickname: game.nickname});
Object.assign(newGameInstance, serializedGame);
Now you should be ok to call newGameInstance.getHost()

How Can I get function value without toString()?

I need to make sure that some specific native Javascript functions are not patched nor overrode.
Unfortunately, I cannot do that with accessing the .toString() of the function or Function.prototype.toString with one of bind apply or call, since the Function.prototype.toString is one of the functions I have to test.
Is there any other method which returns the value (the function itself) of a function? (Or [Native Code] for native JS functions)
Editing: One of the purposes of this test is to check if the client is a bot that patches some JS functions. Creating new frame and taking its Function.prototype.toString value won't work in that case
In response to edit
If it's a malicious client that can't or won't update their bot script in response to your checks, then just save a copy of Function.prototype.toString() using javascript in your HTML header to a temp variable. Then check against this to see if the client has mutated the js at all.
If the client is malicious AND is trying to actively avoid your checks by changing their bot, then there is simply no iron-clad way to stop them. It will become an arms-race where you patch in checks and they patch in fixes in response. Ultimately, the client has the final say in what gets run in their browser, so you might want to think again about why you're doing these checks to see if there's another viable approach to your problem.
Initial Answer
You could re-request the whole .js file and parse it all as a string. You would have to do this for every js file and find a good pattern for determining if your functions have been over-written, so it may not work for your needs.
// my JS file is being served from giorgiosjames.com/myjs.js
const myJs = await fetch('giorgiosjames.com/myjs.js').then(res => res.text());
// parse myJs here, something like
if (myJs.includes('Function.prototype.toString = ')) // do something
If you can constrain your use to the latest Firefox, you can use the method .toSource(), but no other browsers support it and it is not standard. More reading here
// only in latest Firefox
const x = () => 'wow';
console.log(x.toSource())
// returns "() => 'wow'"
And as a frame challenge, you could probably still be using the (arguably) best approach of Function.prototype.toString by:
First checking if toString works.
Resetting .toString() if it has been overridden.
Checking your other functions with .toString()
Un-fixing .toString() if necessary
let temp = null;
if (Function.prototype.toString.toString() !== 'function toString() { [native code] }') {
// save overridden function if you need to come back to it
temp = Function.prototype.toString;
// getting the original toString function by creating an iframe
const iframe = docuemnt.createElement('iframe');
iframe.style.display = 'none';
document.body.appendChild(iframe);
Function.prototype.toString = iframe.contentWindow.Function.prototype.toString;
}
// do your other checks here ex//
if (Array.prototype.includes.toString() !== iframe.contentWindow.Array.prototype.includes.toString()) {
// do something
}
// ..or however you're planning on checking for overridden functions
// restore toString from temp if needed.
Function.prototype.toString = temp;

How to fix 'variable is not constructor' error in discord.js node project?

i'm experemeting with discord bot and tried to create record in database, but there's some troubles with it.
mongodb server is running and fully functioning.
there's two files.
first, with code of command:
https://sourceb.in/6834bfe20e.js
and second. with mongoose scheme:
https://sourceb.in/9f0c7858df.js
acrually, there's third file index file with command handler and
librarys initializations, but that's does not participate in the error.
I expected to create a record in the database, but there's error what says:
'token is not constructor' in command file:13:19
Problem:
Simply put, you're declaring a constant token, but also passing a parameter named token into your callback. When you're attempting to construct a new object based on the constant, you're actually using the callback's token variable.
Take note of this example, which emits the same error with your setup:
const token = class {
constructor(guild) {
this.guild = guild;
}
};
console.log(new token('1234')); // Works fine.
function foo(token) {
console.log(new token('1234')); // Throws error.
}
foo({ someOtherVar: true });
Solution:
A quick rename of your variable(s) will do. I'd suggest naming your const tokenSchema to avoid conflict (and confusion).

Is it possible to use a Proxy JavaScript Object to 'trap' a user from finding its properties/values by emptying the Object PRIOR to getting info/data?

said simply:
I am trying to create a protective barrier around a JavaScript Object, using a Proxy to set 'traps' for any form of retrieval or manipulation. These traps will require the SessionKey parameter to be provided with any such Object manipulations or else default into clearing out -all- information and properties of the Object.
(This SessionKey is of course the one provided by the User Sign-in PHP which is sent back upon successful sign-in.)
If I have this right, and I'm not the most veteran coder here certainly, the Object will only call functions with the corresponding SessionKey parameter being provided - as this Object knows the SessionKey.
I cannot be 100% to thwart any or all such efforts to get into my code, but perhaps I can set up a 'trip' alarm that makes all such efforts unsuccessful. No SessionKey? NO DOM (.empty()), no WebServices/API. Nothing.
Thank you for your help, I appreciate it immensely.
What you are wanting can't really be done. You CAN create a proxy to trap retrieval/manipulation calls but you can't make the underlying object private in any way.
For example, if you have object
const privateObj = { name: 'John Smith', ssn: '123-45-6789' };
and proxy
const proxy = new Proxy(privateObj, {} /* handler for getter/setter traps */);
you can console log the proxy to get something like this:
[[Handler]]: Object
[[Target]]: Object
[[IsRevoked]]: false
and you can expand [[Target]] to see the properties of the underlying object. So if you want this property to be fully private you won't want to use proxies. Furthermore, if the user can inspect the proxy, they can easily get access to the underlying object and mutate it outside of the proxy traps.
If you want to be able to really protect that object, it would be better to protect it in a function closure and have getter/setter wrappers around that object.
You could try as a first step:
const protectObject = (SessionKey, ...objectProps) => {
const protectedObject = { // Do something here to create the object
...objectProps // and its properties you want to protect
};
return {
accessProp(_SessionKey, prop) {
if (_SessionKey !== SessionKey) throw Error("Your session key doesn't match");
return protectedObject[prop];
},
setProp(_SessionKey, prop, val) {
if (_SessionKey !== SessionKey) throw Error("Your session key doesn't match");
protectedObject[prop] = val;
}
};
};
So now you have a private object that is protected:
const privateObj = protectObject('12345', 'John Smith', '7/20/1992', '123-45-6789');
privateObj.accessProp('12345', 1); // '7/20/1992'
privateObj.accessProp('1234', 2); // Uncaught Error: Your session key doesn't match
privateObj.setProp('12345', 1, '7/21/1993');
privateObj.accessProp('12345', 1); // '7/21/1993'

Store and retrieve Google Dart objects in JavaScript library containers

Store and retrieve Google Dart objects in JavaScript library containers
In a Dart application I am using an external JavaScript library to do various matrix calculations.
The specific functionality of the library is not important, what it's important is that I need to store and retrieve Dart object that I put in the matrix.
Dart Class - Lets image i have a dart object that which has a parameter called name
MyDartClass mydc = new MyDartClass(something, something);
mydc.name;
// Everything works as planned
Storing
matrix = js.context.matrix
matrix.cell(1,1).store("thing", new MyDartClass(something, something));
Retrieving
matrix.cell(1,1).has_object_of_type("thing");
// true
MyDartClass mydc = matrix.cell(1,1).retrieve("thing");
Do something with the object
mydc.name;
// Exception: The null object does not have a getter 'name'.
// NoSuchMethodError : method not found: 'name'
// Receiver: null
// Arguments: []
Does the library really work?
Yes it does. I have done the exact same thing in pure javascript many times and there are plenty of test to test the behaviour ( in Javascript )
Is Dart Broken?
When I try to use a javascriptified Hash to do the same behavoiur it works like a charm.
var options = js.map({ 'dart' : new MyDartclass(something, something));
var y = options["dart"];
js.context.console.log(y.name);
// Name is printed
What do you get out from the retrieve?
It seems that I get some kind of Dart Proxy
MyDartClass mydc = matrix.cell(1,1). retrieve("thing");
js.context.console.log(mydc);
DartProxy {id: "dart-ref-20", port: DartSendPortSync}
id: "dart-ref-20"
port: DartSendPortSync
__proto__: DartProxy
I belive that the lib stores the objects, deep down, in a hash map. But it seems like when I retrieve the object into the Dart I get something, but not in a way that I can work with it. So i need help since I don't know how to make it work.
Do I need to de-proxify the object?
Perhaps it IS a Dart bug when you try to retrieve objects from hashes inside objects
Perhaps I missunderstod everything that this is not suppose to work.
Passing and retrieving Dart objects inside the same scope is working. There's the following test case in the tests of js-interop to proove it :
test('retrieve same dart Object', () {
final date = new DateTime.now();
js.context.dartDate = date;
expect(js.context.dartDate, equals(date));
});
However there seems to be an issue with multiple scopes (and multiple event loops as well). There is no way to retain a dart object for now. So your dart object reference goes away at the end of scope. Here's a simple test case that fails :
test('retrieve same dart Object', () {
final date = new DateTime.now();
js.scoped(() {
js.context.dartDate = date;
});
js.scoped(() {
expect(js.context.dartDate, equals(date));
});
});
Please file an issue.

Categories