Add open js project.

main
catvod 3 years ago committed by GitHub
parent 065a42ccf1
commit 3e1ec9f555
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      open/README.md
  2. 275
      open/alist_open.js
  3. 8
      open/app.js
  4. 61
      open/build.js
  5. 70
      open/config_open.json
  6. 337
      open/kunyu77_open.js
  7. 1
      open/lib/cat.js
  8. 47
      open/lib/similarity.js
  9. 342
      open/package-lock.json
  10. 21
      open/package.json
  11. 9
      open/test.js
  12. 72
      open/testAlist.js
  13. 51
      open/testVideo.js
  14. 266
      open/wrapper/index.js

@ -0,0 +1,5 @@
`npm install`
`node test.js`
`node build.js`

@ -0,0 +1,275 @@
import { _ } from './lib/cat.js';
import { findBestLCS } from './lib/similarity.js';
const http = async function (url, options = {}) {
if (options.method == 'POST' && options.data) {
options.body = JSON.stringify(options.data);
options.headers = Object.assign({ 'content-type': 'application/json' }, options.headers);
}
const res = await req(url, options);
res.json = () => (res.content ? JSON.parse(res.content) : null);
res.text = () => res.content;
return res;
};
['get', 'post'].forEach((method) => {
http[method] = function (url, options = {}) {
return http(url, Object.assign(options, { method: method.toUpperCase() }));
};
});
const __drives = {};
const __subtitle_cache = {};
async function get_drives_path(tid) {
const index = tid.indexOf('/', 1);
const name = tid.substring(1, index);
const path = tid.substring(index);
return { drives: await get_drives(name), path };
}
async function get_drives(name) {
const { settings, api, server } = __drives[name];
if (settings.v3 == null) {
//获取 设置
settings.v3 = false;
const data = (await http.get(server + '/api/public/settings')).json().data;
if (_.isArray(data)) {
settings.title = data.find((x) => x.key == 'title')?.value;
settings.v3 = false;
settings.version = data.find((x) => x.key == 'version')?.value;
settings.enableSearch = data.find((x) => x.key == 'enable search')?.value == 'true';
} else {
settings.title = data.title;
settings.v3 = true;
settings.version = data.version;
settings.enableSearch = false; //v3 没有找到 搜索配置
}
//不同版本 接口不一样
api.path = settings.v3 ? '/api/fs/list' : '/api/public/path';
api.file = settings.v3 ? '/api/fs/get' : '/api/public/path';
api.search = settings.v3 ? '/api/public/search' : '/api/public/search';
api.other = settings.v3 ? '/api/fs/other' : null;
}
return __drives[name];
}
let siteKey = '';
let siteType = 0;
function init(cfg) {
siteKey = cfg.skey;
siteType = cfg.stype;
cfg.ext.forEach(
(item) =>
(__drives[item.name] = {
name: item.name,
server: item.server.endsWith('/') ? item.server.substring(0, item.server.length - 1) : item.server,
startPage: item.startPage || '/', //首页
showAll: item.showAll === true, //默认只显示 视频和文件夹,如果想显示全部 showAll 设置true
params: item.params || {},
_path_param: item.params
? _.sortBy(Object.keys(item.params), function (x) {
return -x.length;
})
: [],
settings: {},
api: {},
getParams(path) {
const key = this._path_param.find((x) => path.startsWith(x));
return Object.assign({}, this.params[key], { path });
},
async getPath(path) {
const res = (await http.post(this.server + this.api.path, { data: this.getParams(path) })).json();
return this.settings.v3 ? res.data.content : res.data.files;
},
async getFile(path) {
const res = (await http.post(this.server + this.api.file, { data: this.getParams(path) })).json();
const data = this.settings.v3 ? res.data : res.data.files[0];
if (!this.settings.v3) data.raw_url = data.url; //v2 的url和v3不一样
return data;
},
async getOther(method, path) {
const data = this.getParams(path);
data.method = method;
const res = (await http.post(this.server + this.api.other, { data: data })).json();
return res;
},
isFolder(data) {
return data.type == 1;
},
isVideo(data) {
//判断是否是 视频文件
return this.settings.v3 ? data.type == 2 : data.type == 3;
},
isSubtitle(data) {
if (data.type == 1) return false;
const ext = ['.srt', '.ass', '.scc', '.stl', '.ttml'];
return ext.some((x) => data.name.endsWith(x));
},
getType(data) {
const isVideo = this.isVideo(data);
return this.isFolder(data) ? 0 : isVideo ? 10 : 1;
},
getPic(data) {
let pic = this.settings.v3 ? data.thumb : data.thumbnail;
return pic || (this.isFolder(data) ? 'http://img1.3png.com/281e284a670865a71d91515866552b5f172b.png' : '');
},
getSize(data) {
let sz = data.size || 0;
if (sz <= 0) return '';
let filesize = '';
if (sz > 1024 * 1024 * 1024 * 1024.0) {
sz /= 1024 * 1024 * 1024 * 1024.0;
filesize = 'TB';
} else if (sz > 1024 * 1024 * 1024.0) {
sz /= 1024 * 1024 * 1024.0;
filesize = 'GB';
} else if (sz > 1024 * 1024.0) {
sz /= 1024 * 1024.0;
filesize = 'MB';
} else {
sz /= 1024.0;
filesize = 'KB';
}
return sz.toFixed(2) + filesize;
},
getRemark(data) {
return '';
},
})
);
}
async function dir(dir, pg) {
for (const k in __subtitle_cache) {
delete __subtitle_cache[k];
}
pg = pg || 1;
if (pg == 0) pg == 1;
if (dir === '/' || dir === '') {
const result = _.map(__drives, function (d) {
return { name: d.name, path: '/' + d.name + d.startPage, type: 0, thumb: '' };
});
return JSON.stringify({
parent: '',
page: pg,
pagecount: pg,
list: result,
});
}
let { drives, path } = await get_drives_path(dir);
const id = dir.endsWith('/') ? dir : dir + '/';
const list = await drives.getPath(path);
let subtList = [];
let videos = [];
let allList = [];
list.forEach((item) => {
if (drives.isSubtitle(item)) subtList.push(item.name);
const isVideo = drives.isVideo(item);
if (!drives.showAll && !drives.isFolder(item) && !isVideo) return;
const file = {
name: item.name.replaceAll('$', '_').replaceAll('#', '_'),
path: id + item.name + (drives.isFolder(item) ? '/' : ''),
thumb: drives.getPic(item),
type: drives.getType(item),
size: drives.getSize(item),
remark: drives.getRemark(item),
};
if (drives.isVideo(item)) videos.push(file);
allList.push(file);
});
if (subtList.length > 0) {
videos.forEach((item) => {
var sbust = findBestLCS(item.name, subtList);
if (sbust.bestMatch) __subtitle_cache[item.path] = [id + sbust.bestMatch.target];
});
}
return JSON.stringify({
parent: id,
page: pg,
pagecount: pg,
list: allList,
});
}
async function file(file) {
let { drives, path } = await get_drives_path(file);
const item = await drives.getFile(path);
const subs = [];
if (__subtitle_cache[file]) {
for (const sub of __subtitle_cache[file]) {
try {
let subP = await get_drives_path(sub);
const subItem = await drives.getFile(subP.path);
subs.push(subItem.raw_url);
} catch (error) {}
}
}
if (item.provider === 'AliyundriveShare2Open' && drives.api.other) {
const urls = ['原画', item.raw_url];
try {
const res = await drives.getOther('video_preview', path);
for (const live of res.data.video_preview_play_info.live_transcoding_task_list) {
if (live.status === 'finished') {
urls.push(live.template_id);
urls.push(live.url);
}
}
} catch (error) {}
const result = {
name: item.name,
url: urls,
size: drives.getSize(item),
remark: drives.getRemark(item),
header: {},
extra: {
subt: subs,
},
};
return JSON.stringify(result);
} else if (item.provider === '123Pan') {
let url = item.raw_url;
try {
url = (await http.get(url)).json().data.redirect_url;
} catch (error) {}
const result = {
name: item.name,
url: url,
size: drives.getSize(item),
remark: drives.getRemark(item),
header: {},
extra: {
subt: subs,
},
};
return JSON.stringify(result);
} else {
const result = {
name: item.name,
url: item.raw_url,
size: drives.getSize(item),
remark: drives.getRemark(item),
header: {},
extra: {
subt: subs,
},
};
return JSON.stringify(result);
}
}
function search(wd) {
return JSON.stringify({
list: [],
});
}
export function __jsEvalReturn() {
return {
init: init,
dir: dir,
file: file,
search: search,
};
}

@ -0,0 +1,8 @@
function __jsEvalReturn() {
return {
isVideoFormat: function (url) {
return !0;
},
};
}
export { __jsEvalReturn };

@ -0,0 +1,61 @@
import fs from 'node:fs';
import path from 'path';
import uglifyjs from 'uglify-js';
const copySpider = ['app', 'kunyu77_open', 'alist_open'];
const root = process.cwd();
const src = path.join(root);
const out = path.join(root, 'dist');
function minify(s, d) {
var jsContent = fs.readFileSync(s).toString();
jsContent = jsContent.replace('./lib/cat.js', 'assets://js/lib/cat.js');
jsContent = jsContent.replace('./cat.js', 'assets://js/lib/cat.js');
jsContent = uglifyjs.minify(jsContent, {
mangle: false,
});
fs.writeFileSync(d, jsContent.code);
}
function listAllFiles(dirPath, arrayOfFiles) {
var files = fs.readdirSync(dirPath);
arrayOfFiles = arrayOfFiles || [];
files.forEach(function (file) {
if (fs.statSync(dirPath + '/' + file).isDirectory()) {
arrayOfFiles = listAllFiles(dirPath + '/' + file, arrayOfFiles);
} else {
arrayOfFiles.push(path.join(dirPath, '/', file));
}
});
return arrayOfFiles;
}
function src2Out() {
if (fs.existsSync(out)) fs.rmSync(out, { recursive: true, force: true });
fs.mkdirSync(out, { recursive: true });
const libSrc = path.join(src, 'lib');
const libOut = path.join(out, 'lib');
fs.mkdirSync(libOut, { recursive: true });
const libs = listAllFiles(libSrc);
for (let index = 0; index < libs.length; index++) {
const element = libs[index];
const relative = path.relative(libSrc, element);
minify(element, path.join(libOut, relative));
}
for (const sp of copySpider) {
minify(path.join(src, sp + '.js'), path.join(out, sp + '.js'));
}
}
src2Out();
fs.copyFileSync(path.join(src, 'config_open.json'), path.join(out, 'config_open.json'));
console.log('done');

@ -0,0 +1,70 @@
{
"video": {
"sites": [
{
"key": "kunyu77",
"name": "琨娱七七",
"type": 3,
"api": "assets://js/kunyu77_open.js"
}
]
},
"pan": {
"sites": [
{
"key": "alist",
"name": "Alist",
"type": 40,
"api": "assets://js/alist_open.js",
"ext": [
{
"name": "🙋丫仙女",
"server": "http://alist.xiaoya.pro/",
"startPage": "/",
"showAll": false,
"search": true,
"headers": {
"Authorization": ""
},
"params": {
"/abc": {
"password": "123"
},
"/abc/abc": {
"password": "123"
}
}
},
{
"name": "🐋一只鱼",
"server": "https://alist.youte.ml"
},
{
"name": "🌊七米蓝",
"server": "https://al.chirmyram.com"
},
{
"name": "🐉神族九帝",
"server": "https://alist.shenzjd.com"
},
{
"name": "☃姬路白雪",
"server": "https://pan.jlbx.xyz"
},
{
"name": "✨星梦",
"server": "https://pan.bashroot.top"
},
{
"name": "💢repl",
"server": "https://ali.liucn.repl.co"
},
{
"name": "💦讯维云盘",
"server": "https://pan.xwbeta.com"
}
]
}
]
}
}

@ -0,0 +1,337 @@
import { Crypto, dayjs, jinja2, Uri, _ } from './lib/cat.js';
let key = 'kunyu77';
let url = 'http://api.tyun77.cn';
let device = {};
let timeOffset = 0;
let siteKey = '';
let siteType = 0;
async function request(reqUrl, agentSp) {
let sj = dayjs().unix() - timeOffset;
let uri = new Uri(reqUrl);
uri.addQueryParam('pcode', '010110005');
uri.addQueryParam('version', '2.1.6');
uri.addQueryParam('devid', device.id);
uri.addQueryParam('package', 'com.sevenVideo.app.android');
uri.addQueryParam('sys', 'android');
uri.addQueryParam('sysver', device.release);
uri.addQueryParam('brand', device.brand);
uri.addQueryParam('model', device.model.replaceAll(' ', '_'));
uri.addQueryParam('sj', sj);
let keys = [];
for (var i = 0; i < uri.queryPairs.length; i++) {
keys.push(uri.queryPairs[i][0]);
}
keys = _.sortBy(keys, function (name) {
return name;
});
let tkSrc = uri.path();
for (let k of keys) {
let v = uri.getQueryParamValue(k);
v = encodeURIComponent(v);
tkSrc += v;
}
tkSrc += sj;
tkSrc += 'XSpeUFjJ';
console.log(tkSrc);
let tk = Crypto.MD5(tkSrc).toString().toLowerCase();
console.log(tk);
let header = {
'user-agent': agentSp || 'okhttp/3.12.0',
t: sj,
TK: tk,
};
let res = await req(uri.toString(), {
headers: header,
});
let serverTime = res.headers.date; // dart all response header key is lowercase
let content = res.content;
let serverTimeS = dayjs(serverTime).unix();
timeOffset = dayjs().unix() - serverTimeS;
// console.log(content);
return content;
}
async function init(cfg) {
siteKey = cfg.skey;
siteType = cfg.stype;
var deviceKey = 'device';
var deviceInfo = await local.get(key, deviceKey);
if (deviceInfo.length > 0) {
try {
device = JSON.parse(deviceInfo);
} catch (error) {}
}
if (_.isEmpty(device)) {
device = randDevice();
device.id = randStr(32).toLowerCase();
device.ua = 'Dalvik/2.1.0 (Linux; U; Android ' + device.release + '; ' + device.model + ' Build/' + device.buildId + ')';
await local.set(key, deviceKey, JSON.stringify(device));
}
}
async function home(filter) {
let data = JSON.parse(await request(url + '/api.php/provide/filter')).data;
let classes = [];
let filterObj = {};
let filterAll = [];
for (const key in data) {
classes.push({
type_id: key,
type_name: data[key][0].cat,
});
if (!filter) continue;
try {
let typeId = key.toString();
if (_.isEmpty(filterAll)) {
let filterData = JSON.parse(await request(url + '/api.php/provide/searchFilter?type_id=0&pagenum=1&pagesize=1')).data.conditions;
// console.log(filterData);
// 年份
let year = {
key: 'year',
name: '年份',
init: '',
};
let yearValues = [];
yearValues.push({ n: '全部', v: '' });
filterData.y.forEach((e) => {
yearValues.push({ n: e.name, v: e.value });
});
year['value'] = yearValues;
// 地区
let area = {
key: 'area',
name: '地区',
init: '',
};
let areaValues = [];
areaValues.push({ n: '全部', v: '' });
filterData.a.forEach((e) => {
areaValues.push({ n: e.name, v: e.value });
});
area['value'] = areaValues;
// 类型
let type = {
key: 'category',
name: '类型',
init: '',
};
let typeValues = [];
typeValues.push({ n: '全部', v: '' });
filterData.scat.forEach((e) => {
typeValues.push({ n: e.name, v: e.value });
});
type['value'] = typeValues;
filterAll.push(year, area, type);
}
if (!_.isEmpty(filterAll)) {
filterObj[typeId] = filterAll;
}
} catch (e) {
console.log(e);
}
}
// console.log(classes);
// console.log(filterObj);
return JSON.stringify({
class: classes,
filters: filterObj,
});
}
async function homeVod() {
let data = JSON.parse(await request(url + '/api.php/provide/homeBlock?type_id=0')).data;
let blocks = data.blocks;
let videos = [];
for (const block of blocks) {
let name = block.block_name;
if (name.indexOf('热播') >= 0) continue;
let contents = block.contents;
for (const content of contents) {
videos.push({
vod_id: content.id,
vod_name: content.title,
vod_pic: content.videoCover,
vod_remarks: content.msg,
});
}
}
return JSON.stringify({
list: videos,
});
}
async function category(tid, pg, filter, extend) {
let reqUrl = url + '/api.php/provide/searchFilter?type_id=' + tid + '&pagenum=' + pg + '&pagesize=24&';
reqUrl += jinja2('year={{ext.year}}&category={{ext.category}}&area={{ext.area}}', { ext: extend });
let data = JSON.parse(await request(reqUrl)).data;
let videos = [];
for (const vod of data.result) {
videos.push({
vod_id: vod.id,
vod_name: vod.title,
vod_pic: vod.videoCover,
vod_remarks: vod.msg,
});
}
return JSON.stringify({
page: parseInt(data.page),
pagecount: data.pagesize,
limit: 24,
total: data.total,
list: videos,
});
}
async function detail(id) {
let data = JSON.parse(await request(url + '/api.php/provide/videoDetail?ids=' + id)).data;
console.log(data);
let vod = {
vod_id: data.id,
vod_name: data.videoName,
vod_pic: data.videoCover,
type_name: data.subCategory,
vod_year: data.year,
vod_area: data.area,
vod_remarks: data.msg,
vod_actor: data.actor,
vod_director: data.director,
vod_content: data.brief.trim(),
};
let episodes = JSON.parse(await request(url + '/api.php/provide/videoPlaylist?ids=' + id)).data.episodes;
let playlist = {};
for (const episode of episodes) {
let playurls = episode.playurls;
for (const playurl of playurls) {
let from = playurl.playfrom;
let t = formatPlayUrl(vod.vod_name, playurl.title);
if (t.length == 0) t = playurl.title.trim();
if (!playlist.hasOwnProperty(from)) {
playlist[from] = [];
}
playlist[from].push(t + '$' + playurl.playurl);
}
}
vod.vod_play_from = _.keys(playlist).join('$$$');
let urls = _.values(playlist);
let vod_play_url = [];
for (const urlist of urls) {
vod_play_url.push(urlist.join('#'));
}
vod.vod_play_url = vod_play_url.join('$$$');
return JSON.stringify({
list: [vod],
});
}
async function play(flag, id, flags) {
try {
let data = JSON.parse(await request(url + '/api.php/provide/parserUrl?url=' + id + '&retryNum=0')).data;
let playHeader = data.playHeader;
let jxUrl = data.url;
let res = await req(jxUrl, {
headers: {
'user-agent': 'okhttp/3.12.0',
},
});
let result = jsonParse(id, JSON.parse(res.content));
result['parse'] = 0;
if (playHeader) {
result.header = _.merge(result.header, playHeader);
}
return JSON.stringify(result);
} catch (e) {
return JSON.stringify({
parse: 0,
url: id,
});
}
}
async function search(wd, quick) {
let data = JSON.parse(await request(url + '/api.php/provide/searchVideo?searchName=' + wd + '&pg=1', 'okhttp/3.12.0')).data;
let videos = [];
for (const vod of data) {
videos.push({
vod_id: vod.id,
vod_name: vod.videoName,
vod_pic: vod.videoCover,
vod_remarks: vod.msg,
});
}
return JSON.stringify({
list: videos,
});
}
const charStr = 'abacdefghjklmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789';
function randStr(len, withNum) {
var _str = '';
let containsNum = withNum === undefined ? true : withNum;
for (var i = 0; i < len; i++) {
let idx = _.random(0, containsNum ? charStr.length - 1 : charStr.length - 11);
_str += charStr[idx];
}
return _str;
}
function randDevice() {
return {
brand: 'Huawei',
model: 'HUAWEI Mate 20',
release: '10',
buildId: randStr(3, false).toUpperCase() + _.random(11, 99) + randStr(1, false).toUpperCase(),
};
}
function formatPlayUrl(src, name) {
return name
.trim()
.replaceAll(src, '')
.replace(/<|>|《|》/g, '')
.replace(/\$|#/g, ' ')
.trim();
}
function jsonParse(input, json) {
try {
let url = json.url ?? '';
if (url.startsWith('//')) {
url = 'https:' + url;
}
if (!url.startsWith('http')) {
return {};
}
let headers = json['headers'] || {};
let ua = (json['user-agent'] || '').trim();
if (ua.length > 0) {
headers['User-Agent'] = ua;
}
let referer = (json['referer'] || '').trim();
if (referer.length > 0) {
headers['Referer'] = referer;
}
return {
header: headers,
url: url,
};
} catch (error) {
console.log(error);
}
return {};
}
export function __jsEvalReturn() {
return {
init: init,
home: home,
homeVod: homeVod,
category: category,
detail: detail,
play: play,
search: search,
};
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,47 @@
function compareTwoStrings(first, second) {
if ((first = first.replace(/\s+/g, '')) === (second = second.replace(/\s+/g, ''))) return 1;
if (first.length < 2 || second.length < 2) return 0;
var firstBigrams = new Map();
for (let i = 0; i < first.length - 1; i++) {
var bigram = first.substring(i, i + 2),
count = firstBigrams.has(bigram) ? firstBigrams.get(bigram) + 1 : 1;
firstBigrams.set(bigram, count);
}
let intersectionSize = 0;
for (let i = 0; i < second.length - 1; i++) {
const bigram = second.substring(i, i + 2),
count = firstBigrams.has(bigram) ? firstBigrams.get(bigram) : 0;
0 < count && (firstBigrams.set(bigram, count - 1), intersectionSize++);
}
return (2 * intersectionSize) / (first.length + second.length - 2);
}
function findBestMatch(mainString, targetStrings) {
var ratings = [];
let bestMatchIndex = 0;
for (let i = 0; i < targetStrings.length; i++) {
var currentTargetString = targetStrings[i],
currentRating = compareTwoStrings(mainString, currentTargetString);
ratings.push({ target: currentTargetString, rating: currentRating }), currentRating > ratings[bestMatchIndex].rating && (bestMatchIndex = i);
}
return { ratings: ratings, bestMatch: ratings[bestMatchIndex], bestMatchIndex: bestMatchIndex };
}
function lcs(str1, str2) {
if (!str1 || !str2) return { length: 0, sequence: '', offset: 0 };
for (var sequence = '', str1Length = str1.length, str2Length = str2.length, num = new Array(str1Length), maxlen = 0, lastSubsBegin = 0, i = 0; i < str1Length; i++) {
for (var subArray = new Array(str2Length), j = 0; j < str2Length; j++) subArray[j] = 0;
num[i] = subArray;
}
for (var thisSubsBegin = null, i = 0; i < str1Length; i++) for (j = 0; j < str2Length; j++) str1[i] !== str2[j] ? (num[i][j] = 0) : ((num[i][j] = 0 === i || 0 === j ? 1 : 1 + num[i - 1][j - 1]), num[i][j] > maxlen && ((maxlen = num[i][j]), lastSubsBegin === (thisSubsBegin = i - num[i][j] + 1) ? (sequence += str1[i]) : ((lastSubsBegin = thisSubsBegin), (sequence = ''), (sequence += str1.substr(lastSubsBegin, i + 1 - lastSubsBegin)))));
return { length: maxlen, sequence: sequence, offset: thisSubsBegin };
}
function findBestLCS(mainString, targetStrings) {
var results = [];
let bestMatchIndex = 0;
for (let i = 0; i < targetStrings.length; i++) {
var currentTargetString = targetStrings[i],
currentLCS = lcs(mainString, currentTargetString);
results.push({ target: currentTargetString, lcs: currentLCS }), currentLCS.length > results[bestMatchIndex].lcs.length && (bestMatchIndex = i);
}
return { allLCS: results, bestMatch: results[bestMatchIndex], bestMatchIndex: bestMatchIndex };
}
export { compareTwoStrings, findBestMatch, findBestLCS };

@ -0,0 +1,342 @@
{
"name": "CatVodOpenJSSpider",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "CatVodOpenJSSpider",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"axios": "^1.4.0",
"qs": "^6.11.2"
},
"devDependencies": {
"@types/node": "^20.1.5",
"uglify-js": "^3.17.4"
}
},
"node_modules/@types/node": {
"version": "20.4.2",
"resolved": "https://registry.npmmirror.com/@types/node/-/node-20.4.2.tgz",
"integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==",
"dev": true
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/axios": {
"version": "1.4.0",
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.4.0.tgz",
"integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
"dependencies": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/call-bind": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.2.tgz",
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
"dependencies": {
"function-bind": "^1.1.1",
"get-intrinsic": "^1.0.2"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"node_modules/get-intrinsic": {
"version": "1.2.1",
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
"integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
"dependencies": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3"
}
},
"node_modules/has": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dependencies": {
"function-bind": "^1.1.1"
},
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/has-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/has-proto/-/has-proto-1.0.1.tgz",
"integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/object-inspect": {
"version": "1.12.3",
"resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.3.tgz",
"integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g=="
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"node_modules/qs": {
"version": "6.11.2",
"resolved": "https://registry.npmmirror.com/qs/-/qs-6.11.2.tgz",
"integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==",
"dependencies": {
"side-channel": "^1.0.4"
},
"engines": {
"node": ">=0.6"
}
},
"node_modules/side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.4.tgz",
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
"dependencies": {
"call-bind": "^1.0.0",
"get-intrinsic": "^1.0.2",
"object-inspect": "^1.9.0"
}
},
"node_modules/uglify-js": {
"version": "3.17.4",
"resolved": "https://registry.npmmirror.com/uglify-js/-/uglify-js-3.17.4.tgz",
"integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==",
"dev": true,
"bin": {
"uglifyjs": "bin/uglifyjs"
},
"engines": {
"node": ">=0.8.0"
}
}
},
"dependencies": {
"@types/node": {
"version": "20.4.2",
"resolved": "https://registry.npmmirror.com/@types/node/-/node-20.4.2.tgz",
"integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==",
"dev": true
},
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"axios": {
"version": "1.4.0",
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.4.0.tgz",
"integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
"requires": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"call-bind": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.2.tgz",
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
"requires": {
"function-bind": "^1.1.1",
"get-intrinsic": "^1.0.2"
}
},
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"requires": {
"delayed-stream": "~1.0.0"
}
},
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
},
"follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
},
"form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
}
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"get-intrinsic": {
"version": "1.2.1",
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
"integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
"requires": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3"
}
},
"has": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"requires": {
"function-bind": "^1.1.1"
}
},
"has-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/has-proto/-/has-proto-1.0.1.tgz",
"integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg=="
},
"has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
},
"mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
},
"mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"requires": {
"mime-db": "1.52.0"
}
},
"object-inspect": {
"version": "1.12.3",
"resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.3.tgz",
"integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g=="
},
"proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"qs": {
"version": "6.11.2",
"resolved": "https://registry.npmmirror.com/qs/-/qs-6.11.2.tgz",
"integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==",
"requires": {
"side-channel": "^1.0.4"
}
},
"side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.4.tgz",
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
"requires": {
"call-bind": "^1.0.0",
"get-intrinsic": "^1.0.2",
"object-inspect": "^1.9.0"
}
},
"uglify-js": {
"version": "3.17.4",
"resolved": "https://registry.npmmirror.com/uglify-js/-/uglify-js-3.17.4.tgz",
"integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==",
"dev": true
}
}
}

@ -0,0 +1,21 @@
{
"name": "CatVodOpenJSSpider",
"version": "1.0.0",
"description": "",
"main": "app.js",
"type": "module",
"directories": {
"lib": "lib"
},
"scripts": {},
"author": "",
"license": "ISC",
"dependencies": {
"axios": "^1.4.0",
"qs": "^6.11.2"
},
"devDependencies": {
"@types/node": "^20.1.5",
"uglify-js": "^3.17.4"
}
}

@ -0,0 +1,9 @@
import {} from './wrapper/index.js';
// import { test } from './testVideo.js';
import { test } from './testAlist.js';
(async function () {
await test();
debugger;
})();

@ -0,0 +1,72 @@
import { __jsEvalReturn } from './alist_open.js';
var spider = __jsEvalReturn();
async function test() {
await spider.init({
skey: 'siteKey',
ext: [
{
name: '🙋丫仙女',
server: 'http://v.elizen.me/',
startPage: '/',
showAll: false,
search: true,
headers: {
Authorization: '',
},
params: {
'/abc': {
password: '123',
},
'/abc/abc': {
password: '123',
},
},
},
{
name: '🐋一只鱼',
server: 'https://alist.youte.ml',
},
{
name: '🌊七米蓝',
server: 'https://al.chirmyram.com',
},
{
name: '🐉神族九帝',
server: 'https://alist.shenzjd.com',
},
{
name: '☃姬路白雪',
server: 'https://pan.jlbx.xyz',
},
{
name: '✨星梦',
server: 'https://pan.bashroot.top',
},
{
name: '💢repl',
server: 'https://ali.liucn.repl.co',
},
{
name: '💦讯维云盘',
server: 'https://pan.xwbeta.com',
},
],
});
var files = JSON.parse(await spider.dir('/'));
console.log(files);
files = JSON.parse(await spider.dir(files.list[0].path));
console.log(files);
// files = JSON.parse(await spider.dir('/🙋丫仙女/电视剧/欧美/4K/00 漫威衍生美剧/L 猎鹰与冬兵4K(2021)【美剧】豆瓣评分:7.5/'));
// console.log(files);
var fileInfo = JSON.parse(await spider.file('/💦讯维云盘/热播短剧/傲世神尊/01.mp4'));
console.log(fileInfo);
}
export { test };

@ -0,0 +1,51 @@
import { __jsEvalReturn } from './kunyu77_open.js';
var spider = __jsEvalReturn();
async function test() {
var spType = null;
var spVid = null;
spType = '2';
// spVid = '95873';
await spider.init({ skey: 'siteKey', ext: '' });
var classes = JSON.parse(await spider.home(true));
console.log(classes);
var homeVod = JSON.parse(await spider.homeVod());
console.log(homeVod);
if (classes.class && classes.class.length > 0) {
var page = JSON.parse(await spider.category(spType || classes.class[0].type_id, 0, undefined, {}));
console.log(page);
if (page.list && page.list.length > 0) {
for (const k in page.list) {
if (k >= 5) break;
var detail = JSON.parse(await spider.detail(spVid || page.list[k].vod_id));
console.log(detail);
if (detail.list && detail.list.length > 0) {
var pFlag = detail.list[0].vod_play_from.split('$$$');
var pUrls = detail.list[0].vod_play_url.split('$$$');
if (pFlag.length > 0 && pUrls.length > 0) {
for (const i in pFlag) {
var flag = pFlag[i];
var urls = pUrls[i].split('#');
if (urls.length > 0) {
var url = urls[0].split('$')[1];
console.log(flag, url);
var playUrl = await spider.play(flag, url, []);
console.log(playUrl);
}
}
}
}
if (spVid) break;
}
}
}
var search = JSON.parse(await spider.search('奥特曼'));
console.log(search);
search = JSON.parse(await spider.search('喜欢'));
console.log(search);
}
export { test };

@ -0,0 +1,266 @@
// !!!!! Do not use in release mode. Just a native inject fake wrapper for test spider. !!!!!
// !!!!! Do not use in release mode. Just a native inject fake wrapper for test spider. !!!!!
// !!!!! Do not use in release mode. Just a native inject fake wrapper for test spider. !!!!!
import axios from 'axios';
import crypto from 'crypto';
import https from 'https';
import fs from 'node:fs';
import qs from 'qs';
import { Uri, _ } from '../lib/cat.js';
const confs = {};
function initLocalStorage(storage) {
if (!_.has(confs, storage)) {
if (!fs.existsSync('local')) {
fs.mkdirSync('local');
}
const storagePath = 'local/js_' + storage;
if (!fs.existsSync(storagePath)) {
fs.writeFileSync(storagePath, '{}');
confs[storage] = {};
} else {
confs[storage] = JSON.parse(fs.readFileSync(storagePath).toString());
}
}
}
function localGet(storage, key) {
initLocalStorage(storage);
return _.get(confs[storage], key, '');
}
function localSet(storage, key, value) {
initLocalStorage(storage);
confs[storage][key] = value;
fs.writeFileSync('local/js_' + storage, JSON.stringify(confs[storage]));
}
async function request(url, opt) {
try {
var data = opt ? opt.data || null : null;
var postType = opt ? opt.postType || null : null;
var returnBuffer = opt ? opt.buffer || 0 : 0;
var timeout = opt ? opt.timeout || 5000 : 5000;
var headers = opt ? opt.headers || {} : {};
if (postType == 'form') {
headers['Content-Type'] = 'application/x-www-form-urlencoded';
if (data != null) {
data = qs.stringify(data, { encode: false });
}
}
let respType = returnBuffer == 1 || returnBuffer == 2 ? 'arraybuffer' : undefined;
var resp = await axios(url, {
responseType: respType,
method: opt ? opt.method || 'get' : 'get',
headers: headers,
data: data,
timeout: timeout,
httpsAgent: https.Agent({
rejectUnauthorized: false,
}),
});
var data = resp.data;
var resHeader = {};
for (const hks of resp.headers) {
var v = hks[1];
resHeader[hks[0]] = Array.isArray(v) ? (v.length == 1 ? v[0] : v) : v;
}
if (!returnBuffer) {
if (typeof data === 'object') {
data = JSON.stringify(data);
}
} else if (returnBuffer == 1) {
return { code: resp.status, headers: resHeader, content: data };
} else if (returnBuffer == 2) {
return { code: resp.status, headers: resHeader, content: data.toString('base64') };
}
return { code: resp.status, headers: resHeader, content: data };
} catch (error) {
console.error(error);
}
return { headers: {}, content: '' };
}
function base64EncodeBuf(buff, urlsafe = false) {
return buff.toString(urlsafe ? 'base64url' : 'base64');
}
function base64Encode(text, urlsafe = false) {
return base64EncodeBuf(Buffer.from(text, 'utf8'), urlsafe);
}
function base64DecodeBuf(text) {
return Buffer.from(text, 'base64');
}
function base64Decode(text) {
return base64DecodeBuf(text).toString('utf8');
}
function md5(text) {
return crypto.createHash('md5').update(Buffer.from(text, 'utf8')).digest('hex');
}
function aes(mode, encrypt, input, inBase64, key, iv, outBase64) {
if (iv.length == 0) iv = null;
try {
if (mode.startsWith('AES/CBC')) {
switch (key.length) {
case 16:
mode = 'aes-128-cbc';
break;
case 32:
mode = 'aes-256-cbc';
break;
}
} else if (mode.startsWith('AES/ECB')) {
switch (key.length) {
case 16:
mode = 'aes-128-ecb';
break;
case 32:
mode = 'aes-256-ecb';
break;
}
}
const inBuf = inBase64 ? base64DecodeBuf(input) : Buffer.from(input, 'utf8');
let keyBuf = Buffer.from(key);
if (keyBuf.length < 16) keyBuf = Buffer.concat([keyBuf], 16);
let ivBuf = iv == null ? Buffer.alloc(0) : Buffer.from(iv);
if (iv != null && ivBuf.length < 16) ivBuf = Buffer.concat([ivBuf], 16);
const cipher = encrypt ? crypto.createCipheriv(mode, keyBuf, ivBuf) : crypto.createDecipheriv(mode, keyBuf, ivBuf);
const outBuf = Buffer.concat([cipher.update(inBuf), cipher.final()]);
return outBase64 ? base64EncodeBuf(outBuf) : outBuf.toString('utf8');
} catch (error) {
console.log(error);
}
return '';
}
function des(mode, encrypt, input, inBase64, key, iv, outBase64) {
try {
if (mode.startsWith('DESede/CBC')) {
// https://stackoverflow.com/questions/29831300/convert-desede-ecb-nopadding-algorithm-written-in-java-into-nodejs-using-crypto
switch (key.length) {
case 16:
mode = 'des-ede-cbc';
break;
case 24:
mode = 'des-ede3-cbc';
break;
}
}
const inBuf = inBase64 ? base64DecodeBuf(input) : Buffer.from(input, 'utf8');
let keyBuf = Buffer.from(key);
if (keyBuf.length < 16) keyBuf = Buffer.concat([keyBuf], 16);
let ivBuf = iv == null ? Buffer.alloc(0) : Buffer.from(iv);
if (iv != null && ivBuf.length < 8) ivBuf = Buffer.concat([ivBuf], 8);
const cipher = encrypt ? crypto.createCipheriv(mode, keyBuf, ivBuf) : crypto.createDecipheriv(mode, keyBuf, ivBuf);
const outBuf = Buffer.concat([cipher.update(inBuf), cipher.final()]);
return outBase64 ? base64EncodeBuf(outBuf) : outBuf.toString('utf8');
} catch (error) {
console.log(error);
}
return '';
}
// pkcs8 only
function rsa(mode, pub, encrypt, input, inBase64, key, outBase64) {
try {
let pd = undefined;
const keyObj = pub ? crypto.createPublicKey(key) : crypto.createPrivateKey(key);
if (!keyObj.asymmetricKeyDetails || !keyObj.asymmetricKeyDetails.modulusLength) return '';
const moduleLen = keyObj.asymmetricKeyDetails.modulusLength;
let blockLen = moduleLen / 8;
switch (mode) {
case 'RSA/PKCS1':
pd = crypto.constants.RSA_PKCS1_PADDING;
blockLen = encrypt ? blockLen - 11 : blockLen;
break;
case 'RSA/None/NoPadding':
pd = crypto.constants.RSA_NO_PADDING;
break;
case 'RSA/None/OAEPPadding':
pd = crypto.constants.RSA_PKCS1_OAEP_PADDING;
blockLen = encrypt ? blockLen - 41 : blockLen;
break;
default:
throw Error('not support ' + mode);
}
let inBuf = inBase64 ? base64DecodeBuf(input) : Buffer.from(input, 'utf8');
let bufIdx = 0;
let outBuf = Buffer.alloc(0);
while (bufIdx < inBuf.length) {
const bufEndIdx = Math.min(bufIdx + blockLen, inBuf.length);
let tmpInBuf = inBuf.subarray(bufIdx, bufEndIdx);
if (pd == crypto.constants.RSA_NO_PADDING) {
if (tmpInBuf.length < blockLen) {
tmpInBuf = Buffer.concat([Buffer.alloc(128 - tmpInBuf.length), tmpInBuf]);
}
}
let tmpBuf;
if (pub) {
tmpBuf = encrypt ? crypto.publicEncrypt({ key: keyObj, padding: pd }, tmpInBuf) : crypto.publicDecrypt({ key: keyObj, padding: pd }, tmpInBuf);
} else {
tmpBuf = encrypt ? crypto.privateEncrypt({ key: keyObj, padding: pd }, tmpInBuf) : crypto.privateDecrypt({ key: keyObj, padding: pd }, tmpInBuf);
}
bufIdx = bufEndIdx;
outBuf = Buffer.concat([outBuf, tmpBuf]);
}
return outBase64 ? base64EncodeBuf(outBuf) : outBuf.toString('utf8');
} catch (error) {
console.log(error);
}
return '';
}
var charStr = 'abacdefghjklmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789';
function randStr(len, withNum) {
var _str = '';
let containsNum = withNum === undefined ? true : withNum;
for (var i = 0; i < len; i++) {
let idx = _.random(0, containsNum ? charStr.length - 1 : charStr.length - 11);
_str += charStr[idx];
}
return _str;
}
globalThis.local = {
get: async function (storage, key) {
return localGet(storage, key);
},
set: async function (storage, key, val) {
localSet(storage, key, val);
},
};
globalThis.md5X = md5;
globalThis.rsaX = rsa;
globalThis.aesX = aes;
globalThis.desX = des;
globalThis.req = request;
globalThis.url2Proxy = async function (type, url, headers) {
let hd = Object.keys(headers).length == 0 ? '_' : encodeURIComponent(JSON.stringify(headers));
let uri = new Uri(url);
let path = uri.path();
path = path.substring(path.lastIndexOf('/'));
let ext = path.indexOf('.') >= 0 ? path.substring(path.indexOf('.')) : '.bin';
return 'http://127.0.0.1:13333/up/' + randStr(6) + '/' + type + '/' + hd + '/' + encodeURIComponent(url) + '/' + ext;
};
globalThis.js2Proxy = async function (dynamic, siteType, site, url, headers) {
let hd = Object.keys(headers).length == 0 ? '_' : encodeURIComponent(JSON.stringify(headers));
return (dynamic ? 'js2p://_WEB_/' : 'http://127.0.0.1:13333/jp/') + randStr(6) + '/' + siteType + '/' + site + '/' + hd + '/' + encodeURIComponent(url);
};
export default {};
Loading…
Cancel
Save