2

I am trying to store callbacks in my database, and use them later from another session.

Is it possible?

Lets make some code for example:

// One session
var callback = () => {
  console.log("Hey! This is a callback!");
}

db.store("myCallback", callback);

// Another session
db.get("myCallback")(); // Output: "Hey! This is a callback!"

EDIT - Just to clarify my context, we can refer to this question: Question

Etgar
  • 5,774
  • 2
  • 16
  • 30
  • I don't think it's a serializable object... It turn is into a string like `[Object Object]` and... that's it.. :( – EvgenyKolyakov Jun 28 '17 at 17:08
  • @EvgenyKolyakov I know it isn't serializable, but I still find a way to implement that. Thanks! – Etgar Jun 28 '17 at 17:08
  • Also, try first to `console.log(db.get("myCallback"));` .. – EvgenyKolyakov Jun 28 '17 at 17:09
  • @EvgenyKolyakov I'm pretty sure it should print "[Function]" – Etgar Jun 28 '17 at 17:10
  • Exactly... now how do you expect to parse it back ?? – EvgenyKolyakov Jun 28 '17 at 17:10
  • 3
    With this particular example, you can `callback.toString()` and `eval` later, but it will be executed in different context, so is hardly usable for anything more complex than `console.log`; – Alex Blex Jun 28 '17 at 17:11
  • @EvgenyKolyakov This is why I'm asking. I know it isn't right to save callbacks like that, but I still find a solution. – Etgar Jun 28 '17 at 17:11
  • @AlexBlex This is what I was searching for! Thanks! I know that the context isn't the same... I'm looking forward to solve this problem as well. – Etgar Jun 28 '17 at 17:13

3 Answers3

2

You could use the javascript Function class.

As Alex Blex said, to implement this, you would have to store each callback as a string of javascript code in the database, and then retrieve it as a string. You pass this in as an argument for the Function(...) constructor.

That being said, this isn't a very efficient way of doing things. If you could store the result of the function in the data base, that would save a lot of space.

clabe45
  • 2,354
  • 16
  • 27
  • Sounds like a great idea (Of course it has security weaknesses, but it depends on the use). Regarding your second suggestion, you can see the reference that I've added in the question, and maybe this will provide you some information about what I'm trying to implement. – Etgar Jun 28 '17 at 17:37
  • Okay, you should consider theRemix's answer then. Store parameters for the function, _not_ the function itself. – clabe45 Jun 28 '17 at 17:52
  • **And remember to escape characters so the user cannot inject more code when you plug it in as an argument** – clabe45 Jun 28 '17 at 17:54
  • But then we are restricted for 'dummy' functions... And how can we escape the characters? – Etgar Jun 28 '17 at 17:55
  • What do you mean? And also take a look at [this question](https://stackoverflow.com/questions/942011/how-to-prevent-javascript-injection-attacks-within-user-generated-html) for preventing script injection – clabe45 Jun 28 '17 at 17:59
1

It would work best to store the parts if the callback functions that differ.

var callbackParams = { 
  message : "Hey! This is a callback!"
}
db.store("myCallback", callbackParams); 
// Another session 
var handleCallback = (params) => {
    console.log(params.message);
}
handleCallback(db.get("myCallback"));

The worst way is to use eval. Do not use eval as it could be easily exploitable leaving your program and system vulnerable for easy attacks.

theRemix
  • 2,154
  • 16
  • 16
  • The problem with this solution is that we are restricted to dummy `console.log` callbacks, aren't we? – Etgar Jun 28 '17 at 17:28
  • That's an example. Basically you want to store **data** in the db, not **functionality**. Once you retrieve data, you can handle it however you need to within defined functions. – theRemix Jun 28 '17 at 17:32
0

I'd make scene if you had something like this:

var myObj = new function() {
  // One session
  this.callback1 = () => {
    console.log("Hey! This is a callback1!");
  }
  this.callback2 = () => {
    console.log("Hey! This is a callback2!");
  }
}();



db.store("myCallback", "callback1");

// Another session
myObj[db.get("myCallback")](); // Output: "Hey! This is a callback1!"
EvgenyKolyakov
  • 3,310
  • 2
  • 21
  • 31
  • I don't understand why you're trying to do. Why should the window have this callback again in his prototype? – Etgar Jun 28 '17 at 17:16
  • You can use smart words, or just assign any function to any object in JS. – EvgenyKolyakov Jun 28 '17 at 17:17
  • But in other session, there shouldn't be the callback in the window. – Etgar Jun 28 '17 at 17:18
  • I know what you were meaning by saying `window`, but I still don't understand why you think that the callback is going to appear in the object again in the seconds session, because if the callback is not serializable, serializing `myObj` won't serialize the callback, so that the `myObj` from the first session won't be the same `myObj` in the second session. – Etgar Jun 28 '17 at 17:25
  • `myObj[db.get("myCallback")]();` means - invoke function/method that is called (string) `db.get("myCallback")` in `myObj` object. – EvgenyKolyakov Jun 28 '17 at 17:27
  • and I'm storing a string... `db.store("myCallback", "callback1"); ` – EvgenyKolyakov Jun 28 '17 at 17:28
  • I promise you that I understand what you're trying to do, but there is still the problem that I've mentioned two comments above. – Etgar Jun 28 '17 at 17:30
  • I usually store a json with my config of 2Kb rather than the whole 240Kb object... – EvgenyKolyakov Jun 28 '17 at 17:32
  • That's great, your more than right. But how should we store the code of the callback if we store only the name of it? The callback won't exist in the seconds session, will it? – Etgar Jun 28 '17 at 17:34
  • Oh, now I get your mind. The thing is that I don't have a direct access to the code (or the memory) that calls "me". – Etgar Jun 28 '17 at 17:45
  • 1
    You need to store the code in the code and the data in the database. It's bad practice to store code in the DB... what if tomorrow you decide to change something in the code.. now, you'll need to change it everywhere in the DB... rather than just uploading the new script. – EvgenyKolyakov Jun 28 '17 at 17:46
  • You can see the reference I've added to the question itself to get some more context about it. – Etgar Jun 28 '17 at 17:58
  • I will pass this one. Thank you – EvgenyKolyakov Jun 28 '17 at 17:59