Optionally receiving avtocod data from clients
This commit is contained in:
parent
c89ce6071c
commit
33e64ac412
@ -4,27 +4,12 @@ import DebugInfo from '../models/DebugInfo.js';
|
|||||||
import { Centrifuge } from 'centrifuge';
|
import { Centrifuge } from 'centrifuge';
|
||||||
import WebSocket from 'ws';
|
import WebSocket from 'ws';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
import crypto from 'crypto';
|
|
||||||
|
|
||||||
const baseUrl = 'https://avtocod.ru/api/v4';
|
const baseUrl = 'https://avtocod.ru/api/v4';
|
||||||
const tokenRefreshUrl = 'https://avtocod.ru/api/centrifuge/refresh';
|
const tokenRefreshUrl = 'https://avtocod.ru/api/centrifuge/refresh';
|
||||||
const minimalVersionUrl = 'https://avtocod.ru/api/v4/info/minimal_version?platform=ios'; // Just for getting cookies
|
|
||||||
const userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:138.0) Gecko/20100101 Firefox/138.0';
|
const userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:138.0) Gecko/20100101 Firefox/138.0';
|
||||||
|
|
||||||
const sign = {
|
|
||||||
version: '4.6.2',
|
|
||||||
sign: '3343fc07110c5df19b840d688bc45b78',
|
|
||||||
platform: 'Win32',
|
|
||||||
browsers: ['chrome'],
|
|
||||||
score: 0.6,
|
|
||||||
};
|
|
||||||
|
|
||||||
let deviceToken = uuidv4().replaceAll('-', '').toUpperCase();
|
let deviceToken = uuidv4().replaceAll('-', '').toUpperCase();
|
||||||
var cookie = null;
|
|
||||||
|
|
||||||
setInterval(() => {
|
|
||||||
cookie = null;
|
|
||||||
}, 30*60*1000);
|
|
||||||
|
|
||||||
const myWs = function (options) {
|
const myWs = function (options) {
|
||||||
return class wsClass extends WebSocket {
|
return class wsClass extends WebSocket {
|
||||||
@ -34,91 +19,24 @@ const myWs = function (options) {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
function findValue(key, str) {
|
|
||||||
|
|
||||||
let result = str.match(new RegExp(`"(${key}=.*?)"`));
|
|
||||||
if(result == null) {
|
|
||||||
throw Error(`Cannot find ${key} data`);
|
|
||||||
}
|
|
||||||
return result[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSpsnCookie(html, sign) {
|
|
||||||
|
|
||||||
let signStr = JSON.stringify(sign);
|
|
||||||
let signHex = Buffer.from(signStr).toString('hex');
|
|
||||||
|
|
||||||
let spsnStart = findValue('spsn', html);
|
|
||||||
return spsnStart + signHex + ';';
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSpidCookie(html) {
|
|
||||||
|
|
||||||
return findValue('spid', html) + ';';
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSpscCookie(html) {
|
|
||||||
|
|
||||||
let keyResult = html.match(/-----BEGIN.*?KEY-----.*?-----END.*?KEY-----/s);
|
|
||||||
if(keyResult == null) {
|
|
||||||
throw Error('Cannot find key for decrypting spsc data');
|
|
||||||
}
|
|
||||||
let key = keyResult[0];
|
|
||||||
|
|
||||||
let srcResult = html.match(/decrypt\("(.*?)"/);
|
|
||||||
if(srcResult == null) {
|
|
||||||
throw Error('Cannot find spsc data');
|
|
||||||
}
|
|
||||||
let dataToDecrypt = Buffer.from(srcResult[1], 'hex');
|
|
||||||
|
|
||||||
let decrypted = crypto.privateDecrypt({
|
|
||||||
key,
|
|
||||||
padding: crypto.constants.RSA_PKCS1_PADDING
|
|
||||||
}, dataToDecrypt);
|
|
||||||
|
|
||||||
return 'spsc=' + decrypted.toString() + ';';
|
|
||||||
}
|
|
||||||
|
|
||||||
function fromBase64(data) {
|
function fromBase64(data) {
|
||||||
return Buffer.from(data, 'base64').toString('binary');
|
return Buffer.from(data, 'base64').toString('binary');
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getPage(url) {
|
async function getPage(url) {
|
||||||
let result = await fetch(url, {
|
let result = await fetch(url, {
|
||||||
headers: {
|
|
||||||
'User-Agent': userAgent,
|
|
||||||
'cookie': await getCookies()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return await result.text();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getCookies() {
|
|
||||||
if(cookie != null) {
|
|
||||||
return cookie;
|
|
||||||
}
|
|
||||||
|
|
||||||
let result = await fetch(minimalVersionUrl, {
|
|
||||||
headers: {
|
headers: {
|
||||||
'User-Agent': userAgent
|
'User-Agent': userAgent
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return await result.text();
|
||||||
let html = await result.text();
|
|
||||||
|
|
||||||
let spsnCookie = getSpsnCookie(html, sign);
|
|
||||||
let spidCookie = getSpidCookie(html);
|
|
||||||
let spscCookie = getSpscCookie(html);
|
|
||||||
cookie = [spsnCookie, spidCookie, spscCookie].join(' ');
|
|
||||||
return cookie;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getJson(url) {
|
async function getJson(url) {
|
||||||
|
|
||||||
let jsonResult = await fetch(url, {
|
let jsonResult = await fetch(url, {
|
||||||
headers: {
|
headers: {
|
||||||
'User-Agent': userAgent,
|
'User-Agent': userAgent
|
||||||
'cookie': await getCookies()
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return await jsonResult.json();
|
return await jsonResult.json();
|
||||||
@ -145,8 +63,7 @@ function getToken(ctx) {
|
|||||||
fetch(tokenRefreshUrl, {
|
fetch(tokenRefreshUrl, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json'
|
||||||
'cookie': cookie
|
|
||||||
}),
|
}),
|
||||||
body: JSON.stringify(ctx)
|
body: JSON.stringify(ctx)
|
||||||
})
|
})
|
||||||
@ -211,13 +128,17 @@ function waitForReport(centrifugoConfig, channel) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class AvtocodProvider {
|
class AvtocodProvider {
|
||||||
static async getReport(number, type) {
|
static async getReport(number, type, htmlReport) {
|
||||||
try {
|
try {
|
||||||
|
let html = '';
|
||||||
|
if(htmlReport) {
|
||||||
|
html = Buffer.from(htmlReport, 'base64').toString('utf-8');
|
||||||
|
} else {
|
||||||
let numberType = type ?? 'GRZ';
|
let numberType = type ?? 'GRZ';
|
||||||
let url = `${baseUrl}/auto/generate?number=${encodeURIComponent(number)}&device_token=${deviceToken}&type=${numberType}`;
|
let url = `${baseUrl}/auto/generate?number=${encodeURIComponent(number)}&device_token=${deviceToken}&type=${numberType}`;
|
||||||
let resp = await getJson(url);
|
let resp = await getJson(url);
|
||||||
|
html = await getPage(resp.report_uri);
|
||||||
let html = await getPage(resp.report_uri);
|
}
|
||||||
|
|
||||||
let result = html.match(/<meta name="app-version-hash" content="(.*?)" \/>/);
|
let result = html.match(/<meta name="app-version-hash" content="(.*?)" \/>/);
|
||||||
if(result == null) {
|
if(result == null) {
|
||||||
|
|||||||
2
index.js
2
index.js
@ -23,7 +23,7 @@ app.use(responseTime(function (req, res, time) {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
app.use(compression());
|
app.use(compression());
|
||||||
app.use(express.json());
|
app.use(express.json({ limit: '5Mb' }));
|
||||||
app.use(expressMongoDb(process.env.MONGO_CONNECTION_STRING));
|
app.use(expressMongoDb(process.env.MONGO_CONNECTION_STRING));
|
||||||
app.use(bearerToken());
|
app.use(bearerToken());
|
||||||
app.use(jwt({ secret: process.env.JWT_SECRET_AUTH, exclude: ['/user/signup', '/user/login', '/vehicles/shared_report'] }));
|
app.use(jwt({ secret: process.env.JWT_SECRET_AUTH, exclude: ['/user/signup', '/user/login', '/vehicles/shared_report'] }));
|
||||||
|
|||||||
@ -19,7 +19,7 @@ const makeError = (error) => ({ success: false, error });
|
|||||||
router.post('/check', async (req, res) => {
|
router.post('/check', async (req, res) => {
|
||||||
const number = req.body.number.replace(/ /g, '').toUpperCase();
|
const number = req.body.number.replace(/ /g, '').toUpperCase();
|
||||||
const type = req.body.type;
|
const type = req.body.type;
|
||||||
const { googleIdToken, forceUpdate, notes, events } = req.body;
|
const { googleIdToken, forceUpdate, notes, events, avtocodReport } = req.body;
|
||||||
const { email } = req.user;
|
const { email } = req.user;
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
@ -54,7 +54,7 @@ router.post('/check', async (req, res) => {
|
|||||||
res.send({ success: true, data: vehicles[0] });
|
res.send({ success: true, data: vehicles[0] });
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
let autocodPromise = AvtocodProvider.getReport(number, type);
|
let autocodPromise = AvtocodProvider.getReport(number, type, avtocodReport);
|
||||||
let all = [autocodPromise];
|
let all = [autocodPromise];
|
||||||
|
|
||||||
if (googleIdToken) {
|
if (googleIdToken) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user