Skip to content

Commit

Permalink
prepare the code for v7 version, -- v8 could be removing support for …
Browse files Browse the repository at this point in the history
…this since they flagged some code as legacy, but this will work for now.
abdumu committed Sep 14, 2024
1 parent 6a6fe7a commit 759f590
Showing 10 changed files with 8,967 additions and 2,350 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -159,3 +159,9 @@ deploy/\*\*
# forge

out/
jarir_dump/
flows_jarir
jarir_dump.zip
jarir.har
code.c
e
68 changes: 62 additions & 6 deletions cli/backend/api-calls.js
Original file line number Diff line number Diff line change
@@ -53,8 +53,8 @@ const http = axios.create({
});
http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
http.defaults.headers.post["User-Agent"] = "okhttp/4.3.1";
http.defaults.headers.post["Host"] = "api.jarirreader.com";
// http.defaults.headers.post["Host"] = "api.yaqut.me"; //rufoof
http.defaults.headers.post["Host"] = "api.jarirreader.com";// hapi.jarirreader.rufoof.com for staging
// http.defaults.headers.post["Host"] = "api.yaqut.me"; //hapi.rufoof.com for staging. rufoof

const getInitialAuth = () => {
return new Promise((resolve, reject) => {
@@ -63,8 +63,9 @@ const getInitialAuth = () => {
resolve([settings.initialToken, settings.expires]);
}


http.post(
"/v5.0.1/login/token",
"/v7/login/token",
querystring.stringify({
grant_type: "client_credentials",
client_secret: "cfb6113dfb4ccba4da7fd18c4dd8da6d",
@@ -142,12 +143,13 @@ const auth = (email, password) => {
email: settings.email,
});


const deviceUID = settings.deviceUID || uuid().replace("-", "");
const deviceName = settings.deviceName || randomCompany();
const x_access = xAccess();

http.post(
"v5.0.1/login/login",
"v7/login/login",
querystring.stringify({
access_token: initialToken,
deviceUID: deviceUID,
@@ -209,7 +211,7 @@ const getUserBooks = () => {
(settings.hasOwnProperty("books") && settings.books.cached_at < Date.now() - 1000 * 60 * 10)
) {
http.post(
"/v5.0.1/books/get-user-books",
"/v7/books/get-user-books",
querystring.stringify({
access_token: authResult.auth,
Platform: "Android",
@@ -227,6 +229,7 @@ const getUserBooks = () => {
var books = [];
if (!blank(response.data) && response.data.hasOwnProperty("result")) {
var bookPath, book;

response.data.result.forEach((item, index) => {
book = Book(
item["book_id"],
@@ -238,6 +241,11 @@ const getUserBooks = () => {
item["cover_thumb_url"] || null,
item["file_type"],
item["cover_thumb_url"],
item["book_access"],
item["book_file_md5"],
item["bookfile_id"],
item["latest_file_id"],
item["size"],
false
);
bookPath = pathResolve(
@@ -330,8 +338,9 @@ const downloadBook = (book) => {
reject(err);
});

//todo 403.
axios({
url: book.url,
url: book.url.replace("_sample", ""),
method: "GET",
responseType: "stream",
headers: {
@@ -370,9 +379,56 @@ const downloadAndGenerateBook = async (book) => {
});
};

//logout
const logout = () => {
return new Promise((resolve, reject) => {
var settings = getSettings();

if (blank(settings) || !settings.hasOwnProperty("auth")) {
resolve(true);
return;
}


http.post(
"/v7/logout",
querystring.stringify({
access_token: getSettings("auth"),
deviceUID: getSettings("deviceUID"),
appId: "1",
Platform: "Android",
}),
{
timeout: 10000,
headers: {
"X-Request-Check": getRequestCheck(),
},
}
)
.then((response) => {
if (response.data !== null && response.data.hasOwnProperty("result")) {
resolve(response.data.result);
return;
}

const err = new Error("(503) Could not logout! check your info!");
err.code = 503;

reject(err);
})
.catch((error) => {
const err = new Error("(504) Could not logout! check your info! \n error:" + error.message);
err.code = 504;
reject(err);
});
});
};


module.exports = {
auth,
getUserBooks,
downloadBook,
downloadAndGenerateBook,
logout
};
13 changes: 10 additions & 3 deletions cli/backend/book.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const arabicTrans = require("./transliteration");

function Book(id, name, url, index, publisher, authors, cover, type, thumb, bookPath) {
function Book(id, name, url, index, publisher, authors, cover, type, thumb, access, file_md5, file_id, latest_file_id, size, bookPath) {
if (typeof id === "object") {
Object.assign(this, id);
return this;
@@ -10,7 +10,7 @@ function Book(id, name, url, index, publisher, authors, cover, type, thumb, book
if (typeof id === "object") {
return new Book(id);
} else {
return new Book(id, name, url, index, publisher, authors, cover, type, thumb, bookPath);
return new Book(id, name, url, index, publisher, authors, cover, type, thumb, access, file_md5, file_id, latest_file_id, size, bookPath);
}
}

@@ -21,7 +21,7 @@ function Book(id, name, url, index, publisher, authors, cover, type, thumb, book
this.id = id;
this.value = index;
this.title = name;
this.url = url;
this.url = url; // this is a sample now
this.type = type;
this.short = this.id;
this.publisher = publisher;
@@ -30,6 +30,13 @@ function Book(id, name, url, index, publisher, authors, cover, type, thumb, book
this.thumb = thumb;
this.bookPath = bookPath;
this.name = this.id + { pdf: "🟥", epub: "📗", mp3: "🔉 mp3", "-": "" }[this.type] + ": " + arabicTrans(this.title) + " (" + this.title + ")";
//new items
this.access = access || 0;
this.file_md5 = file_md5 || "";
this.file_id = file_id || 0;
this.latest_file_id = latest_file_id || 0;
this.size = size || 0;

}

Book.prototype.urlFilename = function urlFilename() {
41 changes: 36 additions & 5 deletions cli/backend/decrypt.js
Original file line number Diff line number Diff line change
@@ -3,7 +3,8 @@ const bottomInfo = require("./bottom-info");
const StreamZip = require("node-stream-zip");

const { resolve: pathResolve } = require("path");
const Crypto = require("crypto");
// const Crypto = require("crypto");
const CryptoJS = require("crypto-js");
const { inflateSync } = require("zlib");
const { getAppDataPath } = require("./cross-platform");

@@ -82,18 +83,48 @@ const unzipBook = (book) => {

const decryptBinary = (file) => {
const key = new Int8Array(Buffer.from([115, -36, 110, -93, 78, -22, 63, -71, 97, -126, 86, 66, -36, 46, 13, -96]));
const cipher = Crypto.createDecipheriv("rc4", key, "");
let outputBuffer = cipher.update(readFileSync(file), null, "binary") + cipher.final("binary");
// const cipher = Crypto.createDecipheriv("rc4", key, "");
// let outputBuffer = cipher.update(readFileSync(file), null, "binary") + cipher.final("binary");

const keyHex = Array.from(keyArray).map(byte => {
const hex = (byte & 0xff).toString(16);
return hex.length === 1 ? '0' + hex : hex;
}).join('');

const keyNew = CryptoJS.enc.Hex.parse(keyHex);
const encryptedData = readFileSync(file, 'binary');
const encryptedWordArray = CryptoJS.enc.Latin1.parse(encryptedData);
const decrypted = CryptoJS.RC4.decrypt(
{ ciphertext: encryptedWordArray },
key
);

const outputBuffer = CryptoJS.enc.Latin1.stringify(decrypted);

writeFileSync(file + "x", outputBuffer, {
encoding: "binary",
});
};

const decryptText = async (file) => {
const key = new Int8Array(Buffer.from([115, -36, 110, -93, 78, -22, 63, -71, 97, -126, 86, 66, -36, 46, 13, -96]));
const cipher = Crypto.createDecipheriv("rc4", key, "");
// const cipher = Crypto.createDecipheriv("rc4", key, "");
// let outputBuffer = cipher.update(readFileSync(file), null, "binary") + cipher.final("binary");
const keyHex = Array.from(key).map(byte => {
const hex = (byte & 0xff).toString(16);
return hex.length === 1 ? '0' + hex : hex;
}).join('');

const keyNew = CryptoJS.enc.Hex.parse(keyHex);
const encryptedData = readFileSync(file, 'binary');
const encryptedWordArray = CryptoJS.enc.Latin1.parse(encryptedData);
const decrypted = CryptoJS.RC4.decrypt(
{ ciphertext: encryptedWordArray },
keyNew
);

const outputBuffer = CryptoJS.enc.Latin1.stringify(decrypted);

let outputBuffer = cipher.update(readFileSync(file), null, "binary") + cipher.final("binary");
writeFileSync(file + "_x", outputBuffer, {
encoding: "binary",
});
32 changes: 27 additions & 5 deletions cli/backend/helpers.js
Original file line number Diff line number Diff line change
@@ -20,7 +20,29 @@ const blank = (parameter) => {
};

const randomCompany = () => {
items = ["Google Nexus 6", "Google Pixel 2", "Google Pixel 3", "Samsung Note 4", "Samsung S9", "Samsung S20", "Samsung S10"];
const items = [
"Google Nexus 6",
"Google Pixel 2",
"Google Pixel 3",
"Google Pixel 4",
"Google Pixel 5",
"Google Pixel 6",
"Google Pixel 7",
"Google Pixel 8",
"Samsung Note 4",
"Samsung Galaxy S9",
"Samsung Galaxy S10",
"Samsung Galaxy S20",
"Samsung Galaxy S21",
"Samsung Galaxy S22",
"Samsung Galaxy S23",
"Samsung Galaxy Note 20",
"OnePlus 7",
"OnePlus 8",
"OnePlus 9",
"OnePlus 10",
"OnePlus 11"
];
return items[Math.floor(Math.random() * items.length)];
};

@@ -131,12 +153,12 @@ const openExplorer = (path, callback) => {
const clearResidue = (book) => {
const path = pathResolve(getAppDataPath("jarir-cli"), "books", "" + book.id);
if (existsSync(path + ".zip")) {
unlinkSync(path + ".zip");
// unlinkSync(path + ".zip");
}
if (existsSync(path)) {
rmdirSync(path, {
recursive: true,
});
// rmdirSync(path, {
// recursive: true,
// });
}
};

4 changes: 2 additions & 2 deletions cli/index2.js
Original file line number Diff line number Diff line change
@@ -6,9 +6,9 @@ const bookGenerator = require("./backend/book-generator");

const inquirerErrorLog = (error) => {
if (error.isTtyError) {
inquirerErrorLog("Prompt couldn't be rendered in the current environment.\n");
console.error("Prompt couldn't be rendered in the current environment.\n");
} else {
inquirerErrorLog((typeof error === "object" ? error.message : error) + "\n");
console.error((typeof error === "object" ? error.message : error) + "\n");
}
process.exit();
};
7,174 changes: 7,174 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@
"description": "تحميل كتب قارئ جرير وتحويلها لكتب عادية غير مشفرة",
"main": "ui/index.js",
"scripts": {
"start": "electron-forge start",
"start": "electron-forge start -- --no-sandbox",
"package": "electron-forge package",
"make": "electron-forge make",
"publish": "electron-forge publish",
@@ -21,6 +21,7 @@
"forge": "./forge.config.js"
},
"dependencies": {
"crypto-js": "^4.2.0",
"electron-squirrel-startup": "^1.0.0",
"jarir-cli": "file:./cli"
},
3 changes: 2 additions & 1 deletion ui/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const { app, BrowserWindow, ipcMain, shell, dialog } = require("electron");
const { existsSync } = require("fs");
const path = require("path");
const { auth, getUserBooks, downloadAndGenerateBook, getAppDataPath, getSettings, logoutFromApp, initiateCli } = require("jarir-cli");
const { auth, getUserBooks, downloadAndGenerateBook, getAppDataPath, getSettings, logoutFromApp, initiateCli, logout } = require("jarir-cli");

if (require("electron-squirrel-startup")) {
app.quit();
@@ -65,6 +65,7 @@ const createWindow = () => {
return new Promise((resolve) => resolve(false));
}
} else if (action === "logout") {
logout(); // to remove device from devices list, since jarir app have devices limit
logoutFromApp().then(() => {
mainWindow.close();
});
3,973 changes: 1,646 additions & 2,327 deletions yarn.lock

Large diffs are not rendered by default.

0 comments on commit 759f590

Please sign in to comment.