nhentai-tools
Version:
A toolset to interact with the doujin site nhentai.net
106 lines (105 loc) • 5.21 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getCaptcha = exports.logout = exports.login = exports.getUser = exports.updateUser = exports.isLoggedIn = exports.notLoggedInError = void 0;
const client_1 = require("./client");
const utils_1 = require("./utils");
const puppeteer = require("puppeteer");
exports.notLoggedInError = new Error('User is not logged in');
exports.isLoggedIn = false;
let _data = null;
const updateUser = () => client_1.client.get('/')
.then(({ data }) => {
var _a;
const user = (_a = data.match(/user: (.+),/)) === null || _a === void 0 ? void 0 : _a[1];
if (!user || !user.includes('JSON.parse'))
throw new Error('User is not logged in');
return JSON.parse((0, utils_1.unescapeUTF8)(user.match(/JSON\.parse\("(.+)"\)/)[1]));
});
exports.updateUser = updateUser;
const getUser = () => {
if (!exports.isLoggedIn)
throw exports.notLoggedInError;
return _data;
};
exports.getUser = getUser;
/** Login as username/password. If you're logging in multiple times, make sure to include a method to get a captcha token. */
const login = (username_or_email, password, captcha) => {
if (exports.isLoggedIn)
throw new Error('Already logged in');
// wrapped in promise to allow early breakout if a captcha is required
return new Promise((resolve, reject) => {
client_1.client.get('/login/')
.then(({ data }) => __awaiter(void 0, void 0, void 0, function* () {
// grab the csrfmiddlewaretoken from the body
const [, csrfmiddlewaretoken] = data.match(/name="csrfmiddlewaretoken" value="(\w{64})"/);
// create the body of the post request, containing the csrfmiddlewaretoken and the username/password
const body = new URLSearchParams({ csrfmiddlewaretoken, username_or_email, password });
// if we have a captcha, wait for it to be solved, then add it to the body
if (data.includes('captcha')) {
if (captcha)
body.set('g-recaptcha-response', yield captcha());
else
throw new Error('Captcha required, but no captcha function was provided');
}
return client_1.client.post('/login/', body.toString(), { validateStatus: status => status === 302 || status === 200 });
}))
.then(({ data }) => {
// if the data has a captcha, we need to retry the login
if (data.includes('captcha'))
resolve((0, exports.login)(username_or_email, password, captcha));
if (data.includes('Invalid username (or email) or password.'))
reject('Invalid username or password');
return (0, exports.updateUser)();
})
.then(data => {
_data = data;
exports.isLoggedIn = true;
resolve(_data);
});
});
};
exports.login = login;
/** Logout from the current user. */
const logout = () => {
if (!exports.isLoggedIn)
throw exports.notLoggedInError;
return client_1.client.get('/logout/')
.then(({ data }) => {
const csrfmiddlewaretoken = data.match(/"csrfmiddlewaretoken" value="\w{64}/)[0].split('value="')[1];
return client_1.client.post('/logout/', new URLSearchParams({ csrfmiddlewaretoken }).toString(), { validateStatus: status => status === 302 });
})
.then(() => {
_data = null;
exports.isLoggedIn = false;
});
};
exports.logout = logout;
/** A method, using puppeteer, to get captcha tokens. */
//eslint-disable-next-line no-async-promise-executor
const getCaptcha = () => new Promise((resolve) => __awaiter(void 0, void 0, void 0, function* () {
const browser = yield puppeteer.launch({ headless: false, ignoreDefaultArgs: true });
const page = (yield browser.pages())[0];
yield page.setRequestInterception(true);
page.on('request', req => {
if (req.method() === 'POST' && req.url() === 'https://nhentai.net/login/') {
req.abort();
browser.close();
resolve(new URLSearchParams(req.postData()).get('g-recaptcha-response'));
}
else {
req.continue();
}
});
yield page.goto('https://nhentai.net/login/');
page.$$eval('.inputs .row', elems => elems.forEach(e => e.remove()));
}));
exports.getCaptcha = getCaptcha;