blob: 95a257e51743a2df39c722cf925f742edfa85354 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
/**
* Message validation helpers (background side).
*
* All messages received from content scripts must pass through these
* validators before they are used. The page origin is untrusted
* (Security.md §7): every field is type-checked and length-limited.
*/
import { CONTENT_TO_BG, MAX_SELECTION_LENGTH } from './constants.js';
/**
* Generate a random request id. Uses crypto.randomUUID when available and
* falls back to a random-hex string otherwise.
* @returns {string}
*/
export function createRequestId() {
if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
return crypto.randomUUID();
}
const bytes = new Uint8Array(16);
if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') {
crypto.getRandomValues(bytes);
} else {
for (let i = 0; i < bytes.length; i++) bytes[i] = Math.floor(Math.random() * 256);
}
return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');
}
/**
* @param {*} message
* @returns {boolean} true when the message is a valid translate request.
*/
export function isValidTranslateRequest(message) {
if (message === null || typeof message !== 'object' || Array.isArray(message)) {
return false;
}
if (message.type !== CONTENT_TO_BG.TRANSLATE) return false;
if (typeof message.requestId !== 'string' || message.requestId.length === 0 || message.requestId.length > 128) {
return false;
}
if (typeof message.text !== 'string') return false;
if (message.text.length === 0) return false;
if (message.text.length > MAX_SELECTION_LENGTH) return false;
return true;
}
/**
* @param {*} message
* @returns {boolean} true when the message is a valid cancel request.
*/
export function isValidCancelRequest(message) {
if (message === null || typeof message !== 'object' || Array.isArray(message)) {
return false;
}
if (message.type !== CONTENT_TO_BG.CANCEL) return false;
return typeof message.requestId === 'string' && message.requestId.length > 0 && message.requestId.length <= 128;
}
/**
* Check whether the sender is a background-trusted extension context
* (i.e. a message coming from our own content script, popup or options).
* @param {unknown} sender WebExtensions MessageSender
* @returns {boolean}
*/
export function isTrustedSender(sender) {
// Only extension-internal senders carry an id; external senders are not
// accepted anyway because onMessageExternal is not used.
return Boolean(sender && sender.id);
}
|