zotero-plugin 5.0.23 → 5.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/keypair +22 -3
- package/bin/release.js +1 -1
- package/debug-log.d.ts +0 -4
- package/debug-log.js +42 -76
- package/package.json +1 -1
package/bin/keypair
CHANGED
|
@@ -2,6 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
from cryptography.hazmat.primitives.asymmetric import rsa
|
|
4
4
|
from cryptography.hazmat.primitives import serialization
|
|
5
|
+
import sys, os
|
|
6
|
+
|
|
7
|
+
script_name = os.path.basename(sys.argv[0])
|
|
8
|
+
if len(sys.argv) != 2:
|
|
9
|
+
print(f'Usage: {script_name} <directory>')
|
|
10
|
+
sys.exit(1)
|
|
11
|
+
|
|
12
|
+
target = sys.argv[1]
|
|
13
|
+
if not os.path.isdir(target):
|
|
14
|
+
print(f'Error: {target} is not a directory.')
|
|
15
|
+
sys.exit(1)
|
|
16
|
+
|
|
17
|
+
valid_files = {'public.pem', 'private.pem'}
|
|
18
|
+
all_files = set(os.listdir(target))
|
|
19
|
+
|
|
20
|
+
if not all_files.issubset(valid_files):
|
|
21
|
+
print(f'Error: Directory contains invalid files: {all_files - valid_files}')
|
|
22
|
+
sys.exit(1)
|
|
5
23
|
|
|
6
24
|
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
|
|
7
25
|
private_pem = private_key.private_bytes(
|
|
@@ -9,12 +27,13 @@ private_pem = private_key.private_bytes(
|
|
|
9
27
|
format=serialization.PrivateFormat.PKCS8,
|
|
10
28
|
encryption_algorithm=serialization.NoEncryption()
|
|
11
29
|
)
|
|
30
|
+
with open(os.path.join(target, 'private.pem'), 'w') as f:
|
|
31
|
+
f.write(private_pem.decode('utf-8'))
|
|
12
32
|
|
|
13
33
|
public_key = private_key.public_key()
|
|
14
34
|
public_pem = public_key.public_bytes(
|
|
15
35
|
encoding=serialization.Encoding.PEM,
|
|
16
36
|
format=serialization.PublicFormat.SubjectPublicKeyInfo
|
|
17
37
|
)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
print(public_pem.decode('utf-8'))
|
|
38
|
+
with open(os.path.join(target, 'public.pem'), 'w') as f:
|
|
39
|
+
f.write(public_pem.decode('utf-8'))
|
package/bin/release.js
CHANGED
|
@@ -8448,7 +8448,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
8448
8448
|
"package.json"(exports, module) {
|
|
8449
8449
|
module.exports = {
|
|
8450
8450
|
name: "zotero-plugin",
|
|
8451
|
-
version: "5.0.
|
|
8451
|
+
version: "5.0.25",
|
|
8452
8452
|
description: "Zotero plugin builder",
|
|
8453
8453
|
homepage: "https://github.com/retorquere/zotero-plugin/wiki",
|
|
8454
8454
|
bin: {
|
package/debug-log.d.ts
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
declare class DebugLogSender {
|
|
2
|
-
private $zotero;
|
|
3
2
|
id: {
|
|
4
3
|
menu: string;
|
|
5
4
|
menupopup: string;
|
|
6
5
|
menuitem: string;
|
|
7
6
|
};
|
|
8
7
|
debugEnabledAtStart: boolean;
|
|
9
|
-
private get zotero();
|
|
10
|
-
convertLegacy(): void;
|
|
11
8
|
private element;
|
|
12
9
|
register(plugin: string, preferences?: string[], pubkey?: string): void;
|
|
13
10
|
unregister(plugin: string): void;
|
|
14
|
-
private alert;
|
|
15
11
|
send(target: EventTarget): void;
|
|
16
12
|
private sendAsync;
|
|
17
13
|
private preferences;
|
package/debug-log.js
CHANGED
|
@@ -15,41 +15,10 @@ class DebugLogSender {
|
|
|
15
15
|
? (Zotero.Prefs.get('debug.store') || Zotero.Debug.enabled)
|
|
16
16
|
: null;
|
|
17
17
|
}
|
|
18
|
-
get zotero() {
|
|
19
|
-
if (typeof Zotero !== 'undefined')
|
|
20
|
-
return Zotero;
|
|
21
|
-
if (!this.$zotero) {
|
|
22
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
23
|
-
if (typeof Services === 'undefined')
|
|
24
|
-
Services = ChromeUtils.import('resource://gre/modules/Services.jsm').Services;
|
|
25
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
26
|
-
const windows = Services.wm.getEnumerator('navigator:browser');
|
|
27
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
28
|
-
while (!this.$zotero && windows.hasMoreElements()) {
|
|
29
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
30
|
-
this.$zotero = windows.getNext().Zotero;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
return this.$zotero;
|
|
34
|
-
}
|
|
35
|
-
convertLegacy() {
|
|
36
|
-
var _a, _b;
|
|
37
|
-
if (!this.zotero.DebugLogSender)
|
|
38
|
-
return;
|
|
39
|
-
const plugins = this.zotero.DebugLogSender.plugins || {};
|
|
40
|
-
delete this.zotero.DebugLogSender;
|
|
41
|
-
const doc = (_a = this.zotero.getMainWindow()) === null || _a === void 0 ? void 0 : _a.document;
|
|
42
|
-
if (doc) {
|
|
43
|
-
(_b = doc.querySelector('menuitem#debug-log-menu')) === null || _b === void 0 ? void 0 : _b.remove();
|
|
44
|
-
for (const [plugin, preferences] of Object.entries(plugins)) {
|
|
45
|
-
this.register(plugin, preferences);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
18
|
element(name, attrs = {}) {
|
|
50
|
-
const doc =
|
|
19
|
+
const doc = Zotero.getMainWindow().document;
|
|
51
20
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
|
|
52
|
-
const elt = doc[
|
|
21
|
+
const elt = doc[Zotero.platformMajorVersion >= 102 ? 'createXULElement' : 'createElement'](name);
|
|
53
22
|
for (const [k, v] of Object.entries(attrs)) {
|
|
54
23
|
elt.setAttribute(k, v);
|
|
55
24
|
}
|
|
@@ -57,9 +26,8 @@ class DebugLogSender {
|
|
|
57
26
|
}
|
|
58
27
|
register(plugin, preferences = [], pubkey = '') {
|
|
59
28
|
var _a, _b;
|
|
60
|
-
|
|
61
|
-
const
|
|
62
|
-
const doc = (_a = this.zotero.getMainWindow()) === null || _a === void 0 ? void 0 : _a.document;
|
|
29
|
+
const label = 'Send debug log to 0x0';
|
|
30
|
+
const doc = (_a = Zotero.getMainWindow()) === null || _a === void 0 ? void 0 : _a.document;
|
|
63
31
|
if (doc) {
|
|
64
32
|
let menupopup = doc.querySelector(`#${this.id.menupopup}`);
|
|
65
33
|
if (menupopup) {
|
|
@@ -82,7 +50,7 @@ class DebugLogSender {
|
|
|
82
50
|
}
|
|
83
51
|
unregister(plugin) {
|
|
84
52
|
var _a, _b, _c;
|
|
85
|
-
const doc = (_a =
|
|
53
|
+
const doc = (_a = Zotero.getMainWindow()) === null || _a === void 0 ? void 0 : _a.document;
|
|
86
54
|
if (doc) {
|
|
87
55
|
(_b = doc.querySelector(`.debug-log-sender[label=${JSON.stringify(plugin)}]`)) === null || _b === void 0 ? void 0 : _b.remove();
|
|
88
56
|
const menupopup = doc.querySelector('#debug-log-sender-menupopup');
|
|
@@ -90,34 +58,24 @@ class DebugLogSender {
|
|
|
90
58
|
(_c = doc.querySelector('#debug-log-sender-menu')) === null || _c === void 0 ? void 0 : _c.remove();
|
|
91
59
|
}
|
|
92
60
|
}
|
|
93
|
-
alert(title, body) {
|
|
94
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
95
|
-
const ps = this.zotero.platformMajorVersion >= 102
|
|
96
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
97
|
-
? Services.prompt
|
|
98
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
99
|
-
: Components.classes['@mozilla.org/embedcomp/prompt-service;1'].getService(Components.interfaces.nsIPromptService);
|
|
100
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
101
|
-
ps.alert(null, title, body);
|
|
102
|
-
}
|
|
103
61
|
send(target) {
|
|
104
62
|
const elt = target;
|
|
105
63
|
const plugin = elt.getAttribute('label');
|
|
106
64
|
const preferences = JSON.parse(elt.getAttribute('data-preferences'));
|
|
107
65
|
const pubkey = elt.getAttribute('data-pubkey');
|
|
108
66
|
this.sendAsync(plugin, preferences, pubkey).catch((err) => {
|
|
109
|
-
|
|
67
|
+
Services.prompt.alert(null, 'Debug log submission error', `${err}`); // eslint-disable-line @typescript-eslint/restrict-template-expressions
|
|
110
68
|
});
|
|
111
69
|
}
|
|
112
|
-
async sendAsync(plugin, preferences, pubkey
|
|
113
|
-
await
|
|
70
|
+
async sendAsync(plugin, preferences, pubkey) {
|
|
71
|
+
await Zotero.Schema.schemaUpdatePromise;
|
|
114
72
|
const files = {};
|
|
115
73
|
const enc = new TextEncoder();
|
|
116
|
-
const key =
|
|
74
|
+
const key = Zotero.Utilities.generateObjectKey();
|
|
117
75
|
let log = [
|
|
118
76
|
await this.info(preferences),
|
|
119
|
-
|
|
120
|
-
|
|
77
|
+
Zotero.getErrors(true).join('\n\n'),
|
|
78
|
+
Zotero.Debug.getConsoleViewerOutput().slice(-250000).join('\n'), // eslint-disable-line no-magic-numbers
|
|
121
79
|
].filter((txt) => txt).join('\n\n').trim();
|
|
122
80
|
files[`${key}/debug.txt`] = enc.encode(log);
|
|
123
81
|
let rdf = await this.rdf();
|
|
@@ -125,26 +83,34 @@ class DebugLogSender {
|
|
|
125
83
|
files[`${key}/items.rdf`] = enc.encode(rdf);
|
|
126
84
|
// do this runtime because Zotero is not defined at start for bootstrapped zoter6 plugins
|
|
127
85
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
128
|
-
if (typeof FormData === 'undefined' &&
|
|
86
|
+
if (typeof FormData === 'undefined' && Zotero.platformMajorVersion >= 102)
|
|
129
87
|
Components.utils.importGlobalProperties(['FormData']);
|
|
130
88
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
131
|
-
|
|
132
|
-
|
|
89
|
+
const zip = new Uint8Array(UZip.encode(files));
|
|
90
|
+
let blob;
|
|
133
91
|
if (pubkey) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
92
|
+
try {
|
|
93
|
+
const subtle = Zotero.getMainWindow().crypto.subtle;
|
|
94
|
+
const pem = pubkey
|
|
95
|
+
.replace('-----BEGIN PUBLIC KEY-----', '')
|
|
96
|
+
.replace('-----END PUBLIC KEY-----', '')
|
|
97
|
+
.replace(/\s/g, '');
|
|
98
|
+
const keyBuffer = Uint8Array.from(atob(pem), c => c.charCodeAt(0)).buffer;
|
|
99
|
+
const publicKey = await subtle.importKey('spki', keyBuffer, { name: 'RSA-OAEP', hash: 'SHA-256' }, true, ['encrypt']);
|
|
100
|
+
const encrypted = await subtle.encrypt({ name: 'RSA-OAEP' }, publicKey, zip);
|
|
101
|
+
blob = new Blob([encrypted], { type: 'application/octet-stream' });
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
Services.prompt.alert(null, `Log encryption for ${plugin} failed`, err.message);
|
|
105
|
+
}
|
|
140
106
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
107
|
+
if (!blob)
|
|
108
|
+
blob = new Blob([zip], { type: 'application/zip' });
|
|
144
109
|
const formData = new FormData();
|
|
145
110
|
formData.append('file', blob, `${key}.zip`);
|
|
111
|
+
formData.append('expire', `${7 * 24}`);
|
|
146
112
|
try {
|
|
147
|
-
const response = await fetch(
|
|
113
|
+
const response = await fetch('https://0x0.st', {
|
|
148
114
|
method: 'POST',
|
|
149
115
|
body: formData,
|
|
150
116
|
headers: {
|
|
@@ -152,13 +118,13 @@ class DebugLogSender {
|
|
|
152
118
|
},
|
|
153
119
|
});
|
|
154
120
|
const body = await response.text();
|
|
155
|
-
const id = body.match(/https
|
|
121
|
+
const id = body.match(/https:\/\/0x0.st\/([A-Z0-9]+)\.zip/i);
|
|
156
122
|
if (!id)
|
|
157
123
|
throw new Error(body);
|
|
158
|
-
|
|
124
|
+
Services.prompt.alert(null, `Debug log ID for ${plugin}`, `${key}-0x0-${id[1]}`);
|
|
159
125
|
}
|
|
160
126
|
catch (err) {
|
|
161
|
-
|
|
127
|
+
Services.prompt.alert(null, `Could not post debug log for ${plugin}`, err.message);
|
|
162
128
|
}
|
|
163
129
|
}
|
|
164
130
|
preferences(preferences) {
|
|
@@ -177,7 +143,7 @@ class DebugLogSender {
|
|
|
177
143
|
}
|
|
178
144
|
}
|
|
179
145
|
for (const pref of names.sort()) {
|
|
180
|
-
prefs[pref] =
|
|
146
|
+
prefs[pref] = Zotero.Prefs.get(pref, true);
|
|
181
147
|
}
|
|
182
148
|
return prefs;
|
|
183
149
|
}
|
|
@@ -186,16 +152,16 @@ class DebugLogSender {
|
|
|
186
152
|
let info = '';
|
|
187
153
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
|
|
188
154
|
const appInfo = Components.classes['@mozilla.org/xre/app-info;1'].getService(Components.interfaces.nsIXULAppInfo);
|
|
189
|
-
info += `Application: ${appInfo.name} ${appInfo.version} ${
|
|
155
|
+
info += `Application: ${appInfo.name} ${appInfo.version} ${Zotero.locale}\n`;
|
|
190
156
|
const platform = ['Win', 'Mac', 'Linux'].find(p => Zotero[`is${p}`]) || 'Unknown';
|
|
191
|
-
const arch =
|
|
157
|
+
const arch = Zotero.oscpu || Zotero.arch;
|
|
192
158
|
info += `Platform: ${platform} ${arch}\n`;
|
|
193
|
-
const addons = await
|
|
159
|
+
const addons = await Zotero.getInstalledExtensions();
|
|
194
160
|
if (addons.length) {
|
|
195
161
|
info += 'Addons:\n' + addons.map((addon) => ` ${addon}\n`).join(''); // eslint-disable-line prefer-template
|
|
196
162
|
}
|
|
197
163
|
info += `Debug logging on at Zotero start: ${this.debugEnabledAtStart}\n`;
|
|
198
|
-
info += `Debug logging on at log submit: ${
|
|
164
|
+
info += `Debug logging on at log submit: ${Zotero.Prefs.get('debug.store') || Zotero.Debug.enabled}\n`;
|
|
199
165
|
for (const [pref, value] of Object.entries(this.preferences(preferences))) {
|
|
200
166
|
info += `${pref} = ${JSON.stringify(value)}\n`;
|
|
201
167
|
}
|
|
@@ -204,11 +170,11 @@ class DebugLogSender {
|
|
|
204
170
|
rdf() {
|
|
205
171
|
return new Promise((resolve, reject) => {
|
|
206
172
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
|
|
207
|
-
const items =
|
|
173
|
+
const items = Zotero.getActiveZoteroPane().getSelectedItems();
|
|
208
174
|
if (items.length === 0)
|
|
209
175
|
return resolve('');
|
|
210
176
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
211
|
-
const translation = new
|
|
177
|
+
const translation = new Zotero.Translate.Export();
|
|
212
178
|
translation.setItems(items);
|
|
213
179
|
translation.setTranslator('14763d24-8ba0-45df-8f52-b8d1108e7ac9'); // rdf
|
|
214
180
|
translation.setHandler('done', (obj, success) => {
|