fnbr
Version:
A library to interact with Epic Games' Fortnite HTTP and XMPP services
251 lines • 12.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
/* eslint-disable @typescript-eslint/indent */
/* eslint-disable no-restricted-syntax */
const collection_1 = require("@discordjs/collection");
const fs_1 = require("fs");
const url_1 = require("url");
const Base_1 = tslib_1.__importDefault(require("../Base"));
const Endpoints_1 = tslib_1.__importDefault(require("../../resources/Endpoints"));
const enums_1 = require("../../resources/enums");
const FortniteAuthSession_1 = tslib_1.__importDefault(require("./FortniteAuthSession"));
const LauncherAuthSession_1 = tslib_1.__importDefault(require("./LauncherAuthSession"));
const AuthClients_1 = tslib_1.__importDefault(require("../../resources/AuthClients"));
const Util_1 = require("../util/Util");
const EpicgamesAPIError_1 = tslib_1.__importDefault(require("../exceptions/EpicgamesAPIError"));
const FortniteClientCredentialsAuthSession_1 = tslib_1.__importDefault(require("./FortniteClientCredentialsAuthSession"));
const EOSAuthSession_1 = tslib_1.__importDefault(require("./EOSAuthSession"));
/**
* Represents the client's authentication manager
* @private
*/
class Auth extends Base_1.default {
/**
* @param client The main client
*/
constructor(client) {
super(client);
this.sessions = new collection_1.Collection();
}
/**
* Authenticates the client against EpicGames' API
*/
async authenticate() {
this.client.debug('[AUTH] Authenticating...');
const authStartTime = Date.now();
const authClient = this.client.config.auth.authClient;
const authCreds = this.client.config.auth;
if (authCreds.launcherRefreshToken) {
await this.launcherRefreshTokenAuthenticate(authCreds.launcherRefreshToken, authClient);
}
else if (authCreds.deviceAuth) {
await this.deviceAuthAuthenticate(authCreds.deviceAuth, authClient);
}
else if (authCreds.refreshToken) {
await this.refreshTokenAuthenticate(authCreds.refreshToken, authClient);
}
else if (authCreds.exchangeCode) {
await this.exchangeCodeAuthenticate(authCreds.exchangeCode, authClient);
}
else if (authCreds.authorizationCode) {
await this.authorizationCodeAuthenticate(authCreds.authorizationCode, authClient);
}
else {
throw new Error('No valid auth method found! Please provide one in the client config');
}
if ((!authCreds.launcherRefreshToken && this.client.listenerCount('refreshtoken:created') > 0)
|| (authCreds.createLauncherSession && !this.sessions.has(enums_1.AuthSessionStoreKey.Launcher))) {
const exchangeCode = await this.sessions.get(enums_1.AuthSessionStoreKey.Fortnite).createExchangeCode();
const launcherSession = await LauncherAuthSession_1.default.create(this.client, AuthClients_1.default.launcherAppClient2.clientId, AuthClients_1.default.launcherAppClient2.secret, {
grant_type: 'exchange_code',
exchange_code: exchangeCode,
token_type: 'eg1',
});
this.sessions.set(enums_1.AuthSessionStoreKey.Launcher, launcherSession);
}
if (this.client.config.auth.killOtherTokens) {
await this.client.http.epicgamesRequest({
method: 'DELETE',
url: `${Endpoints_1.default.OAUTH_TOKEN_KILL_MULTIPLE}?killType=OTHERS_ACCOUNT_CLIENT_SERVICE`,
}, enums_1.AuthSessionStoreKey.Fortnite);
}
if (this.client.config.auth.checkEULA) {
const eulaCheck = await this.acceptEULA();
if (!eulaCheck.alreadyAccepted)
this.client.debug('[AUTH] Successfully accepted the EULA');
}
if (!authCreds.deviceAuth && this.client.listenerCount('deviceauth:created') > 0) {
const deviceauth = await this.createDeviceAuth();
const deviceAuth = {
accountId: deviceauth.accountId,
deviceId: deviceauth.deviceId,
secret: deviceauth.secret,
};
this.client.emit('deviceauth:created', deviceAuth);
}
const fortniteClientCredsSession = await FortniteClientCredentialsAuthSession_1.default.create(this.client, AuthClients_1.default[authClient].clientId, AuthClients_1.default[authClient].secret, {
grant_type: 'client_credentials',
token_type: 'eg1',
});
this.sessions.set(enums_1.AuthSessionStoreKey.FortniteClientCredentials, fortniteClientCredsSession);
// Only create an EOS token if we connect to STOMP
if (this.client.config.connectToSTOMP) {
await this.fortniteEOSAuthenticate();
}
this.client.debug(`[AUTH] Authentification successful (${((Date.now() - authStartTime) / 1000).toFixed(2)}s)`);
}
/**
* Kills all active auth sessions
*/
async revokeAllTokens() {
await Promise.all([...this.sessions.filter((s, k) => k !== enums_1.AuthSessionStoreKey.Launcher).values()].map((s) => s.revoke()));
}
/**
* Accepts the Fortnite End User License Agreement (EULA)
*/
async acceptEULA() {
const EULAdata = await this.client.http.epicgamesRequest({
url: `${Endpoints_1.default.INIT_EULA}/account/${this.sessions.get(enums_1.AuthSessionStoreKey.Fortnite).accountId}`,
}, enums_1.AuthSessionStoreKey.Fortnite);
if (!EULAdata)
return { alreadyAccepted: true };
await this.client.http.epicgamesRequest({
method: 'POST',
url: `${Endpoints_1.default.INIT_EULA}/version/${EULAdata.version}/account/`
+ `${this.sessions.get(enums_1.AuthSessionStoreKey.Fortnite).accountId}/accept?locale=${EULAdata.locale}`,
}, enums_1.AuthSessionStoreKey.Fortnite);
try {
await this.client.http.epicgamesRequest({
method: 'POST',
url: `${Endpoints_1.default.INIT_GRANTACCESS}/${this.sessions.get(enums_1.AuthSessionStoreKey.Fortnite).accountId}`,
}, enums_1.AuthSessionStoreKey.Fortnite);
}
catch (e) {
if (e instanceof EpicgamesAPIError_1.default && e.message === 'Client requested access grant but already has the requested access entitlement') {
return { alreadyAccepted: true };
}
}
return { alreadyAccepted: false };
}
/**
* Creates a device auth
*/
async createDeviceAuth() {
var _a;
return this.client.http.epicgamesRequest({
method: 'POST',
url: `${Endpoints_1.default.OAUTH_DEVICE_AUTH}/${(_a = this.sessions.get(enums_1.AuthSessionStoreKey.Fortnite)) === null || _a === void 0 ? void 0 : _a.accountId}/deviceAuth`,
}, enums_1.AuthSessionStoreKey.Fortnite);
}
/**
* Authentication via a device auth
* @param deviceAuthResolvable A resolvable device auth
*/
async deviceAuthAuthenticate(deviceAuthResolvable, authClient) {
var _a, _b;
const deviceAuth = await (0, Util_1.resolveAuthObject)(deviceAuthResolvable);
const fortniteSession = await FortniteAuthSession_1.default.create(this.client, AuthClients_1.default[authClient].clientId, AuthClients_1.default[authClient].secret, {
grant_type: 'device_auth',
device_id: (_a = deviceAuth.deviceId) !== null && _a !== void 0 ? _a : deviceAuth.device_id,
account_id: (_b = deviceAuth.accountId) !== null && _b !== void 0 ? _b : deviceAuth.account_id,
secret: deviceAuth.secret,
token_type: 'eg1',
});
this.sessions.set(enums_1.AuthSessionStoreKey.Fortnite, fortniteSession);
}
/**
* Authentication via an exchange code
* @param exchangeCodeResolvable A resolvable exchange code
*/
async exchangeCodeAuthenticate(exchangeCodeResolvable, authClient) {
const exchangeCode = await (0, Util_1.resolveAuthString)(exchangeCodeResolvable);
const fortniteSession = await FortniteAuthSession_1.default.create(this.client, AuthClients_1.default[authClient].clientId, AuthClients_1.default[authClient].secret, {
grant_type: 'exchange_code',
exchange_code: exchangeCode,
token_type: 'eg1',
});
this.sessions.set(enums_1.AuthSessionStoreKey.Fortnite, fortniteSession);
}
/**
* Authentication via an authorization code
* @param authorizationCodeResolvable A resolvable authorization code
*/
async authorizationCodeAuthenticate(authorizationCodeResolvable, authClient) {
var _a;
let authorizationCode;
switch (typeof authorizationCodeResolvable) {
case 'function':
authorizationCode = await authorizationCodeResolvable();
break;
case 'string':
if (authorizationCodeResolvable.length === 32) {
authorizationCode = authorizationCodeResolvable;
}
else if (authorizationCodeResolvable.includes('?code=')) {
const url = new url_1.URL(authorizationCodeResolvable);
authorizationCode = (_a = url.searchParams.get('code')) !== null && _a !== void 0 ? _a : undefined;
}
else {
authorizationCode = (await fs_1.promises.readFile(authorizationCodeResolvable)).toString();
}
break;
default:
throw new TypeError(`The type "${typeof authorizationCodeResolvable}" does not resolve to a valid auth string`);
}
const fortniteSession = await FortniteAuthSession_1.default.create(this.client, AuthClients_1.default[authClient].clientId, AuthClients_1.default[authClient].secret, {
grant_type: 'authorization_code',
code: authorizationCode,
token_type: 'eg1',
});
this.sessions.set(enums_1.AuthSessionStoreKey.Fortnite, fortniteSession);
}
/**
* Authentication via a refresh token
* @param refreshTokenResolvable A resolvable refresh token
*/
async refreshTokenAuthenticate(refreshTokenResolvable, authClient) {
const refreshToken = await (0, Util_1.resolveAuthString)(refreshTokenResolvable);
const fortniteSession = await FortniteAuthSession_1.default.create(this.client, AuthClients_1.default[authClient].clientId, AuthClients_1.default[authClient].secret, {
grant_type: 'refresh_token',
refresh_token: refreshToken,
token_type: 'eg1',
});
this.sessions.set(enums_1.AuthSessionStoreKey.Fortnite, fortniteSession);
}
/**
* Authentication via a launcher refresh token
* @param refreshTokenResolvable A resolvable refresh token
*/
async launcherRefreshTokenAuthenticate(refreshTokenResolvable, authClient) {
const refreshToken = await (0, Util_1.resolveAuthString)(refreshTokenResolvable);
const launcherSession = await LauncherAuthSession_1.default.create(this.client, AuthClients_1.default.launcherAppClient2.clientId, AuthClients_1.default.launcherAppClient2.secret, {
grant_type: 'refresh_token',
refresh_token: refreshToken,
token_type: 'eg1',
});
this.sessions.set(enums_1.AuthSessionStoreKey.Launcher, launcherSession);
const exchangeCode = await launcherSession.createExchangeCode();
const fortniteSession = await FortniteAuthSession_1.default.create(this.client, AuthClients_1.default[authClient].clientId, AuthClients_1.default[authClient].secret, {
grant_type: 'exchange_code',
exchange_code: exchangeCode,
token_type: 'eg1',
});
this.sessions.set(enums_1.AuthSessionStoreKey.Fortnite, fortniteSession);
}
async fortniteEOSAuthenticate() {
const exchangeCode = await this.sessions.get(enums_1.AuthSessionStoreKey.Fortnite).createExchangeCode();
const authClient = this.client.config.auth.authClient;
const eosSession = await EOSAuthSession_1.default.create(this.client, AuthClients_1.default[authClient].clientId, AuthClients_1.default[authClient].secret, {
grant_type: 'exchange_code',
exchange_code: exchangeCode,
}, {
// base payload used for initial & refresh auth
token_type: 'epic_id',
deployment_id: this.client.config.eosDeploymentId,
});
this.sessions.set(enums_1.AuthSessionStoreKey.FortniteEOS, eosSession);
}
}
exports.default = Auth;
//# sourceMappingURL=Auth.js.map