ocilo / skype-http

Unofficial Skype API for Node.js via HTTP
https://ocilo.github.io/skype-http
MIT License
51 stars 24 forks source link

save/load state support (somewhat hacky) #27

Closed mitchcapper closed 7 years ago

mitchcapper commented 7 years ago

I figured before working on other things reduce the number of times logging into the skype account and get serialization working.

Sample use case:

if (fs.existsSync("state.json")) {
        let state = fs.readFileSync("state.json", 'utf8');
        api = await skypeHttp.connect({ verbose: true, state: JSON.parse(state) });
    } else {
        api = await skypeHttp.connect({ verbose: true, credentials: { username: "<user>", password: "<pass>" } });
        fs.writeFileSync("state.json", JSON.stringify(await api.getState()));
    }

So it works but all I am really able to save out is the skype token. Even serializing everything else I could see making the "state" I need to re-run the registration token to generate the endpoint. If all we want to serialize is the skype token I can update the serialization object to only take that, if you have a way to serialize the entire state let me know.

Once we figure something out will update docs and finalize the PR.

mitchcapper commented 7 years ago

Looking at https://github.com/OllieTerrance/SkPy/blob/master/skpy/conn.py they do save a few other state items and restore them (maybe it is the host url redirect?) their saveToken function spells out what it captures.

demurgos commented 7 years ago

The use case you described above is something I'd like to support (hence the TODO to restore the API from an exported state). As you've seen, all the state of the API is stored in a Context but this object does not handle serialization very well because it has a CookieJar which is currently treated as a blackbox. Exposing the cookie store is a possible workaround but we are loosing encapsulation of the cookies. The best would be if it was possible to directly call a method on the cookie jar to serialize and then deserialize it.

We could also simply use the OAuth workflow and just export the registrationToken to then re-issue a new Skype token.

This is a larger PR so I'll need more time to check your changes and look at other implementations. I'll come back to it later today.

mitchcapper commented 7 years ago

So the cookiejar can be serialized directly as under the hood they are using the tough-cookie and it does support serialization. The problem is that requires "inside knowledge" on the library and its internals. Right now I instead pass it the same memorystore it uses by default, but then we can use tough-cookie itself to call methods we know exist and are safe rather than relying on the fact we know the jar is actually a tough-cookie jar in the lib. To me it seemed like the better implementation strategy. Problem is even with serializing everything in Context (what my code currently does) restoring the endpoint doesn't work. May look at what some other projects do more.

demurgos commented 7 years ago

Ok, I am currently looking into this.

Currently, the lib can only use tough-cookie jars so I agree that it's better to explicitly create the memory store if it allows to avoid some casts or relying on the default implementation of request. Anyway, it has always bothered me a bit that the public API depends on the tough-cookie instead of having a library-independent representation for cookies.

I am working on top of your commits, I'll send you a proposition.

demurgos commented 7 years ago

I pushed my changes to a branch on my repo: https://github.com/demurgos/skype-http/tree/save_state_support_pr

The main changes are that I use the cookie store to access the cookie (there's no permanent cookie jar), the Date in the tokens is deserialized to a Date and I do not use request.default. There's no need to obtain a new registration token and resubscribe to resources.

demurgos commented 7 years ago

2017-05-13 at 20:29 (UTC) @demurgos:

I export the skype token, registration token and the cookies and there's no need to retrieve a new registration token. I also updated the code to directly use the cookie store: https://github.com/demurgos/skype-http/tree/save_state_support_pr

2017-05-13 at 20:50 (UTC) @mitchcapper:

yeah your save state sees better I tried the request.default as a last ditch at restoring anything else I could see different between running state and resumed state.

Merging into master