Compare commits

...

8 Commits

Author SHA1 Message Date
Alexander Corn
339d5dc1e4 3.14.1 2015-12-07 16:36:20 -05:00
Alexander Corn
2a7a03d35e Use SHA-1 hash of our SteamID when enabling 2FA 2015-12-07 16:34:49 -05:00
Alexander Corn
ff1c3279c8 Use random hex value instead of current time for deviceid 2015-12-07 11:42:10 -05:00
Alexander Corn
9175a44828 3.14.0 2015-12-05 01:41:39 -05:00
Alexander Corn
deeeb633cf Delete _identitySecret if we have it when we stop polling 2015-12-05 01:41:35 -05:00
Alexander Corn
a50bd35a54 Added proper queue for confirmations 2015-12-05 01:37:41 -05:00
Alexander Corn
5bf51a2e3e Added automatic confirmation accepting 2015-12-05 00:41:27 -05:00
Alexander Corn
448b32b9c6 callback with an error if we don't get a valid RSA key (resolves #29) 2015-12-05 00:24:52 -05:00
4 changed files with 63 additions and 9 deletions

View File

@@ -1,5 +1,7 @@
var SteamCommunity = require('../index.js');
var Cheerio = require('cheerio');
var SteamTotp = require('steam-totp');
var Async = require('async');
var CConfirmation = require('../classes/CConfirmation.js');
@@ -139,7 +141,7 @@ SteamCommunity.prototype.respondToConfirmation = function(confID, confKey, time,
function request(community, url, key, time, tag, params, json, callback) {
params = params || {};
params.p = "android:" + Date.now();
params.p = "android:" + require('crypto').randomBytes(16).toString('hex');
params.a = community.steamID.getSteamID64();
params.k = key;
params.t = time;
@@ -164,11 +166,13 @@ function request(community, url, key, time, tag, params, json, callback) {
/**
* Start automatically polling our confirmations for new ones. The `confKeyNeeded` event will be emitted when we need a confirmation key, or `newConfirmation` when we get a new confirmation
* @param {int} pollInterval - The interval, in milliseconds, at which we will poll for confirmations. This shouldn't be any less than 10,000 probably.
* @param {Buffer|string|null} [identitySecret=null] - Your identity_secret. If passed, all confirmations will be automatically accepted and nothing will be emitted.
*/
SteamCommunity.prototype.startConfirmationChecker = function(pollInterval) {
SteamCommunity.prototype.startConfirmationChecker = function(pollInterval, identitySecret) {
this._confirmationPollInterval = pollInterval;
this._knownConfirmations = this._knownConfirmations || {};
this._confirmationKeys = this._confirmationKeys || {};
this._identitySecret = identitySecret;
if(this._confirmationTimer) {
clearTimeout(this._confirmationTimer);
@@ -185,6 +189,10 @@ SteamCommunity.prototype.stopConfirmationChecker = function() {
delete this._confirmationPollInterval;
}
if(this._identitySecret) {
delete this._identitySecret;
}
if(this._confirmationTimer) {
clearTimeout(this._confirmationTimer);
delete this._confirmationTimer;
@@ -202,6 +210,27 @@ SteamCommunity.prototype.checkConfirmations = function() {
}
var self = this;
if(!this._confirmationQueue) {
this._confirmationQueue = Async.queue(function(conf, callback) {
// Worker to process new confirmations
if(self._identitySecret) {
// We should accept this
self.emit('debug', "Accepting confirmation #" + conf.id);
var time = Math.floor(Date.now() / 1000);
conf.respond(time, SteamTotp.getConfirmationKey(self._identitySecret, time, "allow"), true, function() {
// If there was an error and it wasn't actually accepted, we'll pick it up again
delete self._knownConfirmations[conf.id];
setTimeout(callback, 1000); // Call the callback in 1 second, to make sure the time changes
});
} else {
self.emit('newConfirmation', conf);
setTimeout(callback, 1000); // Call the callback in 1 second, to make sure the time changes
}
}, 1);
}
this.emit('debug', 'Checking confirmations');
this._confirmationCheckerGetKey('conf', function(err, key) {
if(err) {
resetTimer();
@@ -227,16 +256,16 @@ SteamCommunity.prototype.checkConfirmations = function() {
// We have new confirmations! Grab a key to get details.
self._confirmationCheckerGetKey('details', function(err, key) {
var handled = 0;
newOnes.forEach(function(conf) {
self._knownConfirmations[conf.id] = conf; // Add it to our list of known confirmations
if(err) {
handleNewConfirmation(conf, handled++);
self._confirmationQueue.push(conf);
} else {
// Get its offer ID, if we can
conf.getOfferID(key.time, key.key, function(err, offerID) {
conf.offerID = offerID ? offerID : null;
handleNewConfirmation(conf, handled++);
self._confirmationQueue.push(conf);
});
}
});
@@ -257,12 +286,32 @@ SteamCommunity.prototype.checkConfirmations = function() {
// Delay them by 1 second per new confirmation that we see, so that keys won't be the same.
setTimeout(function() {
self.emit('newConfirmation', conf);
if(self._identitySecret) {
self.emit('debug', 'Accepting confirmation ' + conf.id);
var time = Math.floor(Date.now() / 1000);
conf.respond(time, SteamTotp.getConfirmationKey(self._identitySecret, time, "allow"), true, function() {
delete self._knownConfirmations[conf.id];
});
} else {
self.emit('newConfirmation', conf);
}
}, handleNumber * 1000);
}
};
SteamCommunity.prototype._confirmationCheckerGetKey = function(tag, callback) {
if(this._identitySecret) {
if(tag == 'details') {
// We don't care about details
callback(new Error("Disabled"));
return;
}
var time = Math.floor(Date.now() / 1000);
callback(null, {"time": time, "key": SteamTotp.getConfirmationKey(this._identitySecret, time, tag)});
return;
}
var existing = this._confirmationKeys[tag];
var reusable = ['conf', 'details'];

View File

@@ -18,7 +18,7 @@ SteamCommunity.prototype.enableTwoFactor = function(callback) {
// Create a random device ID hash
var hash = require('crypto').createHash('sha1');
hash.update(Math.random().toString());
hash.update(self.steamID.getSteamID64());
hash = hash.digest('hex');
self.request.post({

View File

@@ -69,6 +69,11 @@ SteamCommunity.prototype.login = function(details, callback) {
callback(e);
return;
}
if(!json.publickey_mod || !json.publickey_exp) {
callback(new Error("Invalid RSA key received"));
return;
}
var key = new RSA();
key.setPublic(json.publickey_mod, json.publickey_exp);

View File

@@ -1,6 +1,6 @@
{
"name": "steamcommunity",
"version": "3.13.0",
"version": "3.14.1",
"description": "Provides an interface for logging into and interacting with the Steam Community website",
"keywords": ["steam", "steam community"],
"homepage": "https://github.com/DoctorMcKay/node-steamcommunity",