Files
WidevineProxy2/util.js
DevLARLEY 86f3c5bfa3 + Set static width of popup window
+ Fixed removal of `selected` key from sync storage
2024-10-27 12:04:28 +01:00

367 lines
12 KiB
JavaScript

import { WidevineDevice } from "./device.js";
import { RemoteCdm } from "./remote_cdm.js";
export class AsyncSyncStorage {
static async setStorage(items) {
return new Promise((resolve, reject) => {
chrome.storage.sync.set(items, () => {
if (chrome.runtime.lastError) {
reject(new Error(chrome.runtime.lastError));
} else {
resolve();
}
});
});
}
static async getStorage(keys) {
return new Promise((resolve, reject) => {
chrome.storage.sync.get(keys, (result) => {
if (chrome.runtime.lastError) {
reject(new Error(chrome.runtime.lastError));
} else {
resolve(result);
}
});
});
}
static async removeStorage(keys) {
return new Promise((resolve, reject) => {
chrome.storage.sync.remove(keys, (result) => {
if (chrome.runtime.lastError) {
reject(new Error(chrome.runtime.lastError));
} else {
resolve(result);
}
});
});
}
}
export class AsyncLocalStorage {
static async setStorage(items) {
return new Promise((resolve, reject) => {
chrome.storage.local.set(items, () => {
if (chrome.runtime.lastError) {
reject(new Error(chrome.runtime.lastError));
} else {
resolve();
}
});
});
}
static async getStorage(keys) {
return new Promise((resolve, reject) => {
chrome.storage.local.get(keys, (result) => {
if (chrome.runtime.lastError) {
reject(new Error(chrome.runtime.lastError));
} else {
resolve(result);
}
});
});
}
static async removeStorage(keys) {
return new Promise((resolve, reject) => {
chrome.storage.local.remove(keys, (result) => {
if (chrome.runtime.lastError) {
reject(new Error(chrome.runtime.lastError));
} else {
resolve(result);
}
});
});
}
}
export class DeviceManager {
static async saveWidevineDevice(name, value) {
const result = await AsyncSyncStorage.getStorage(['devices']);
const array = result.devices === undefined ? [] : result.devices;
array.push(name);
await AsyncSyncStorage.setStorage({ devices: array });
await AsyncSyncStorage.setStorage({ [name]: value });
}
static async loadWidevineDevice(name) {
const result = await AsyncSyncStorage.getStorage([name]);
return result[name] || "";
}
static setWidevineDevice(name, value){
const wvd_combobox = document.getElementById('wvd-combobox');
const wvd_element = document.createElement('option');
wvd_element.text = name;
wvd_element.value = value;
wvd_combobox.appendChild(wvd_element);
}
static async loadSetAllWidevineDevices() {
const result = await AsyncSyncStorage.getStorage(['devices']);
const array = result.devices || [];
for (const item of array) {
this.setWidevineDevice(item, await this.loadWidevineDevice(item));
}
}
static async saveSelectedWidevineDevice(name) {
await AsyncSyncStorage.setStorage({ selected: name });
}
static async getSelectedWidevineDevice() {
const result = await AsyncSyncStorage.getStorage(["selected"]);
return result["selected"] || "";
}
static async selectWidevineDevice(name) {
document.getElementById('wvd-combobox').value = await this.loadWidevineDevice(name);
}
static async removeSelectedWidevineDevice() {
const selected_device_name = await DeviceManager.getSelectedWidevineDevice();
const result = await AsyncSyncStorage.getStorage(['devices']);
const array = result.devices === undefined ? [] : result.devices;
const index = array.indexOf(selected_device_name);
if (index > -1) {
array.splice(index, 1);
}
await AsyncSyncStorage.setStorage({ devices: array });
await AsyncSyncStorage.removeStorage([selected_device_name]);
}
static async removeSelectedWidevineDeviceKey() {
await AsyncSyncStorage.removeStorage(["selected"]);
}
}
export class RemoteCDMManager {
static async saveRemoteCDM(name, obj) {
const result = await AsyncSyncStorage.getStorage(['remote_cdms']);
const array = result.remote_cdms === undefined ? [] : result.remote_cdms;
array.push(name);
await AsyncSyncStorage.setStorage({ remote_cdms: array });
await AsyncSyncStorage.setStorage({ [name]: obj });
}
static async loadRemoteCDM(name) {
const result = await AsyncSyncStorage.getStorage([name]);
return JSON.stringify(result[name] || {});
}
static setRemoteCDM(name, value){
const remote_combobox = document.getElementById('remote-combobox');
const remote_element = document.createElement('option');
remote_element.text = name;
remote_element.value = value;
remote_combobox.appendChild(remote_element);
}
static async loadSetAllRemoteCDMs() {
const result = await AsyncSyncStorage.getStorage(['remote_cdms']);
const array = result.remote_cdms || [];
for (const item of array) {
this.setRemoteCDM(item, await this.loadRemoteCDM(item));
}
}
static async saveSelectedRemoteCDM(name) {
await AsyncSyncStorage.setStorage({ selected_remote_cdm: name });
}
static async getSelectedRemoteCDM() {
const result = await AsyncSyncStorage.getStorage(["selected_remote_cdm"]);
return result["selected_remote_cdm"] || "";
}
static async selectRemoteCDM(name) {
document.getElementById('remote-combobox').value = await this.loadRemoteCDM(name);
}
static async removeSelectedRemoteCDM() {
const selected_remote_cdm_name = await RemoteCDMManager.getSelectedRemoteCDM();
const result = await AsyncSyncStorage.getStorage(['remote_cdms']);
const array = result.remote_cdms === undefined ? [] : result.remote_cdms;
const index = array.indexOf(selected_remote_cdm_name);
if (index > -1) {
array.splice(index, 1);
}
await AsyncSyncStorage.setStorage({ remote_cdms: array });
await AsyncSyncStorage.removeStorage([selected_remote_cdm_name]);
}
static async removeSelectedRemoteCDMKey() {
await AsyncSyncStorage.removeStorage(["selected_remote_cdm"]);
}
}
export class SettingsManager {
static async setEnabled(enabled) {
await AsyncSyncStorage.setStorage({ enabled: enabled });
}
static async getEnabled() {
const result = await AsyncSyncStorage.getStorage(["enabled"]);
return result["enabled"] === undefined ? false : result["enabled"];
}
static downloadFile(content, filename) {
const blob = new Blob([content], { type: 'application/octet-stream' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
static async importDevice(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = async function (loaded) {
const result = loaded.target.result;
const widevine_device = new WidevineDevice(result);
const b64_device = uint8ArrayToBase64(new Uint8Array(result));
const device_name = widevine_device.get_name();
if (!await DeviceManager.loadWidevineDevice(device_name)) {
await DeviceManager.saveWidevineDevice(device_name, b64_device);
}
await DeviceManager.saveSelectedWidevineDevice(device_name);
resolve();
};
reader.readAsArrayBuffer(file);
});
}
static async saveDarkMode(dark_mode) {
await AsyncSyncStorage.setStorage({ dark_mode: dark_mode });
}
static async getDarkMode() {
const result = await AsyncSyncStorage.getStorage(["dark_mode"]);
return result["dark_mode"] || false;
}
static setDarkMode(dark_mode) {
const textImage = document.getElementById("textImage");
const toggle = document.getElementById('darkModeToggle');
toggle.checked = dark_mode;
document.body.classList.toggle('dark-mode', dark_mode);
textImage.src = dark_mode ? "../images/proxy_text_dark.png" : "../images/proxy_text.png";
}
static async loadRemoteCDM(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = async function (loaded) {
const result = loaded.target.result;
let json_file = void 0;
try {
json_file = JSON.parse(result);
} catch {
resolve();
return;
}
console.log("LOADED DEVICE:", json_file);
const remote_cdm = new RemoteCdm(
json_file.device_type,
json_file.system_id,
json_file.security_level,
json_file.host,
json_file.secret,
json_file.device_name ?? json_file.name,
);
const device_name = remote_cdm.get_name();
console.log("NAME:", device_name);
if (await RemoteCDMManager.loadRemoteCDM(device_name) === "{}") {
await RemoteCDMManager.saveRemoteCDM(device_name, json_file);
}
await RemoteCDMManager.saveSelectedRemoteCDM(device_name);
resolve();
};
reader.readAsText(file);
});
}
static async saveSelectedDeviceType(selected_type) {
await AsyncSyncStorage.setStorage({ device_type: selected_type });
}
static async getSelectedDeviceType() {
const result = await AsyncSyncStorage.getStorage(["device_type"]);
return result["device_type"] || "WVD";
}
static setSelectedDeviceType(device_type) {
switch (device_type) {
case "WVD":
const wvd_select = document.getElementById('wvd_select');
wvd_select.checked = true;
break;
case "REMOTE":
const remote_select = document.getElementById('remote_select');
remote_select.checked = true;
break;
}
}
}
export function intToUint8Array(num) {
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
view.setUint32(0, num, false);
return new Uint8Array(buffer);
}
export function compareUint8Arrays(arr1, arr2) {
if (arr1.length !== arr2.length)
return false;
return Array.from(arr1).every((value, index) => value === arr2[index]);
}
export function uint8ArrayToHex(buffer) {
return Array.prototype.map.call(buffer, x => x.toString(16).padStart(2, '0')).join('');
}
export function uint8ArrayToString(uint8array) {
return String.fromCharCode.apply(null, uint8array)
}
export function uint8ArrayToBase64(uint8array) {
return btoa(String.fromCharCode.apply(null, uint8array));
}
export function base64toUint8Array(base64_string){
return Uint8Array.from(atob(base64_string), c => c.charCodeAt(0))
}
export function stringToUint8Array(string) {
return Uint8Array.from(string.split("").map(x => x.charCodeAt()))
}
export function stringToHex(string){
return string.split("").map(c => c.charCodeAt(0).toString(16).padStart(2, "0")).join("");
}