Skip to content

Commit

Permalink
Oauth 2.0 is here
Browse files Browse the repository at this point in the history
  • Loading branch information
Gurrman375 committed May 23, 2021
1 parent ddbc176 commit 25f5f1c
Show file tree
Hide file tree
Showing 12 changed files with 264 additions and 176 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,5 @@ credentials.json
dist/credentials.json
*.json
__pycache__/additional.cpython-37.pyc
dist/HaloMCCRPC.zip
richpresence.spec
Binary file added __pycache__/auth.cpython-37.pyc
Binary file not shown.
159 changes: 159 additions & 0 deletions auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import requests, json
from additional import clear, application_path
from datetime import datetime
from os import path, makedirs
import webbrowser
from time import sleep
CLIENT_ID = "8f9b5ee4-b4eb-40ea-a02f-c9be1f7ae7bf"
REDIRECT_URI = "https://localhost/oauth_success"

def main():
"""Making sure tokens are up to date in case any errors arrive.
"""
current = datetime.now().isoformat(timespec='microseconds') + "9Z"

if(path.exists(application_path() + "\\tokens\\token.json")):
with open((application_path() + '\\tokens\\token.json'), 'r') as f:
tokens = json.load(f)
else:
tokens = None
if(tokens != None):
if(current > tokens['NotAfter']):
if(application_path() + "\\tokens\\accesstoken.json"):
with open((application_path() + "\\tokens\\accesstoken.json"), 'r+') as f:
accesstoken = json.load(f)
access_token = refreshToken(accesstoken['refresh_token'])
user_token = userToken(access_token)
XToken(user_token)
print("Generated a token.")
else:
url()
authorization_code = input("Enter URL:")
makedirs(application_path() + "\\tokens")
clear()
access_token = accessToken(authorization_code)
user_token = userToken(access_token)
XToken(user_token)
pass


def url() -> None:
"""
Authorize account for app and receive authorization code
"""
url = "https://login.live.com/oauth20_authorize.srf"
query_params = {
"client_id": CLIENT_ID,
"response_type": "code",
"approval_prompt": "auto",
"scope": "Xboxlive.signin Xboxlive.offline_access",
"redirect_uri": REDIRECT_URI,
}

destination_url = requests.Request("GET", url, params=query_params).prepare().url

print("Login to your xbox account and save the url.")
sleep(2)
webbrowser.open(destination_url)


def accessToken(authorization_code) -> str:
"""
Authenticate account via authorization code and receive access/refresh token
"""
base_url = "https://login.live.com/oauth20_token.srf"
params = {
"grant_type": "authorization_code",
"client_id": CLIENT_ID,
"scope": "Xboxlive.signin Xboxlive.offline_access",
"code": authorization_code.replace("https://localhost/oauth_success?code=", ""),
"redirect_uri": REDIRECT_URI,
}

resp = requests.post(base_url, data=params)
if resp.status_code != 200:
print("Failed to get access token")
return

access_token = resp.json()["access_token"]
with open('tokens\\accesstoken.json', 'w+') as f:
f.write(json.dumps(resp.json(), indent=2))
return access_token

def refreshToken(refresh_token) -> str:
"""
Authenticate account via refresh code and receive access/refresh token
"""
base_url = "https://login.live.com/oauth20_token.srf"
params = {
"grant_type": "refresh_token",
"client_id": CLIENT_ID,
"scope": "Xboxlive.signin Xboxlive.offline_access",
"refresh_token": refresh_token,
"redirect_uri": REDIRECT_URI,
}

resp = requests.post(base_url, data=params)
if resp.status_code != 200:
print("Failed to refresh token")
return

access_token = resp.json()["access_token"]
with open('tokens\\accesstoken.json', 'w+') as f:
f.write(json.dumps(resp.json(), indent=2))
return access_token

def userToken(access_token) -> str:
"""
Authenticate via access token and receive user token
"""
url = "https://user.auth.xboxlive.com/user/authenticate"
headers = {"x-xbl-contract-version": "1"}
data = {
"RelyingParty": "http://auth.xboxlive.com",
"TokenType": "JWT",
"Properties": {
"AuthMethod": "RPS",
"SiteName": "user.auth.xboxlive.com",
"RpsTicket": "d=" + access_token,
},
}

resp = requests.post(url, json=data, headers=headers)

if resp.status_code != 200:
print("Invalid response")
return

user_token = resp.json()["Token"]
with open('tokens\\token.json', 'w+') as f:
f.write(json.dumps(resp.json(), indent=2))
return user_token

def XToken(user_token) -> str:
"""
Authorize via user token and receive final X token
"""
url = "https://xsts.auth.xboxlive.com/xsts/authorize"
headers = {"x-xbl-contract-version": "1"}
data = {
"RelyingParty": "http://xboxlive.com",
"TokenType": "JWT",
"Properties": {
"UserTokens": [user_token],
"SandboxId": "RETAIL",
},
}

resp = requests.post(url, json=data, headers=headers)

if resp.status_code != 200:
print("Invalid response")
return

with open('tokens\\xtoken.json', 'w+') as f:
data = f.write(json.dumps(resp.json(), indent=2))
return data

if __name__ == "__main__":
main()
4 changes: 0 additions & 4 deletions credentials.json

This file was deleted.

1 change: 0 additions & 1 deletion dist/credentials.json

This file was deleted.

61 changes: 22 additions & 39 deletions dist/richpresence.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const { authenticate, xbl } = require('@xboxreplay/xboxlive-auth');
const { call, getPlayerXUID } = require('@xboxreplay/xboxlive-api');
const { writeFileSync } = require('fs');
const { call } = require('@xboxreplay/xboxlive-api');
const { writeFileSync, readFileSync } = require('fs');
const args = require('yargs').argv;
const { option } = require('yargs');
let config, response, deviceDetails;

const nullactivity = {
Expand All @@ -11,26 +12,23 @@ const nullactivity = {
game: ""
};

const jsonfile = __dirname + '/rpc.json';
const jsonfile = __dirname + '\\rpc.json';

async function richPresence(username, password){
const XBLContractVersion = 1;

async function richPresence(){
// Get Xbox credentials
const { Token: deviceToken } = await xbl.EXPERIMENTAL_createDummyWin32DeviceToken();
const { user_hash, xsts_token } = await authenticate(username, password, {
deviceToken
});
const userID = args.xuid;
const data = JSON.parse(readFileSync((__dirname + "/tokens/xtoken.json")));
const authorization = {
userHash: data['DisplayClaims']['xui'][0]['uhs'],
XSTSToken: data['Token'],
xuid: data['DisplayClaims']['xui'][0]['xid']
};
config = {
url: `https://peoplehub.xboxlive.com/users/me/people/xuids(${userID})/decoration/presenceDetail`,
url: `https://peoplehub.xboxlive.com/users/me/people/xuids(${authorization.xuid})/decoration/presenceDetail`,
method: 'GET'
};
const authorization = {
userHash: user_hash,
XSTSToken: xsts_token
};
try{
response = await call(config, authorization, XBLContractVersion);
response = await call(config, authorization, 1);

// Presence info
let presenceText = response['people'][0]['presenceDetails'], device;
Expand Down Expand Up @@ -61,7 +59,8 @@ async function richPresence(username, password){
writeFileSync(jsonfile, JSON.stringify(activity, null, 2));
}
catch(err){
console.log("Unable to write to file. Check to make sure all data entered is correct.")
console.log("Unable to write to file. Check to make sure all data entered is correct.");
console.log("Check that this file exists " + jsonfile);
}
}
i += 1;
Expand All @@ -75,32 +74,16 @@ async function richPresence(username, password){
}
return;
}
richPresence(args.u, args.p);
richPresence();

/**
* args.u, args.p
steamid: "76561198293744031",
steamid: "",
gameid: "976730",
lobbysteamid: "109775241013106433"
lobbysteamid: ""
steam://joinlobby/
976730/ <------ Game ID
109775241013106433/ <------ Lobby ID
76561198293744031 <------ Steam ID
lobbysteamid/ <------ Lobby ID
steamid <------ Steam ID
80EC429274AF252714363656B71562C0 <------ API Key
*/

// const defaultData = {
// "details": null,
// "state": null,
// "assets":{
// "largeImageKey": null,
// "largeImageText": null,
// "smallImageKey": null,
// "smallImageText": null
// }
// }
// }

// fs.writeFile("./rpc.json", JSON.stringify(defaultData), err => {
// if (err) console.log('Error writing file:', err)
// });
*/
8 changes: 4 additions & 4 deletions dist/rpc.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"details": "",
"state": "",
"device": "",
"game": ""
"details": "Title Screen",
"state": "Main Menu",
"device": "Win32",
"game": "Halo: The Master Chief Collection"
}
31 changes: 15 additions & 16 deletions richpresence.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const { authenticate, xbl } = require('@xboxreplay/xboxlive-auth');
const { call, getPlayerXUID } = require('@xboxreplay/xboxlive-api');
const { writeFileSync } = require('fs');
const { call } = require('@xboxreplay/xboxlive-api');
const { writeFileSync, readFileSync } = require('fs');
const args = require('yargs').argv;
const { option } = require('yargs');
let config, response, deviceDetails;

const nullactivity = {
Expand All @@ -13,24 +14,21 @@ const nullactivity = {

const jsonfile = __dirname + '/rpc.json';

async function richPresence(username, password){
const XBLContractVersion = 1;

async function richPresence(){
// Get Xbox credentials
const { Token: deviceToken } = await xbl.EXPERIMENTAL_createDummyWin32DeviceToken();
const { user_hash, xsts_token } = await authenticate(username, password, {
deviceToken
});
const userID = args.xuid;
const data = JSON.parse(readFileSync((__dirname + "/tokens/xtoken.json")));
const authorization = {
userHash: data['DisplayClaims']['xui'][0]['uhs'],
XSTSToken: data['Token'],
xuid: data['DisplayClaims']['xui'][0]['xid']
};
config = {
url: `https://peoplehub.xboxlive.com/users/me/people/xuids(${userID})/decoration/presenceDetail`,
url: `https://peoplehub.xboxlive.com/users/me/people/xuids(${authorization.xuid})/decoration/presenceDetail`,
method: 'GET'
};
const authorization = {
userHash: user_hash,
XSTSToken: xsts_token
};
try{
response = await call(config, authorization, XBLContractVersion);
response = await call(config, authorization, 1);

// Presence info
let presenceText = response['people'][0]['presenceDetails'], device;
Expand Down Expand Up @@ -62,6 +60,7 @@ async function richPresence(username, password){
}
catch(err){
console.log("Unable to write to file. Check to make sure all data entered is correct.")
console.log(err)
}
}
i += 1;
Expand All @@ -75,7 +74,7 @@ async function richPresence(username, password){
}
return;
}
richPresence(args.u, args.p);
richPresence();

/**
* args.u, args.p
Expand Down
Loading

0 comments on commit 25f5f1c

Please sign in to comment.