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 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
- print(private_pem.decode('utf-8'))
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.23",
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 = this.zotero.getMainWindow().document;
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[this.zotero.platformMajorVersion >= 102 ? 'createXULElement' : 'createElement'](name);
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
- this.convertLegacy();
61
- const label = 'Send debug log to bashupload.com';
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 = this.zotero.getMainWindow()) === null || _a === void 0 ? void 0 : _a.document;
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
- this.alert('Debug log submission error', `${err}`); // eslint-disable-line @typescript-eslint/restrict-template-expressions
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 = null) {
113
- await this.zotero.Schema.schemaUpdatePromise;
70
+ async sendAsync(plugin, preferences, pubkey) {
71
+ await Zotero.Schema.schemaUpdatePromise;
114
72
  const files = {};
115
73
  const enc = new TextEncoder();
116
- const key = this.zotero.Utilities.generateObjectKey();
74
+ const key = Zotero.Utilities.generateObjectKey();
117
75
  let log = [
118
76
  await this.info(preferences),
119
- this.zotero.getErrors(true).join('\n\n'),
120
- this.zotero.Debug.getConsoleViewerOutput().slice(-250000).join('\n'), // eslint-disable-line no-magic-numbers
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' && this.zotero.platformMajorVersion >= 102)
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
- let zip = new Uint8Array(UZip.encode(files));
132
- /*
89
+ const zip = new Uint8Array(UZip.encode(files));
90
+ let blob;
133
91
  if (pubkey) {
134
- const publicKey = await openpgp.readKey({ armoredKey: pubkey })
135
- const encrypted = await openpgp.encrypt({
136
- message: await openpgp.createMessage({ binary: zip }),
137
- encryptionKeys: publicKey,
138
- })
139
- zip = encrypted
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
- const blob = new Blob([zip], { type: 'application/zip' });
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(`https://bashupload.com/${key}.zip`, {
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:[/][/]bashupload.com[/]([A-Z0-9]+)[/][A-Z0-9]+[.]zip/i);
121
+ const id = body.match(/https:\/\/0x0.st\/([A-Z0-9]+)\.zip/i);
156
122
  if (!id)
157
123
  throw new Error(body);
158
- this.alert(`Debug log ID for ${plugin}`, `${key}-buc-${id[1]}. If you sent this log in error, visit ${id[0]} and it will be automatically removed.`);
124
+ Services.prompt.alert(null, `Debug log ID for ${plugin}`, `${key}-0x0-${id[1]}`);
159
125
  }
160
126
  catch (err) {
161
- this.alert(`Could not post debug log for ${plugin}`, err.message);
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] = this.zotero.Prefs.get(pref, true);
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} ${this.zotero.locale}\n`;
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 = this.zotero.oscpu || this.zotero.arch;
157
+ const arch = Zotero.oscpu || Zotero.arch;
192
158
  info += `Platform: ${platform} ${arch}\n`;
193
- const addons = await this.zotero.getInstalledExtensions();
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: ${this.zotero.Prefs.get('debug.store') || this.zotero.Debug.enabled}\n`;
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 = this.zotero.getActiveZoteroPane().getSelectedItems();
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 this.zotero.Translate.Export();
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) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zotero-plugin",
3
- "version": "5.0.23",
3
+ "version": "5.0.25",
4
4
  "description": "Zotero plugin builder",
5
5
  "homepage": "https://github.com/retorquere/zotero-plugin/wiki",
6
6
  "bin": {