From db223185dde26c9d7c04ae6c9a29dc1f5e0a8834 Mon Sep 17 00:00:00 2001 From: Hanro Date: Sat, 25 Feb 2023 13:10:09 +0200 Subject: [PATCH] Finally added support for console logins --- lexipacks/english.json | 13 +++++---- src/assets.ts | 11 ++++---- src/auth/auth.ts | 56 +++++++++++++++++++++++++++++++++----- src/tests.ts | 2 +- tests/console/index.mjs | 35 ++++++++++++++++++++++++ tests/console/package.json | 15 ++++++++++ 6 files changed, 113 insertions(+), 19 deletions(-) create mode 100644 tests/console/index.mjs create mode 100755 tests/console/package.json diff --git a/lexipacks/english.json b/lexipacks/english.json index 68593c9..fcf61a5 100644 --- a/lexipacks/english.json +++ b/lexipacks/english.json @@ -1,30 +1,31 @@ { "version":"4.0.0", "name": "English", - "error": "An unknown error has occured", - "error.auth": "An unknown authentication error has occured", + "error": "An unknown error has occurred", + "error.auth": "An unknown authentication error has occurred", "error.auth.microsoft": "Failed to login to Microsoft account", "error.auth.xboxLive": "Failed to login to Xbox Live", - "error.auth.xsts": "Unknown error occured when attempting to obtain an Xbox Live Security Token", + "error.auth.xsts": "Unknown error occurred when attempting to obtain an Xbox Live Security Token", "error.auth.xsts.userNotFound": "The given Microsoft account doesn't have an Xbox account", "error.auth.xsts.bannedCountry": "The given Microsoft account is from a country where Xbox Live is not available", "error.auth.xsts.child": "The account is a child (under 18) and cannot proceed unless the account is added to a Family account by an adult", "error.auth.xsts.child.SK": "South Korean Law: Go to the Xbox page and grant parental rights to continue logging in.", - "error.auth.minecraft": "Unknown error occured when attempting to login to Minecraft", + "error.auth.minecraft": "Unknown error occurred when attempting to login to Minecraft", "error.auth.minecraft.login": "Failed to authenticate with Mojang with given Xbox account", "error.auth.minecraft.profile": "Failed to fetch minecraft profile", "error.auth.minecraft.entitlements": "Failed to fetch player entitlements", - "error.gui": "An unknown gui framework error has occured", + "error.gui": "An unknown gui framework error has occurred", "error.gui.closed": "Gui closed by user", "error.gui.raw.noBrowser": "No chromium browser was set, cannot continue!", "error.state.invalid": "[Internal]: Method not implemented.", + "error.state.invalid.http": "[Internal]: Http server support not present in current environment .", "error.state.invalid.gui": "[Internal]: Invalid gui framework.", "error.state.invalid.redirect": "[Internal]: The token must have a redirect starting with 'http://localhost/' for this function to work!", "error.state.invalid.electron": "[Internal]: It seems you're attempting to load electron on the frontend. A critical function is missing!", - + "load": "Generic load event", "load.auth": "Generic authentication load event", "load.auth.microsoft": "Logging into Microsoft account", diff --git a/src/assets.ts b/src/assets.ts index 9fac9f8..91f9334 100644 --- a/src/assets.ts +++ b/src/assets.ts @@ -22,26 +22,27 @@ export type mclcUser = { */ export let lexicon = { //Error - "error": "An unknown error has occured", - "error.auth": "An unknown authentication error has occured", + "error": "An unknown error has occurred", + "error.auth": "An unknown authentication error has occurred", "error.auth.microsoft": "Failed to login to Microsoft account", "error.auth.xboxLive": "Failed to login to Xbox Live", - "error.auth.xsts": "Unknown error occured when attempting to optain an Xbox Live Security Token", + "error.auth.xsts": "Unknown error occurred when attempting to optain an Xbox Live Security Token", "error.auth.xsts.userNotFound": "The given Microsoft account doesn't have an Xbox account", "error.auth.xsts.bannedCountry": "The given Microsoft account is from a country where Xbox live is not available", "error.auth.xsts.child": "The account is a child (under 18) and cannot proceed unless the account is added to a Family account by an adult", "error.auth.xsts.child.SK": "South Korean law: Go to the Xbox page and grant parental rights to continue logging in.", - "error.auth.minecraft": "Unknown error occured when attempting to login to Minecraft", + "error.auth.minecraft": "Unknown error occurred when attempting to login to Minecraft", "error.auth.minecraft.login": "Failed to authenticate with Mojang with given Xbox account", "error.auth.minecraft.profile": "Failed to fetch minecraft profile", "error.auth.minecraft.entitlements": "Failed to fetch player entitlements", - "error.gui": "An unknown gui framework error has occured", + "error.gui": "An unknown gui framework error has occurred", "error.gui.closed": "Gui closed by user", "error.gui.raw.noBrowser": "no chromium browser was set, cannot continue!", "error.state.invalid": "[Internal]: Method not implemented.", + "error.state.invalid.http": "[Internal]: Http server support not present in current environment.", "error.state.invalid.gui": "[Internal]: Invalid gui framework.", "error.state.invalid.redirect": "[Internal]: The token must have a redirect starting with 'http://localhost/' for this function to work!", "error.state.invalid.electron": "[Internal]: It seems you're attempting to load electron on the frontend. A critical function is missing!", diff --git a/src/auth/auth.ts b/src/auth/auth.ts index a5b205c..b5a785f 100644 --- a/src/auth/auth.ts +++ b/src/auth/auth.ts @@ -3,6 +3,7 @@ import EventEmitter from "events"; import fetch from "node-fetch"; import { lexcodes, windowProperties, lst, errResponse, err } from "../assets.js"; import type xbox from "./xbox.js"; +import type { Server } from "http" /** * This library's supported gui frameworks. * (Raw requires no extra dependencies, use it if you're using some unknown framework!) @@ -67,6 +68,7 @@ export declare interface auth extends EventEmitter { export class auth extends EventEmitter { token: MStoken; + private app: Server; constructor(prompt?: prompt) constructor(token: MStoken) constructor(token?: MStoken | prompt) { @@ -77,13 +79,13 @@ export class auth extends EventEmitter { } - createLink() { + createLink(redirect?: string) { return ( "https://login.live.com/oauth20_authorize.srf" + "?client_id=" + this.token.client_id + "&response_type=code" + - "&redirect_uri=" + encodeURIComponent(this.token.redirect) + + "&redirect_uri=" + encodeURIComponent(redirect ? redirect : this.token.redirect) + "&scope=XboxLive.signin%20offline_access" + (this.token.prompt ? "&prompt=" + this.token.prompt : "") + "&mkt=" + lst('gui.market') @@ -95,13 +97,13 @@ export class auth extends EventEmitter { load(code: lexcodes) { this.emit("load", code); } - login(code: string) { + login(code: string, redirect?: string) { const body = ( "client_id=" + this.token.client_id + (this.token.clientSecret ? "&client_secret=" + this.token.clientSecret : "") + "&code=" + code + "&grant_type=authorization_code" + - "&redirect_uri=" + this.token.redirect) + "&redirect_uri=" + (redirect ? redirect : this.token.redirect)) return this._get(body); } refresh(MS: msAuthToken): Promise @@ -128,10 +130,49 @@ export class auth extends EventEmitter { err('error.state.invalid.gui') } } + /** + * Used for a console like login experience. + * @param callback + * @param port + * @returns + */ + async setServer(callback: (xbox:xbox) => void, port = 0) { + let http: typeof import("http"); + try { http = await import("http"); } + catch (er) { err("error.state.invalid.http"); } + // if (this.token.redirect.startsWith('http://localhost/')) err("error.state.invalid.redirect"); + try { if (this.app) { this.app.close(); } } catch { /*Ignore*/ } + this.app = http.createServer(async (req, res) => { + const lnk = `http://localhost:${req.socket.localPort}`; + if (req.url.startsWith(`/link`)) { + res.writeHead(302, { + 'Location': this.createLink(lnk) + }); + return res.end(); + } + + res.writeHead(200, { "Content-Type": "text/plain" }); + res.end("Thank you!"); + if (req.url.includes("?")) { + const code = new URLSearchParams(req.url.substr(req.url.indexOf("?") + 1)).get("code"); + console.log(code) + try{ + callback(await this.login(code,lnk)); + }catch(e){ + console.error(e) + } + } + }); + this.app.on("listening", () => { + const f = this.app.address(); + if (typeof f != "string") { + console.log(`Use 'http://localhost:${f.port}/link' to automatically get redirected`) + } else { + console.log(`Server is running on address ${f}...`); + } + }) + return this.app.listen(port); - async server(port = 0) { - if (this.token.redirect.startsWith('http://localhost/') || this.token.redirect.startsWith('http://127.')) err("error.state.invalid.redirect") - throw "error.state.invalid" } private async _get(body: string): Promise { @@ -139,6 +180,7 @@ export class auth extends EventEmitter { var MS_Raw = await fetch("https://login.live.com/oauth20_token.srf", { method: "post", body: body, headers: { "Content-Type": "application/x-www-form-urlencoded" } }) + // console.log(await MS_Raw.text()) errResponse(MS_Raw, "error.auth.microsoft") var MS = await MS_Raw.json(); diff --git a/src/tests.ts b/src/tests.ts index 9fba841..7436570 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,4 +1,4 @@ -import { execSync } from "child_process"; +import { execSync } from "child_process" console.log("Testing raw framework") execSync('npm run start',{cwd:"tests/raw"}) console.log("Testing nwjs framework") diff --git a/tests/console/index.mjs b/tests/console/index.mjs new file mode 100644 index 0000000..07113dd --- /dev/null +++ b/tests/console/index.mjs @@ -0,0 +1,35 @@ +import msmc from "msmc"; +console.log(msmc) +const auth = new msmc.auth({ + "client_id":"9263b99c-b7c7-4c98-ac73-3dd90bc1fa2e", + "redirect":"http://localhost" +}); +auth.setServer((xbla=>{ + console.log(xbla) +})) + + +//assets.loadLexiPack("..","..","lexipacks","afrikaans.json") +//console.log(auth.createLink()) +//auth.on('load', console.log).luanch('raw').then(async e => { + +// const t = await e.getMinecraft() +// console.log(t.mclc()) +//}).catch((e) => { +// console.log(wrapError(e)) +//}) +let R = []; + +//console.log(msmc.getXbox().getXProfile(P.getAuth)) +/* +console.log(L); + +const mclc = getMCLC().getAuth(L); +console.log(mclc); +const r = await getMCLC().refresh(mclc, console.log); +console.log(r); + +console.log("Completed tests!"); +/**Hidden in type files. Here to make keeping the ES6 shim up to date far less of a hassle. */ +//msmc.mkES6(); + diff --git a/tests/console/package.json b/tests/console/package.json new file mode 100755 index 0000000..71b9300 --- /dev/null +++ b/tests/console/package.json @@ -0,0 +1,15 @@ +{ + "name": "launcher", + "version": "0.0.1", + "main": "index.mjs", + "devDependencies": { + "nwjs-types": "^1.0.0" + }, + "dependencies": { + "@types/node": "^17.0.35", + "msmc": "file:../../" + }, + "scripts": { + "start": "node tests.mjs" + } +}