44 lines
2 KiB
TypeScript
44 lines
2 KiB
TypeScript
import { log } from '../logger';
|
|
import { normalizeReferer } from '../utils/uri';
|
|
|
|
export async function fetchKey(keyUri: string, referer?: string, origin?: string): Promise<Uint8Array> {
|
|
const fallbackReferer = document.location.href;
|
|
const fallbackOrigin = new URL(document.location.href).origin;
|
|
const effectiveReferer = normalizeReferer(keyUri, referer || fallbackReferer);
|
|
const effectiveOrigin = origin || (referer ? new URL(referer).origin : fallbackOrigin);
|
|
|
|
log.info(`fetchKey request: url=${keyUri} referer=${effectiveReferer} origin=${effectiveOrigin}`);
|
|
|
|
return new Promise((resolve, reject) => {
|
|
(GM_xmlhttpRequest as any)({
|
|
method: 'GET',
|
|
url: keyUri,
|
|
responseType: 'arraybuffer',
|
|
headers: {
|
|
'Referer': effectiveReferer,
|
|
'Origin': effectiveOrigin,
|
|
},
|
|
onload: (response: any) => {
|
|
log.info(`fetchKey response: status=${response.status} readyState=${response.readyState} headers=${JSON.stringify(response.responseHeaders)}`);
|
|
if (response.status >= 200 && response.status < 300) {
|
|
const buffer = response.detail?.response || response.response;
|
|
const keyBytes = new Uint8Array(buffer);
|
|
log.info(`fetchKey: ${keyUri} size=${keyBytes.length} bytes`);
|
|
|
|
if (keyBytes.length !== 16) {
|
|
log.warn(`fetchKey: key is ${keyBytes.length} bytes, expected 16 for AES-128`);
|
|
}
|
|
|
|
resolve(keyBytes);
|
|
} else {
|
|
log.error(`fetchKey HTTP error: status=${response.status} url=${keyUri} responseHeaders=${JSON.stringify(response.responseHeaders)}`);
|
|
reject(new Error(`Key fetch failed: HTTP ${response.status}`));
|
|
}
|
|
},
|
|
onerror: (error: any) => {
|
|
log.error(`fetchKey network error: url=${keyUri} error=${error.error} status=${error.status} readyState=${error.readyState} responseHeaders=${JSON.stringify(error.responseHeaders || {})}`);
|
|
reject(new Error(`Key fetch error: ${error.error}`));
|
|
},
|
|
});
|
|
});
|
|
}
|