A bare bones login library for Minecraft based projects to authenticate individuals with a Microsoft account.
Based off the Oauth2 flow outline on this site
Atm you can get support via Discord (link below).
A basic example of how to hook this library into Mincraft Launcher core to launch minecraft
//Import just the client package, MSMC replaces the Auth package in Minecraft Launcher core in this example
const { Client } = require("minecraft-launcher-core");
const launcher = new Client();
const msmc = require("msmc");
//Just using NWjs for this example, any function that gives the callback parameter type will work
msmc.getNWjs().FastLaunch(
(callback) => {
let opts = {
clientPackage: null,
// Pulled from the Minecraft Launcher core docs , this function is the star of the show
authorization: msmc.getMCLC().getAuth(callback),
root: "./minecraft",
version: {
number: "1.14.4",
type: "release",
},
memory: {
max: "6G",
min: "4G",
},
};
console.log("Starting");
launcher.launch(opts);
launcher.on("debug", (e) => console.log(e));
launcher.on("data", (e) => console.log(e));
},
(update) => {
//A hook for catching loading bar events and errors, standard with MSMC
console.log("CallBack!!!!!");
console.log(update);
}
);
This is the setup you'd use if you where only using node or an incompatible gui framework
const MSMC = require("msmc");
/**
* Do this if you get the following waring message
* "
* MSMC: Could not automatically determine which version of fetch to use.
* MSMC: Please use 'setFetch' to set this property manually
* "
*/
MSMC.setFetch(require("node-fetch"));
MSMC.MSLogin(
{ client_id: "<token>" },
(call) => {
//The function called when the login has been a success
console.log("");
console.log("CallBack!!!!!");
console.log(call);
console.log("");
},
(update) => {
//A hook for catching loading bar events and errors
console.log("");
console.log("CallBack!!!!!");
console.log(update);
console.log("");
}
).then((link) => {
//This is the link to the login page
console.log("Click ME!!!!");
console.log(link);
});
This is a code sample for electron. It should be added to your main.js file. This will launch a pop-up that allows a user to log in with their Microsoft account as soon as possible. Fastlaunch actually emulates the vanilla Minecraft launcher, meaning that we can use Mojangs own client ID to login. In-line login windows should use the older method.
app.whenReady().then(() => {
...
require("msmc").getElectron().FastLaunch(
(call) => {
// The function is called when the login has been successful
console.log("Login successful");
var accessToken = call.access_token;
var profile = call.profile;
},
(update) => {
// A hook for catching loading bar events and errors
// Possible types are: Starting, Loading, Rejection, Error
switch (update.type) {
case "Starting":
console.log("Checking user started!");
break;
case "Loading":
console.log("Loading:", update.data, "-", update.percent + "%");
break;
case "Rejection":
console.error("Fetch rejected!", update.data);
break;
case "Error":
console.error("MC-Account error:", update.data);
break;
case "Cancelled":
console.error("User clicked cancel!");
break;
}
}
)
...
})
It is recommended to run this in NW.js's node context. Basically in a library that is called via a "require" call in a browser thread.
require("msmc")
.getNWjs()
.FastLaunch(
(call) => {
// The function is called when the login has been successful
console.log("Login successful");
var accessToken = call.access_token;
var profile = call.profile;
},
(update) => {
// A hook for catching loading bar events and errors
// Possible types are: Starting, Loading, Rejection, Error
switch (update.type) {
case "Starting":
console.log("Checking user started!");
break;
case "Loading":
console.log("Loading:", update.data, "-", update.percent + "%");
break;
case "Rejection":
console.error("Fetch rejected!", update.data);
break;
case "Error":
console.error("MC-Account error:", update.data);
break;
case "Cancelled":
console.error("User clicked cancel!");
break;
}
}
);
For more information. Check out Microsoft's support page: https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow#request-an-authorization-code
Basically this is the prompt value in the request sent to Microsoft. This should only be important if you're using either the FastLaunch or Launch functions under either Electron or NW.js
type prompt = "login" | "none" | "consent" | "select_account";
token => Basic MS token info
callback => The callback that is fired on a successful login. It contains a mojang access token and a user profile
updates => A callback that one can hook into to get updates on the login process
returns => The URL needed to log in your user in the form of a promise. You need to send this to a web browser or something similar to that!
function MSLogin(
token: MSToken,
callback: (info: callback) => void,
updates?: (info: update) => void
): Promise<string>;
An exposed version of the function that gets called when this library has found a login code. You can use this for custom setups where you do not want to use pre-made functions provided by the library for yout stuff.
code => The code gotten from a successful login
MStoken => The MS token object
callback => The callback that is fired on a successful login. It contains a mojang access token and a user profile
updates => The URL needed to log in your user. You need to send this to a web browser or something similar to that!
function MSCallBack(
code: string,
MStoken: MSToken,
callback: (info: callback) => void,
updates?: (info: update) => void
): Promise<void>;
This function is used to refresh account objects
profile => Player profile. The same one you'd get from the callback function. This method only works with profiles gotten with msmc!
callback => The callback that is fired on a successful login. It contains a Mojang’s access token and a user profile
updates => A callback that one can hook into to get updates on the login process
MStoken => The MS token object (Optional, will use the vanilla client token if it doesn't have anything)
function MSRefresh(
profile: profile,
callback: (info: callback) => void,
updates?: (info: update) => void,
authToken?: MSToken
): Promise<void>;
An override to manually define which version of fetch should be used. Useful for if you have multiple versions of fetch available and want to use a specific variant
fetchIn => A version of fetch
function setFetch(fetchIn: any): void;
Use with electron to get a electron version of fast launch
returns =>
{
callback => The callback that is fired on a successful login. It contains a mojang access token and a user profile
token => Basic MS token info
updates => A callback that one can hook into to get updates on the login process
properties => See windowProperties interface for more information
function Launch: (token: MSToken, callback: (info: callback) => void, updates?: (info: update) => void, properties?: WindowsProperties) => void
callback => The callback that is fired on a successful login. It contains a mojang access token and a user profile
updates => A callback that one can hook into to get updates on the login process
prompt => See the type definition for "prompt" for more information
properties => See windowProperties interface for more information
function FastLaunch: (callback: (info: callback) => void, updates?: (info: update) => void, prompt?: prompt, properties?: WindowsProperties) => void
}
/**Use with electron to get a electron version of fast launch */
function getElectron(): {
Launch: (
token: MSToken,
callback: (info: callback) => void,
updates?: (info: update) => void,
properties?: WindowsProperties
) => void;
FastLaunch: (
callback: (info: callback) => void,
updates?: (info: update) => void,
prompt?: prompt,
properties?: WindowsProperties
) => void;
};
/**Use with NW.js to get a electron version of fast launch */
function getNWjs(): {
Launch: (
token: MSToken,
callback: (info: callback) => void,
updates?: (info: update) => void,
properties?: WindowsProperties
) => void;
FastLaunch: (
callback: (info: callback) => void,
updates?: (info: update) => void,
prompt?: prompt,
properties?: WindowsProperties
) => void;
};
Checks if a profile object is still valid. Only works with logins done via msmc. profile => Player profile. Similar to the one you'd normaly get with the mojang login (Has a hidden _msmc field)
function Validate(profile: profile): Boolean;
This function will create a login link based on the inputs provided.
Note that this function is called internally after the redirect has been formated. Aka after "http://localhost:\<port>/" is appended to the redirect.
This is done to allow us to create the "FastLaunch" methods which don't rely on an internal http server
token => The MS token object
function CreateLink(token: MSToken): String;
Replaces some of the functions the Authenticator component in MCLC.
This serves as a msmc friendly version of getAuth function in MCLC's Authenticator component. Translating the information msmc gets into something mclc can comprehend. This does however not work with normal Mojang accounts
This serves as a drop in replacement for the validate function in MCLC's Authenticator component. This works with mojang and microsoft accounts.
This serves as a drop in replacement for the refreshAuth function in MCLC's Authenticator component. This will refresh vanilla and msmc accounts. A hidden _msmc variable is used to determine how an account should be refreshed so please avoid removing that somehow since the mojang method of refreshing accounts is not compatible with msmc signed in accounts.
function getMCLC(): {
getAuth: (info: callback) => Promise<any>;
validate: (profile: {
access_token: string;
client_token?: string;
uuid?: string;
name?: string;
user_properties?: Partial<any>;
}) => Promise<Boolean>;
refresh: (profile: {
access_token: string;
client_token?: string;
uuid?: string;
name?: string;
user_properties?: Partial<any>;
}) => Promise<any>;
};
The Oauth2 details needed to log you in.
Resources
- https://docs.microsoft.com/en-us/graph/auth-register-app-v2
- https://docs.microsoft.com/en-us/graph/auth-v2-user#1-register-your-app
- https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredApps
Recommendations:
-
Use "Mobile and desktop applications" as your type setting and make sure to set it up to only use "Personal Microsoft accounts only". You're not a university!
-
set the redirect to "http://localhost/...", With localhost specifically Microsoft does not check port numbers. This means that http://localhost:1/... to http://localhost:65535/... are all the same redirect to MS. (http://localhost/... == http://localhost:80/... btw) This app does not allow you to set the port manually, due to the extreme risk of unforseen bugs popping up.
-
If you set the ridirect to, for example, "http://localhost/Rainbow/Puppy/Unicorns/hl3/confirmed" then the variable {redirect} needs to equal "Rainbow/Puppy/Unicorns/hl3/confirmed".
-
Basically the redirect field is equal to your redirect URL you gave microsoft without the "http://localhost/" part. Please keep this in mind or you'll get weird errors as a mismatch here will still work...sort of.
interface MSToken {
client_id: string;
clientSecret?: string;
redirect?: string;
prompt?: prompt;
}
A minecraft profile object.
interface profile {
id: string;
name: string;
skins?: [];
capes?: [];
}
Used in the callback that is fired upon a successful login
access_token": string => Your classic Mojang auth token. You can do anything with this that you could do with the normal MC login token
profile: { "id": string, "name": string, "skins": [], "capes": [] } => Player profile. Similar to the one you'd normally get with the Mojang login
interface callback {
access_token: string;
profile: { id: string; name: string; skins: []; capes: [] };
}
Used in the callback that is fired multiple times during the login process to give the user feedback on how far along the login process is
interface update {
type: "Loading" | "Rejection" | "Error" | "Starting" | "Cancelled"; //See table below!
/**Some information about the call. Like the component that's loading or the cause of the error. */
data?: string;
/**Used by the rejection type.*/
response?: Response;
/**Used to show how far along the object is in terms of loading*/
percent?: number;
}
Possible values for the 'type' parameter:
Value | Cause |
---|---|
"Loading" | This gives input with regards to how far along the login process is |
"Rejection" | This is given with a fetch error. You are given the fetch item as a data object. |
"Error" | This is given with a normal MC account error and will give you some user readable feedback. |
"Starting" | This is fired once when the whole loading process is started. This is mainly for setting up loading bars and stuff like that. |
"Cancelled" | When the user closes out of a popup (Electron / NV.js / methods that involve a GUI only) . |
Window property is set to any to avoid needing both nw.js and electron loaded as dev dependencies
The common properties between both libraries has been backed into the type information for this interface however
See this resource for Electron, if you want to know what options are available
See this resource for NW.js, if you want to know the available options
interface WindowsProperties {
width: number;
height: number;
resizable?: boolean;
[key: string]: any;
}