Compare commits

...

29 Commits

Author SHA1 Message Date
Alexander Corn
2e02c14455 3.11.1 2015-11-27 22:09:47 -05:00
Alexander Corn
8f580fc231 Fixed enableTwoFactor returning success when it wasn't successful 2015-11-27 22:09:36 -05:00
Alexander Corn
6f596b5b16 3.11.0 2015-11-27 17:57:57 -05:00
Alexander Corn
1249e28d83 Added enableTwoFactor and finalizeTwoFactor methods 2015-11-27 17:57:39 -05:00
Alexander Corn
85bcaa70be 3.10.0 2015-11-27 01:46:10 -05:00
Alexander Corn
2a5419513c Added disableTwoFactor method 2015-11-27 01:45:58 -05:00
Alexander Corn
deec5c52a4 Fixed isLimitedAccount and vacBanned (fixes #12) 2015-11-27 01:32:12 -05:00
Alexander Corn
2399a5b783 Added getWebApiOauthToken 2015-11-27 01:28:31 -05:00
Alexander Corn
efea8c6265 3.9.10 2015-11-11 00:52:18 -05:00
Alexander Corn
2be414b20c Merge pull request #10 from charredgrass/master
Fixed error on getNotifications
2015-11-11 00:36:54 -05:00
Maxwell Chow
25ebb4c5a3 Fixed error on getNotifications 2015-11-10 20:46:17 -08:00
Alexander Corn
ac87fd3a40 3.9.9 2015-11-09 23:30:39 -05:00
Alexander Corn
c67e2e04f1 Merge pull request #9 from shaunidiot/patch-1
Spelling error
2015-11-09 23:30:02 -05:00
Shaun
83eeb0f190 Spelling error 2015-11-10 12:29:23 +08:00
Alexander Corn
e09cf24fbf 3.9.8 2015-10-26 21:30:46 -04:00
Alexander Corn
9d2b5ade67 Fixed scheduleGroupEvent method
Fixes #7
2015-10-26 21:30:27 -04:00
Alexander Corn
be4e5c9449 3.9.7 2015-10-14 00:37:36 -04:00
Alexander Corn
5926197f23 Fixed primary group setting not working 2015-10-14 00:37:27 -04:00
Alexander Corn
2d86f81142 3.9.6 2015-10-06 18:53:33 -04:00
Alexander Corn
f37bff4a57 Make the error in getWebApiKey an Error object 2015-10-06 18:53:25 -04:00
Alexander Corn
c700b7663b 3.9.5 2015-10-04 19:47:06 -04:00
Alexander Corn
c26e548c64 Fixed some dumb code 2015-10-04 19:46:38 -04:00
Alexander Corn
658d8fb708 Merge pull request #6 from JorisD33/patch-get-inventory
Patch getInventory
2015-10-04 19:43:59 -04:00
Joris
cd68841d1d Fix getInventory issue 2015-10-04 23:28:40 +02:00
Joris
5853968661 Fix CSteamUser constructor 2015-10-04 23:20:30 +02:00
Alexander Corn
10d899f7a7 3.9.4 2015-09-20 00:49:51 -04:00
Alexander Corn
4e1453e702 Better handling for missing items in user XML 2015-09-20 00:49:42 -04:00
Alexander Corn
f3cf2a4361 3.9.3 2015-09-20 00:33:32 -04:00
Alexander Corn
2890b70add Actually fixed the previous issue 2015-09-20 00:33:24 -04:00
9 changed files with 227 additions and 38 deletions

View File

@@ -41,8 +41,9 @@ SteamCommunity.prototype.getSteamUser = function(id, callback) {
}
}
if(!result.profile.steamID64 || !result.profile.onlineState) {
if(!result.profile.steamID64) {
callback(new Error("No valid response"));
return;
}
callback(null, new CSteamUser(self, result.profile, customurl));
@@ -54,22 +55,26 @@ function CSteamUser(community, userData, customurl) {
this._community = community;
this.steamID = new SteamID(userData.steamID64[0]);
this.name = userData.steamID[0];
this.onlineState = userData.onlineState[0];
this.stateMessage = userData.stateMessage[0];
this.privacyState = userData.privacyState[0];
this.visibilityState = userData.visibilityState[0];
this.avatarHash = userData.avatarIcon[0].match(/([0-9a-f]+)\.[a-z]+$/)[1];
this.vacBanned = !!userData.vacBanned[0];
this.tradeBanState = userData.tradeBanState[0];
this.isLimitedAccount = !!userData.isLimitedAccount[0];
this.customURL = userData.customURL ? userData.customURL[0] : customurl;
this.name = processItem('steamID');
this.onlineState = processItem('onlineState');
this.stateMessage = processItem('stateMessage');
this.privacyState = processItem('privacyState', 'uncreated');
this.visibilityState = processItem('visibilityState');
this.avatarHash = processItem('avatarIcon', '').match(/([0-9a-f]+)\.[a-z]+$/);
if(this.avatarHash) {
this.avatarHash = this.avatarHash[1];
}
this.vacBanned = processItem('vacBanned', false) == 1;
this.tradeBanState = processItem('tradeBanState', 'None');
this.isLimitedAccount = processItem('isLimitedAccount') == 1;
this.customURL = processItem('customURL', customurl);
if(this.visibilityState == 3) {
this.memberSince = new Date(userData.memberSince[0].replace(/(\d{1,2})(st|nd|th)/, "$1"));
this.location = userData.location[0] || null;
this.realName = userData.realname[0] || null;
this.summary = userData.summary[0] || null;
this.memberSince = new Date(processItem('memberSince', '0').replace(/(\d{1,2})(st|nd|th)/, "$1"));
this.location = processItem('location');
this.realName = processItem('realname');
this.summary = processItem('summary');
} else {
this.memberSince = null;
this.location = null;
@@ -92,6 +97,14 @@ function CSteamUser(community, userData, customurl) {
return new SteamID(group.groupID64[0]);
});
}
function processItem(name, defaultVal) {
if(!userData[name]) {
return defaultVal;
}
return userData[name][0];
}
}
CSteamUser.getAvatarURL = function(hash, size, protocol) {
@@ -144,5 +157,5 @@ CSteamUser.prototype.getInventoryContexts = function(callback) {
};
CSteamUser.prototype.getInventory = function(appID, contextID, tradableOnly, callback) {
this._community.getInventory(appID, contextID, tradableOnly, callback);
this._community.getUserInventory(this.steamID, appID, contextID, tradableOnly, callback);
};

View File

@@ -40,17 +40,9 @@ SteamCommunity.prototype.chatLogon = function(interval, uiMode) {
this.chatState = SteamCommunity.ChatState.LoggingOn;
var self = this;
this.request("https://steamcommunity.com/chat", function(err, response, body) {
if(err || response.statusCode != 200) {
self.emit('debug', 'Error requesting chat WebAPI token: ' + (err ? err.message : "HTTP error " + response.statusCode));
self.chatState = SteamCommunity.ChatState.LogOnFailed;
setTimeout(self.chatLogon.bind(self), 5000);
return;
}
var match = body.match(/[0-9a-f]{32}/);
if(!match) {
self.emit('debug', 'Couldn\'t find a WebAPI chat token in the response.');
this.getWebApiOauthToken(function(err, token) {
if(err) {
self.emit('debug', "Cannot get oauth token: " + err.message);
self.chatState = SteamCommunity.ChatState.LogOnFailed;
setTimeout(self.chatLogon.bind(self), 5000);
return;
@@ -60,7 +52,7 @@ SteamCommunity.prototype.chatLogon = function(interval, uiMode) {
"uri": "https://api.steampowered.com/ISteamWebUserPresenceOAuth/Logon/v1",
"form": {
"ui_mode": uiMode,
"access_token": match[0]
"access_token": token
},
"json": true
}, function(err, response, body) {
@@ -81,7 +73,7 @@ SteamCommunity.prototype.chatLogon = function(interval, uiMode) {
self._chat = {
"umqid": body.umqid,
"message": body.message,
"accessToken": match[0],
"accessToken": token,
"interval": interval
};

View File

@@ -203,7 +203,7 @@ SteamCommunity.prototype.scheduleGroupEvent = function(gid, name, type, descript
var self = this;
this.request.post({
"uri": "https://steamcommunity.com/gid/" + this.steamID.toString() + "/eventEdit",
"uri": "https://steamcommunity.com/gid/" + gid.toString() + "/eventEdit",
"form": form
}, function(err, response, body) {
if(!callback) {

View File

@@ -101,10 +101,10 @@ SteamCommunity.prototype.editProfile = function(settings, callback) {
break;
case 'primaryGroup':
if(typeof settings[i] === 'object' && settings[i].accountid) {
values.primary_group_steamid = settings[i].accountid;
if(typeof settings[i] === 'object' && settings[i].getSteamID64) {
values.primary_group_steamid = settings[i].getSteamID64();
} else {
values.primary_group_steamid = new SteamID(settings[i]).accountid;
values.primary_group_steamid = new SteamID(settings[i]).getSteamID64();
}
break;

160
components/twofactor.js Normal file
View File

@@ -0,0 +1,160 @@
var SteamTotp = require('steam-totp');
var SteamCommunity = require('../index.js');
var ETwoFactorTokenType = {
"None": 0, // No token-based two-factor authentication
"ValveMobileApp": 1, // Tokens generated using Valve's special charset (5 digits, alphanumeric)
"ThirdParty": 2 // Tokens generated using literally everyone else's standard charset (6 digits, numeric). This is disabled.
};
SteamCommunity.prototype.enableTwoFactor = function(callback) {
var self = this;
this.getWebApiOauthToken(function(err, token) {
if(err) {
callback(err);
return;
}
// Create a random device ID hash
var hash = require('crypto').createHash('sha1');
hash.update(Math.random().toString());
hash = hash.digest('hex');
self.request.post({
"uri": "https://api.steampowered.com/ITwoFactorService/AddAuthenticator/v1/",
"form": {
"steamid": self.steamID.getSteamID64(),
"access_token": token,
"authenticator_time": Math.floor(Date.now() / 1000),
"authenticator_type": ETwoFactorTokenType.ValveMobileApp,
"device_identifier": 'android:' + hash,
"sms_phone_id": "1"
},
"json": true
}, function(err, response, body) {
if(self._checkHttpError(err, response, callback)) {
return;
}
if(!body.response) {
callback(new Error("Malformed response"));
return;
}
if(body.response.status != 1) {
var error = new Error("Error " + body.response.status);
error.eresult = body.response.status;
callback(error);
return;
}
callback(null, body.response);
});
});
};
SteamCommunity.prototype.finalizeTwoFactor = function(secret, activationCode, callback) {
var attemptsLeft = 30;
var diff = 0;
var self = this;
this.getWebApiOauthToken(function(err, token) {
if(err) {
callback(err);
return;
}
finalize(token);
});
function finalize(token) {
var code = SteamTotp.generateAuthCode(secret, diff);
self.request.post({
"uri": "https://api.steampowered.com/ITwoFactorService/FinalizeAddAuthenticator/v1/",
"form": {
"steamid": self.steamID.getSteamID64(),
"access_token": token,
"authenticator_code": code,
"authenticator_time": Math.floor(Date.now() / 1000),
"activation_code": activationCode
},
"json": true
}, function(err, response, body) {
if(self._checkHttpError(err, response, callback)) {
return;
}
if(!body.response) {
callback(new Error("Malformed response"));
return;
}
body = body.response;
console.log(body);
if(body.server_time) {
diff = body.server_time - Math.floor(Date.now() / 1000);
}
if(body.status == 89) {
callback(new Error("Invalid activation code"));
} else if(!body.success) {
callback(new Error("Error " + body.status));
} else if(body.want_more) {
attemptsLeft--;
diff += 30;
finalize(token);
} else {
callback(null);
}
});
}
};
SteamCommunity.prototype.disableTwoFactor = function(revocationCode, callback) {
var self = this;
this.getWebApiOauthToken(function(err, token) {
if(err) {
callback(err);
return;
}
self.request.post({
"uri": "https://api.steampowered.com/ITwoFactorService/RemoveAuthenticator/v1/",
"form": {
"steamid": self.steamID.getSteamID64(),
"access_token": token,
"revocation_code": revocationCode,
"steamguard_scheme": 1
},
"json": true
}, function(err, response, body) {
if(self._checkHttpError(err, response, callback)) {
return;
}
if(!body.response) {
callback(new Error("Malformed response"));
return;
}
if(!body.response.success) {
callback(new Error("Request failed"));
return;
}
if(body.response.status == 1) {
callback(null);
return;
}
var error = new Error("Cannot remove authenticator (" + body.response.status + ")");
error.eresult = body.response.status;
callback(error);
});
});
};

View File

@@ -156,7 +156,7 @@ SteamCommunity.prototype.postUserComment = function(userID, message, callback) {
if(body.success) {
callback(null);
} else if(bpdy.error) {
} else if(body.error) {
callback(new Error(body.error));
} else {
callback(new Error("Unknown error"));

20
components/webapi.js Normal file
View File

@@ -0,0 +1,20 @@
var SteamCommunity = require('../index.js');
SteamCommunity.prototype.getWebApiOauthToken = function(callback) {
var self = this;
// Pull an oauth token from the webchat UI
this.request("https://steamcommunity.com/chat", function(err, response, body) {
if(self._checkHttpError(err, response, callback)) {
return;
}
var match = body.match(/"([0-9a-f]{32})"/);
if (!match) {
callback(new Error("Malformed response"));
return;
}
callback(null, match[1]);
});
};

View File

@@ -145,7 +145,7 @@ SteamCommunity.prototype.getSessionID = function() {
function generateSessionID() {
return Math.floor(Math.random() * 1000000000);
};
}
SteamCommunity.prototype.getWebApiKey = function(domain, callback) {
var self = this;
@@ -158,7 +158,7 @@ SteamCommunity.prototype.getWebApiKey = function(domain, callback) {
}
if(body.match(/<h2>Access Denied<\/h2>/)) {
return callback("Access Denied");
return callback(new Error("Access Denied"));
}
var match = body.match(/<p>Key: ([0-9A-F]+)<\/p>/);
@@ -213,6 +213,7 @@ SteamCommunity.prototype.parentalUnlock = function(pin, callback) {
};
SteamCommunity.prototype.getNotifications = function(callback) {
var self = this;
this.request.get("https://steamcommunity.com/actions/RefreshNotificationArea", function(err, response, body) {
if(self._checkHttpError(err, response, callback)) {
return;
@@ -332,6 +333,8 @@ require('./components/market.js');
require('./components/groups.js');
require('./components/users.js');
require('./components/inventoryhistory.js');
require('./components/webapi.js');
require('./components/twofactor.js');
require('./classes/CMarketItem.js');
require('./classes/CMarketSearchResult.js');
require('./classes/CSteamGroup.js');

View File

@@ -1,6 +1,6 @@
{
"name": "steamcommunity",
"version": "3.9.2",
"version": "3.11.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",
@@ -18,6 +18,7 @@
"steamid": "^0.3.1",
"xml2js": "^0.4.11",
"cheerio": "^0.19.0",
"async": "^1.4.2"
"async": "^1.4.2",
"steam-totp": "^1.0.0"
}
}