all: format with prettier
(cherry picked from commit cad5b4d7deba4fbe4a40a17306ce49d3b2f13139)remotes/origin/HEAD
parent
19486d4d34
commit
76dd78130a
@ -1,26 +1,25 @@
|
||||
export interface DecryptResult {
|
||||
title: string
|
||||
album?: string
|
||||
artist?: string
|
||||
title: string;
|
||||
album?: string;
|
||||
artist?: string;
|
||||
|
||||
mime: string
|
||||
ext: string
|
||||
mime: string;
|
||||
ext: string;
|
||||
|
||||
file: string
|
||||
blob: Blob
|
||||
picture?: string
|
||||
|
||||
message?: string
|
||||
rawExt?: string
|
||||
rawFilename?: string
|
||||
file: string;
|
||||
blob: Blob;
|
||||
picture?: string;
|
||||
|
||||
message?: string;
|
||||
rawExt?: string;
|
||||
rawFilename?: string;
|
||||
}
|
||||
|
||||
export interface FileInfo {
|
||||
status: string
|
||||
name: string,
|
||||
size: number,
|
||||
percentage: number,
|
||||
uid: number,
|
||||
raw: File
|
||||
status: string;
|
||||
name: string;
|
||||
size: number;
|
||||
percentage: number;
|
||||
uid: number;
|
||||
raw: File;
|
||||
}
|
||||
|
@ -1,115 +1,117 @@
|
||||
import {QmcMapCipher, QmcRC4Cipher, QmcStaticCipher} from "@/decrypt/qmc_cipher";
|
||||
import fs from 'fs'
|
||||
import { QmcMapCipher, QmcRC4Cipher, QmcStaticCipher } from '@/decrypt/qmc_cipher';
|
||||
import fs from 'fs';
|
||||
|
||||
test("static cipher [0x7ff8,0x8000) ", () => {
|
||||
test('static cipher [0x7ff8,0x8000) ', () => {
|
||||
//prettier-ignore
|
||||
const expected = new Uint8Array([
|
||||
0xD8, 0x52, 0xF7, 0x67, 0x90, 0xCA, 0xD6, 0x4A,
|
||||
0x4A, 0xD6, 0xCA, 0x90, 0x67, 0xF7, 0x52, 0xD8,
|
||||
])
|
||||
|
||||
const c = new QmcStaticCipher()
|
||||
const buf = new Uint8Array(16)
|
||||
c.decrypt(buf, 0x7ff8)
|
||||
const c = new QmcStaticCipher();
|
||||
const buf = new Uint8Array(16);
|
||||
c.decrypt(buf, 0x7ff8);
|
||||
|
||||
expect(buf).toStrictEqual(expected)
|
||||
})
|
||||
expect(buf).toStrictEqual(expected);
|
||||
});
|
||||
|
||||
test("static cipher [0,0x10) ", () => {
|
||||
test('static cipher [0,0x10) ', () => {
|
||||
//prettier-ignore
|
||||
const expected = new Uint8Array([
|
||||
0xC3, 0x4A, 0xD6, 0xCA, 0x90, 0x67, 0xF7, 0x52,
|
||||
0xD8, 0xA1, 0x66, 0x62, 0x9F, 0x5B, 0x09, 0x00,
|
||||
])
|
||||
|
||||
const c = new QmcStaticCipher()
|
||||
const buf = new Uint8Array(16)
|
||||
c.decrypt(buf, 0)
|
||||
const c = new QmcStaticCipher();
|
||||
const buf = new Uint8Array(16);
|
||||
c.decrypt(buf, 0);
|
||||
|
||||
expect(buf).toStrictEqual(expected)
|
||||
})
|
||||
expect(buf).toStrictEqual(expected);
|
||||
});
|
||||
|
||||
|
||||
test("map cipher: get mask", () => {
|
||||
test('map cipher: get mask', () => {
|
||||
//prettier-ignore
|
||||
const expected = new Uint8Array([
|
||||
0xBB, 0x7D, 0x80, 0xBE, 0xFF, 0x38, 0x81, 0xFB,
|
||||
0xBB, 0xFF, 0x82, 0x3C, 0xFF, 0xBA, 0x83, 0x79,
|
||||
])
|
||||
const key = new Uint8Array(256)
|
||||
for (let i = 0; i < 256; i++) key[i] = i
|
||||
const buf = new Uint8Array(16)
|
||||
const key = new Uint8Array(256);
|
||||
for (let i = 0; i < 256; i++) key[i] = i;
|
||||
const buf = new Uint8Array(16);
|
||||
|
||||
const c = new QmcMapCipher(key)
|
||||
c.decrypt(buf, 0)
|
||||
expect(buf).toStrictEqual(expected)
|
||||
})
|
||||
const c = new QmcMapCipher(key);
|
||||
c.decrypt(buf, 0);
|
||||
expect(buf).toStrictEqual(expected);
|
||||
});
|
||||
|
||||
function loadTestDataCipher(name: string): {
|
||||
key: Uint8Array,
|
||||
cipherText: Uint8Array,
|
||||
clearText: Uint8Array
|
||||
key: Uint8Array;
|
||||
cipherText: Uint8Array;
|
||||
clearText: Uint8Array;
|
||||
} {
|
||||
return {
|
||||
key: fs.readFileSync(`testdata/${name}_key.bin`),
|
||||
cipherText: fs.readFileSync(`testdata/${name}_raw.bin`),
|
||||
clearText: fs.readFileSync(`testdata/${name}_target.bin`)
|
||||
}
|
||||
clearText: fs.readFileSync(`testdata/${name}_target.bin`),
|
||||
};
|
||||
}
|
||||
|
||||
test("map cipher: real file", async () => {
|
||||
const cases = ["mflac_map", "mgg_map"]
|
||||
test('map cipher: real file', async () => {
|
||||
const cases = ['mflac_map', 'mgg_map'];
|
||||
for (const name of cases) {
|
||||
const {key, clearText, cipherText} = loadTestDataCipher(name)
|
||||
const c = new QmcMapCipher(key)
|
||||
const { key, clearText, cipherText } = loadTestDataCipher(name);
|
||||
const c = new QmcMapCipher(key);
|
||||
|
||||
c.decrypt(cipherText, 0)
|
||||
c.decrypt(cipherText, 0);
|
||||
|
||||
expect(cipherText).toStrictEqual(clearText)
|
||||
expect(cipherText).toStrictEqual(clearText);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
test("rc4 cipher: real file", async () => {
|
||||
const cases = ["mflac0_rc4"]
|
||||
test('rc4 cipher: real file', async () => {
|
||||
const cases = ['mflac0_rc4'];
|
||||
for (const name of cases) {
|
||||
const {key, clearText, cipherText} = loadTestDataCipher(name)
|
||||
const c = new QmcRC4Cipher(key)
|
||||
const { key, clearText, cipherText } = loadTestDataCipher(name);
|
||||
const c = new QmcRC4Cipher(key);
|
||||
|
||||
c.decrypt(cipherText, 0)
|
||||
c.decrypt(cipherText, 0);
|
||||
|
||||
expect(cipherText).toStrictEqual(clearText)
|
||||
expect(cipherText).toStrictEqual(clearText);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
test("rc4 cipher: first segment", async () => {
|
||||
const cases = ["mflac0_rc4"]
|
||||
test('rc4 cipher: first segment', async () => {
|
||||
const cases = ['mflac0_rc4'];
|
||||
for (const name of cases) {
|
||||
const {key, clearText, cipherText} = loadTestDataCipher(name)
|
||||
const c = new QmcRC4Cipher(key)
|
||||
const { key, clearText, cipherText } = loadTestDataCipher(name);
|
||||
const c = new QmcRC4Cipher(key);
|
||||
|
||||
const buf = cipherText.slice(0, 128)
|
||||
c.decrypt(buf, 0)
|
||||
expect(buf).toStrictEqual(clearText.slice(0, 128))
|
||||
const buf = cipherText.slice(0, 128);
|
||||
c.decrypt(buf, 0);
|
||||
expect(buf).toStrictEqual(clearText.slice(0, 128));
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
test("rc4 cipher: align block (128~5120)", async () => {
|
||||
const cases = ["mflac0_rc4"]
|
||||
test('rc4 cipher: align block (128~5120)', async () => {
|
||||
const cases = ['mflac0_rc4'];
|
||||
for (const name of cases) {
|
||||
const {key, clearText, cipherText} = loadTestDataCipher(name)
|
||||
const c = new QmcRC4Cipher(key)
|
||||
const { key, clearText, cipherText } = loadTestDataCipher(name);
|
||||
const c = new QmcRC4Cipher(key);
|
||||
|
||||
const buf = cipherText.slice(128, 5120)
|
||||
c.decrypt(buf, 128)
|
||||
expect(buf).toStrictEqual(clearText.slice(128, 5120))
|
||||
const buf = cipherText.slice(128, 5120);
|
||||
c.decrypt(buf, 128);
|
||||
expect(buf).toStrictEqual(clearText.slice(128, 5120));
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
test("rc4 cipher: simple block (5120~10240)", async () => {
|
||||
const cases = ["mflac0_rc4"]
|
||||
test('rc4 cipher: simple block (5120~10240)', async () => {
|
||||
const cases = ['mflac0_rc4'];
|
||||
for (const name of cases) {
|
||||
const {key, clearText, cipherText} = loadTestDataCipher(name)
|
||||
const c = new QmcRC4Cipher(key)
|
||||
const { key, clearText, cipherText } = loadTestDataCipher(name);
|
||||
const c = new QmcRC4Cipher(key);
|
||||
|
||||
const buf = cipherText.slice(5120, 10240)
|
||||
c.decrypt(buf, 5120)
|
||||
expect(buf).toStrictEqual(clearText.slice(5120, 10240))
|
||||
const buf = cipherText.slice(5120, 10240);
|
||||
c.decrypt(buf, 5120);
|
||||
expect(buf).toStrictEqual(clearText.slice(5120, 10240));
|
||||
}
|
||||
})
|
||||
});
|
||||
|
@ -1,30 +1,26 @@
|
||||
import {QmcDeriveKey, simpleMakeKey} from "@/decrypt/qmc_key";
|
||||
import fs from "fs";
|
||||
import { QmcDeriveKey, simpleMakeKey } from '@/decrypt/qmc_key';
|
||||
import fs from 'fs';
|
||||
|
||||
test("key dec: make simple key", () => {
|
||||
expect(
|
||||
simpleMakeKey(106, 8)
|
||||
).toStrictEqual(
|
||||
[0x69, 0x56, 0x46, 0x38, 0x2b, 0x20, 0x15, 0x0b]
|
||||
)
|
||||
})
|
||||
test('key dec: make simple key', () => {
|
||||
expect(simpleMakeKey(106, 8)).toStrictEqual([0x69, 0x56, 0x46, 0x38, 0x2b, 0x20, 0x15, 0x0b]);
|
||||
});
|
||||
|
||||
function loadTestDataKeyDecrypt(name: string): {
|
||||
cipherText: Uint8Array,
|
||||
clearText: Uint8Array
|
||||
cipherText: Uint8Array;
|
||||
clearText: Uint8Array;
|
||||
} {
|
||||
return {
|
||||
cipherText: fs.readFileSync(`testdata/${name}_key_raw.bin`),
|
||||
clearText: fs.readFileSync(`testdata/${name}_key.bin`)
|
||||
}
|
||||
clearText: fs.readFileSync(`testdata/${name}_key.bin`),
|
||||
};
|
||||
}
|
||||
|
||||
test("key dec: real file", async () => {
|
||||
const cases = ["mflac_map", "mgg_map", "mflac0_rc4"]
|
||||
test('key dec: real file', async () => {
|
||||
const cases = ['mflac_map', 'mgg_map', 'mflac0_rc4'];
|
||||
for (const name of cases) {
|
||||
const {clearText, cipherText} = loadTestDataKeyDecrypt(name)
|
||||
const buf = QmcDeriveKey(cipherText)
|
||||
const { clearText, cipherText } = loadTestDataKeyDecrypt(name);
|
||||
const buf = QmcDeriveKey(cipherText);
|
||||
|
||||
expect(buf).toStrictEqual(clearText)
|
||||
expect(buf).toStrictEqual(clearText);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
@ -1,5 +1,2 @@
|
||||
const bs = chrome || browser
|
||||
bs.tabs.create({
|
||||
url: bs.runtime.getURL('./index.html')
|
||||
}, tab => console.log(tab))
|
||||
|
||||
const bs = chrome || browser;
|
||||
bs.tabs.create({ url: bs.runtime.getURL('./index.html') }, (tab) => console.log(tab));
|
||||
|
@ -1,31 +1,30 @@
|
||||
/* eslint-disable no-console */
|
||||
|
||||
import {register} from 'register-service-worker'
|
||||
|
||||
if (process.env.NODE_ENV === 'production' && window.location.protocol === "https:") {
|
||||
import { register } from 'register-service-worker';
|
||||
|
||||
if (process.env.NODE_ENV === 'production' && window.location.protocol === 'https:') {
|
||||
register(`${process.env.BASE_URL}service-worker.js`, {
|
||||
ready() {
|
||||
console.log('App is being served from cache by a service worker.')
|
||||
console.log('App is being served from cache by a service worker.');
|
||||
},
|
||||
registered() {
|
||||
console.log('Service worker has been registered.')
|
||||
console.log('Service worker has been registered.');
|
||||
},
|
||||
cached() {
|
||||
console.log('Content has been cached for offline use.')
|
||||
console.log('Content has been cached for offline use.');
|
||||
},
|
||||
updatefound() {
|
||||
console.log('New content is downloading.')
|
||||
console.log('New content is downloading.');
|
||||
},
|
||||
updated() {
|
||||
console.log('New content is available.');
|
||||
window.location.reload();
|
||||
},
|
||||
offline() {
|
||||
console.log('No internet connection found. App is running in offline mode.')
|
||||
console.log('No internet connection found. App is running in offline mode.');
|
||||
},
|
||||
error(error) {
|
||||
console.error('Error during service worker registration:', error)
|
||||
}
|
||||
})
|
||||
console.error('Error during service worker registration:', error);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -1,17 +1,15 @@
|
||||
import Vue, {VNode} from 'vue'
|
||||
import Vue, { VNode } from 'vue';
|
||||
|
||||
declare global {
|
||||
namespace JSX {
|
||||
// tslint:disable no-empty-interface
|
||||
interface Element extends VNode {
|
||||
}
|
||||
interface Element extends VNode {}
|
||||
|
||||
// tslint:disable no-empty-interface
|
||||
interface ElementClass extends Vue {
|
||||
}
|
||||
interface ElementClass extends Vue {}
|
||||
|
||||
interface IntrinsicElements {
|
||||
[elem: string]: any
|
||||
[elem: string]: any;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
declare module '*.vue' {
|
||||
import Vue from 'vue'
|
||||
export default Vue
|
||||
import Vue from 'vue';
|
||||
export default Vue;
|
||||
}
|
||||
|
@ -1,56 +1,73 @@
|
||||
import {fromByteArray as Base64Encode} from "base64-js";
|
||||
import { fromByteArray as Base64Encode } from 'base64-js';
|
||||
|
||||
export const IXAREA_API_ENDPOINT = "https://um-api.ixarea.com"
|
||||
export const IXAREA_API_ENDPOINT = 'https://um-api.ixarea.com';
|
||||
|
||||
export interface UpdateInfo {
|
||||
Found: boolean
|
||||
HttpsFound: boolean
|
||||
Version: string
|
||||
URL: string
|
||||
Detail: string
|
||||
Found: boolean;
|
||||
HttpsFound: boolean;
|
||||
Version: string;
|
||||
URL: string;
|
||||
Detail: string;
|
||||
}
|
||||
|
||||
export async function checkUpdate(version: string): Promise<UpdateInfo> {
|
||||
const resp = await fetch(IXAREA_API_ENDPOINT + "/music/app-version", {
|
||||
method: "POST",
|
||||
headers: {"Content-Type": "application/json"},
|
||||
body: JSON.stringify({"Version": version})
|
||||
const resp = await fetch(IXAREA_API_ENDPOINT + '/music/app-version', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ Version: version }),
|
||||
});
|
||||
return await resp.json();
|
||||
}
|
||||
|
||||
export function reportKeyUsage(keyData: Uint8Array, maskData: number[], filename: string, format: string, title: string, artist?: string, album?: string) {
|
||||
return fetch(IXAREA_API_ENDPOINT + "/qmcmask/usage", {
|
||||
method: "POST",
|
||||
headers: {"Content-Type": "application/json"},
|
||||
export function reportKeyUsage(
|
||||
keyData: Uint8Array,
|
||||
maskData: number[],
|
||||
filename: string,
|
||||
format: string,
|
||||
title: string,
|
||||
artist?: string,
|
||||
album?: string,
|
||||
) {
|
||||
return fetch(IXAREA_API_ENDPOINT + '/qmcmask/usage', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
Mask: Base64Encode(new Uint8Array(maskData)), Key: Base64Encode(keyData),
|
||||
Artist: artist, Title: title, Album: album, Filename: filename, Format: format
|
||||
Mask: Base64Encode(new Uint8Array(maskData)),
|
||||
Key: Base64Encode(keyData),
|
||||
Artist: artist,
|
||||
Title: title,
|
||||
Album: album,
|
||||
Filename: filename,
|
||||
Format: format,
|
||||
}),
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
interface KeyInfo {
|
||||
Matrix44: string
|
||||
Matrix44: string;
|
||||
}
|
||||
|
||||
export async function queryKeyInfo(keyData: Uint8Array, filename: string, format: string): Promise<KeyInfo> {
|
||||
const resp = await fetch(IXAREA_API_ENDPOINT + "/qmcmask/query", {
|
||||
method: "POST",
|
||||
headers: {"Content-Type": "application/json"},
|
||||
body: JSON.stringify({Format: format, Key: Base64Encode(keyData), Filename: filename, Type: 44}),
|
||||
const resp = await fetch(IXAREA_API_ENDPOINT + '/qmcmask/query', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ Format: format, Key: Base64Encode(keyData), Filename: filename, Type: 44 }),
|
||||
});
|
||||
return await resp.json();
|
||||
}
|
||||
|
||||
export interface CoverInfo {
|
||||
Id: string
|
||||
Type: number
|
||||
Id: string;
|
||||
Type: number;
|
||||
}
|
||||
|
||||
export async function queryAlbumCover(title: string, artist?: string, album?: string): Promise<CoverInfo> {
|
||||
const endpoint = IXAREA_API_ENDPOINT + "/music/qq-cover"
|
||||
const params = new URLSearchParams([["Title", title], ["Artist", artist ?? ""], ["Album", album ?? ""]])
|
||||
const resp = await fetch(`${endpoint}?${params.toString()}`)
|
||||
return await resp.json()
|
||||
const endpoint = IXAREA_API_ENDPOINT + '/music/qq-cover';
|
||||
const params = new URLSearchParams([
|
||||
['Title', title],
|
||||
['Artist', artist ?? ''],
|
||||
['Album', album ?? ''],
|
||||
]);
|
||||
const resp = await fetch(`${endpoint}?${params.toString()}`);
|
||||
return await resp.json();
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {expose} from "threads/worker";
|
||||
import {CommonDecrypt} from "@/decrypt/common";
|
||||
import { expose } from 'threads/worker';
|
||||
import { CommonDecrypt } from '@/decrypt/common';
|
||||
|
||||
expose(CommonDecrypt)
|
||||
expose(CommonDecrypt);
|
||||
|
Loading…
Reference in New Issue