Skip to content

Commit

Permalink
Remove cache on init, add handling of session losses
Browse files Browse the repository at this point in the history
  • Loading branch information
lavgup committed Jan 12, 2021
1 parent 0c26e24 commit a839661
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 50 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sidemen19/mediawiki.js",
"version": "4.2.0",
"version": "5.0.0",
"description": "A modern wrapper for the MediaWiki API.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
32 changes: 26 additions & 6 deletions src/API.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,25 @@ import { Config, Payload, ResObject } from './types';
import got from 'got';
import { CookieJar } from 'tough-cookie';
import { MediaWikiJSError } from './MediaWikiJSError';
import { MediaWikiJS } from './MediaWikiJS';

export class API {
private mwToken: string;
private options: Config;
loginRetries = 0;
bot: MediaWikiJS;
jar: CookieJar;
url: string;

constructor(options: Config) {
constructor(bot: MediaWikiJS, options: Config) {
this.options = options;
this.url = options.url;
this.bot = bot;

this.jar = new CookieJar();
this.mwToken = '+\\';
}

setServer(url: string): API {
this.url = url;
return this;
}

private async mw(params: Record<string, unknown>, csrf: boolean | undefined, method: 'GET' | 'POST'): Promise<ResObject> {
const payload: Payload = {
responseType: 'json',
Expand All @@ -42,6 +43,24 @@ export class API {
throw new MediaWikiJSError('MEDIAWIKI_ERROR', 'Request did not return a body');
}

// Handle session loss
if (body.login?.result === 'Aborted') {
if (body.login.reason === 'Cannot log in when using MediaWiki\\Session\\BotPasswordSessionProvider sessions.') return {
login: {
result: 'Success',
preventOverwrite: true
}
};

if (this.loginRetries >= 1) {
throw new MediaWikiJSError('FAILED_LOGIN', body.login.reason);
}

this.loginRetries++;
await this.bot.login(this.options.botUsername, this.options.botPassword);
return this.mw(params, csrf, method);
}

if (body.error) {
// CSRF Catch
if (body.error?.code === 'badtoken') {
Expand Down Expand Up @@ -69,6 +88,7 @@ export class API {

return this.mw(params, csrf, method);
}

throw new MediaWikiJSError('MEDIAWIKI_ERROR', body.error.info);
}

Expand Down
50 changes: 7 additions & 43 deletions src/MediaWikiJS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,38 +13,17 @@ import { Config, ResObject } from './types';
export class MediaWikiJS {
api: API;
API_LIMIT: number;
cacheSite: Record<string, unknown>;
cacheUser: Record<string, unknown>;
options: Config;

constructor(options: Config) {
if (!options) {
throw new MediaWikiJSError('NO_CONFIG');
}

this.api = new API(options);
this.api = new API(this, options);
this.options = options;

this.API_LIMIT = 5000;
this.cacheSite = {};
this.cacheUser = {};

// Auto detect siteInfo
if (typeof options.url !== 'undefined') {
this.getSiteInfo('general').then(data => this.cacheSite = data.general);
}

// Auto login function
if (options.botUsername && options.botPassword) {
try {
this.login(options.botUsername, options.botPassword).then(() => {
this.whoAmI()
.then(data => this.cacheUser = data);
});
} catch (err) {
console.log(err);
}
}
}

/**
Expand All @@ -53,6 +32,9 @@ export class MediaWikiJS {
* @param [password] - The bot password of the account to log in to.
*/
async login(username?: string, password?: string): Promise<Record<string, unknown>> {
if (username && !this.options.botUsername) this.options.botUsername = username;
if (password && !this.options.botPassword) this.options.botPassword = password;

if (!username && this.options.botUsername) username = this.options.botUsername;
if (!password && this.options.botPassword) password = this.options.botPassword;

Expand All @@ -79,20 +61,13 @@ export class MediaWikiJS {
let actionLogin = await this.api.post(loginObj(queryToken?.query?.tokens?.logintoken));

// Support for MW 1.19
if (actionLogin?.login?.result === 'NeedToken') {
actionLogin = await this.api.post(loginObj(actionLogin?.login?.token));
}
if (actionLogin?.login?.result === 'NeedToken') actionLogin = await this.api.post(loginObj(actionLogin?.login?.token));

// Successful login
if (actionLogin?.login?.result === 'Success') {
this.cacheUser = await this.whoAmI();
return actionLogin;
}
if (actionLogin?.login?.result === 'Success') return actionLogin;

// Reason throwing
if (actionLogin?.login?.result) {
throw new MediaWikiJSError('FAILED_LOGIN', actionLogin?.login?.result);
}
if (actionLogin?.login?.result) throw new MediaWikiJSError('FAILED_LOGIN', actionLogin?.login?.result);

// Unspecified throwing
throw new MediaWikiJSError('FAILED_LOGIN', 'Unspecified error! Dumping: ', JSON.stringify(actionLogin));
Expand All @@ -109,7 +84,6 @@ export class MediaWikiJS {
token
});
this.api.jar.removeAllCookiesSync();
this.cacheUser = await this.whoAmI();

return res;
}
Expand Down Expand Up @@ -145,16 +119,6 @@ export class MediaWikiJS {
return token;
}

/**
* Sets the server.
* @param url - The url of the wiki's api.php file.
*/
async setServer(url: string): Promise<MediaWikiJS> {
this.api.setServer(url);
this.cacheSite = (await this.getSiteInfo('general')).general;
return this;
}

/**
* Gets the first item in an object.
* @param object - The object to get the first item of.
Expand Down

0 comments on commit a839661

Please sign in to comment.