Оригинальный вопрос:
Я разрабатываю расширение для браузера, которое использует OpenPGP.js для шифрования и дешифрования выбранного текста на веб-странице. Расширение отлично работает в Chrome, но я столкнулся с проблемой в Firefox, когда объект openpgp
не определен.
Также еще одна ошибка в openpgp.min.js.
Error: concatUint8Array: Data must be in the form of a Uint8Array
Вот соответствующая часть моего сценария контента:
async function encryptSelectedText() {
const selection = window.getSelection().toString();
console.info("Selected text:", selection);
const selectionObj = window.getSelection().getRangeAt(0);
console.info("Selection object:", selectionObj);
if (selection) {
try {
// Get the selected public key from storage
browser.storage.sync.get("selectedPublicKey", async function (data) {
// console.info("Selected public key:", data.selectedPublicKey);
const publicKeyArmored = data.selectedPublicKey;
console.info("Public key:", publicKeyArmored);
if (publicKeyArmored) {
const publicKey = await openpgp.readKey({
armoredKey: publicKeyArmored,
});
// further code but i get error here
Openpgp.js уже включен в скрипты контента:
{
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["src/openpgp.min.js", "src/content.js"]
}
]
}
Моя файловая структура:
├── manifest.json
└── src
├── background.js
├── content.js
├── openpgp.min.js
├── openpgp.min.js.map
└── popup
├── popup.css
├── popup.html
└── popup.js
Объект openpgp
должен быть определен в Firefox так же, как и в Chrome, чтобы функции шифрования и дешифрования работали правильно.
Искал в Интернете похожие проблемы, но безрезультатно. Тоже спрашивал чатгпт, но тоже не помогло
Объект openpgp должен быть определен в Firefox так же, как и в Chrome, чтобы функции шифрования и дешифрования работали правильно, но в Firefox он не работает.
Обновлять:
После дальнейшего расследования я обнаружил, что проблема заключалась в том, как Uint8Array
распознавался в Firefox. Хотя элементы являются экземплярами Uint8Array
, Firefox не распознал их как таковые.
Ниже приведен фрагмент из openpgp.js
function isUint8Array(input) {
return Uint8Array.prototype.isPrototypeOf(input);
}
function concatUint8Array(arrays) {
if (arrays.length === 1) return arrays[0];
console.info("arrays:", arrays);
let totalLength = 0;
for (let i = 0; i < arrays.length; i++) {
const element = arrays[i];
console.info("Element at index", i, ":", element);
console.info("Is Uint8Array:", isUint8Array(element));
console.info("Element constructor:", element.constructor.name);
console.info("Instance of Uint8Array:", element instanceof Uint8Array);
if (!isUint8Array(element)) {
throw new Error('concatUint8Array: Data must be in the form of a Uint8Array');
}
totalLength += element.length;
}
const result = new Uint8Array(totalLength);
let pos = 0;
arrays.forEach(function (element) {
result.set(element, pos);
pos += element.length;
});
return result;
}
Он показывает следующее Firefox
Element at index 0 :
Uint8Array(14) [ 79, 112, 101, 110, 80, 71, 80, 32, 88, 50, … ]
Is Uint8Array: false
Element constructor: Uint8Array
Instance of Uint8Array: false
Это отлично работает в Chrome, но не в Firefox.
Кроме того, если я просто верну true из isUint8Array
, шифрование будет работать, но при расшифровке возникнет следующая ошибка.
Ошибка: Permission denied to access property "constructor"
Я обновил свой вопрос, добавив дополнительные шаги и выводы по устранению неполадок.
Похоже на еще одну ошибку в Firefox или, возможно, ваш массив из другой «области». Покажите код, создающий массив.
После ссылки на это обсуждение на github следующие изменения решили мою проблему:
Изменение
function isUint8Array(input) {
return Uint8Array.prototype.isPrototypeOf(input);
}
к этому:
function isUint8Array(input) {
return Uint8Array.prototype.isPrototypeOf(input) || input instanceof globalThis.Uint8Array;
}
и
arr.push(result);
к
const fixedArray = new Uint8Array(result);
arr.push(fixedArray);
Звучит как bugzil.la/1208775. Попробуйте использовать
window.openpgp
или замените первое назначениеconst t
в openpgp.min.js наconst t=this
.