feat(vikingfile): przechwytuj bezposredni link zamiast pokazywac strone

Jan slusznie zapytal, czy WebView jest w ogole potrzebny. Rozlozylem protokol do
konca: po przejsciu zabezpieczenia strona robi POST na WLASNY adres z cialem
'cf-turnstile-response=<token>' i dostaje JSON z polem link, czyli gotowy plik.
Endpoint to po prostu adres strony pliku, nie zadne osobne API.

Bez tokenu sie nie da: POST z pustym albo brakujacym cf-turnstile-response oddaje
zwykly HTML (701 kB), a nie JSON. Sprawdzone trzy warianty ciala. Tokenu nie
wyprodukuje klient HTTP, bo wymaga silnika JS. Ale NIE wymaga czlowieka: widget jest
w trybie flexible z callbackiem, wiec na czystym domowym laczu przechodzi sam.

Wykorzystujemy to: WebView zostaje jako silnik JS, tylko podsluchujemy ten jeden POST
i gdy w odpowiedzi pojawi sie link, oddajemy go aplikacji przez istniejacy kanal
video_url. Aplikacja przechodzi wtedy na NATYWNY odtwarzacz, bez reklam i bez
ogladania strony hostera. Oswojony wyglad strony zostaje jako zabezpieczenie na
wypadek, gdyby zabezpieczenie jednak zazadalo kliniecia.

Blok zwalidowany jako realny JavaScript (new Function po zamianie podwojnych
backslashy na pojedyncze, tak jak robi to szablon). Typecheck bez nowych bledow.

Opublikowane OTA na 1.2 i 1.1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
goon-foss 2026-08-22 19:46:13 +02:00
parent 1154834170
commit 1f73dad7d3
2 changed files with 30 additions and 1 deletions

View file

@ -20,7 +20,7 @@ export const CHANGELOG: ChangelogEntry[] = [
id: '2026-08-22b', id: '2026-08-22b',
date: 'August 2026', date: 'August 2026',
items: [ items: [
'Older galaxyporn scenes no longer open a blank page. They now live on a file host whose page is mostly site furniture, so the app strips it down to just the confirm-you-are-human box and the video, with a line telling you what to tap. Once the video appears it takes over the screen.', 'Older galaxyporn scenes no longer open a blank page. They moved to a file host, and the app now grabs the video file straight from it and plays it in the normal player, so in most cases you will not see that page at all. If the host does ask you to confirm you are human, the page is stripped down to just that box and the video.',
], ],
}, },
{ {

View file

@ -1197,6 +1197,35 @@ const INJECTED_JS = `
}; };
document.addEventListener('DOMContentLoaded', vkReady); document.addEventListener('DOMContentLoaded', vkReady);
setInterval(vkReady, 600); setInterval(vkReady, 600);
// Bezposredni adres pliku DA sie przechwycic i nie trzeba do tego ogladac strony.
// Po przejsciu zabezpieczenia strona robi POST na WLASNY adres z cialem
// 'cf-turnstile-response=<token>' i dostaje JSON z polem link, czyli gotowy plik.
// Sam token wymaga silnika JS (bez niego serwer oddaje HTML zamiast JSON-a,
// sprawdzone), ale widget jest w trybie flexible z callbackiem, wiec na zwyklym
// domowym laczu przechodzi sam, bez klikania. Podsluchujemy wiec ten jeden POST i
// gdy tylko link sie pojawi, oddajemy go aplikacji, ktora przechodzi na natywny
// odtwarzacz. Oswojony wyglad strony zostaje jako zabezpieczenie na wypadek, gdyby
// zabezpieczenie jednak zazadalo kliniecia.
var vkOpen = XMLHttpRequest.prototype.open;
var vkSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.open = function() { return vkOpen.apply(this, arguments); };
XMLHttpRequest.prototype.send = function() {
var self = this;
try {
self.addEventListener('load', function() {
try {
var j = JSON.parse(self.responseText);
if (j && j.link && window.ReactNativeWebView) {
window.ReactNativeWebView.postMessage(
JSON.stringify({ type: 'video_url', url: j.link })
);
}
} catch (e) {}
});
} catch (e) {}
return vkSend.apply(this, arguments);
};
} }
} catch (e) {} } catch (e) {}