Если помните об этом посте, то спешу вас обрадовать, он больше не актуален.
Маленькая шалость
Сейчас там вооот такая красота, в которой я, к сожалению своему, ещё не до конца разобралась. Но, по идее, на сколько я понимаю эту тему, это именно то, что нужно. Это не сам код, а любезно предоставленные разработчиками (или скопированные с GitHub'а, что весьма вероятно — там часто появляется ссылка на этот домен) примеры и пояснения (но в, отличие от кода, они довольно интересные).
/
*
* @Description
*
* A wrapper for messaging on WebKit platforms. It supports modern WebKit messageHandlers
* along with encryption for older versions (like macOS Catalina)
*
* Note: If you wish to support Catalina then you'll need to implement the native
* part of the message handling, see {@Link WebkitMessagingTransport} for details.
*/
// eslint-disable-next-line @TypeScript-eslint/no-unused-vars
/
* @Example
* On macOS 11+, this will just call through to window.webkit.messageHandlers.x.postMessage
*
* Eg: for a foo message defined in Swift that accepted the payload {"bar": "baz"}, the following
* would occur:
*
* * const json = await window.webkit.messageHandlers.foo.postMessage({ bar: "baz" });
* const response = JSON.parse(json)
*
*
* @Example
* On macOS 10 however, the process is a little more involved. A method will be appended to window
* that allows the response to be delivered there instead. It's not exactly this, but you can visualize the flow
* as being something along the lines of:
*
* * // add the window method
* window["_0123456"] = (response) => {
* // decrypt `response` and deliver the result to the caller here
* // then remove the temporary method
* delete window['_0123456']
* };
*
* // send the data + `messageHanding` values
* window.webkit.messageHandlers.foo.postMessage({
* bar: "baz",
* messagingHandling: {
* methodName: "_0123456",
* secret: "super-secret",
* key: [1, 2, 45, 2],
* iv: [34, 4, 43],
* }
* });
*
* // later in swift, the following JavaScript snippet will be executed
* (() => {
* window['_0123456']({
* ciphertext: [12, 13, 4],
* tag: [3, 5, 67, 56]
* })
* })()
*
* @implements {MessagingTrans
Этот фрагмент снизу и вовсе кусок от куска побольше, что, наверное, легко понять по ненормально большому количеству скобочек внизу. Тем не менее, в нём можно встретить все переменные, которые были в примере выше, и я нахожу это очень подозрительным (это единственное что мне остаётся — понятия не имею что такое async и с чем его едят). Из всего, могу сказать, что наверное мне надо начинать учиться разбираться во всём потихоньку... Этот сайт развивается явно успешнее чем я сама — это мотивирует учиться. Так что в общих планах на (следующий, а если не повезёт — через следующий) год прибавилось изучение HTML и JavaScript. По крайней мере всей той части, которая связана с JSON... Они же связаны как-то, да?
async wkSendAndWait (handler, data) {
if (this.config.hasModernWebkitAPI) {
const response = await this.wkSend(handler, data);
return this.globals.JSONparse(response || '{}')
}
try {
const randMethodName = this.createRandMethodName();
const key = await this.createRandKey();
const iv = this.createRandIv();
const {
ciphertext,
tag
} = await new this.globals.Promise((/ @type {any} */ resolve) => {
this.generateRandomMethod(randMethodName, resolve);
// @ts-expect-error - this is a carve-out for catalina that will be removed soon
data.messageHandling = new SecureMessagingParams({
methodName: randMethodName,
secret: this.config.secret,
key: this.globals.Arrayfrom(key),
iv: this.globals.Arrayfrom(iv)
});
this.wkSend(handler, data);
});
const cipher = new this.globals.Uint8Array([...ciphertext, ...tag]);
const decrypted = await this.decrypt(cipher, key, iv);
return this.globals.JSONparse(decrypted || '{}')
} catch (e) {
// re-throw when the error is just a 'MissingHandler'
if (e instanceof MissingHandler) {
throw e
} else {
console.error('decryption failed', e);
console.error(e);
return { error: e }
}
}
}
/
* @Param {import('../index.js').NotificationMessage} msg
*/
notify (msg) {
this.wkSend(msg.context, msg);
}
/
* @Param {import('../index.js').RequestMessage} msg
*/
async request (msg) {
const data = await this.wkSendAndWait(msg.context, msg);
Я там в коде по ходу разглядывания даже встретила некий "псевдорандомный генератор чисел на основе алгоритма Alea" (как мне после любезно подсказал GPT-chat). Это такая прикольная вещь!
(function(global, module, define) {
function Alea(seed) {
var me = this, mash = Mash();
me.next = function() {
var t = 2091639 * me.s0 + me.c * 2.3283064365386963e-10; // 2^-32
me.s0 = me.s1;
me.s1 = me.s2;
return me.s2 = t - (me.c = t | 0);
};
// Apply the seeding algorithm from Baagoe.
me.c = 1;
me.s0 = mash(' ');
me.s1 = mash(' ');
me.s2 = mash(' ');
me.s0 -= mash(seed);
if (me.s0 < 0) { me.s0 += 1; }
me.s1 -= mash(seed);
if (me.s1 < 0) { me.s1 += 1; }
me.s2 -= mash(seed);
if (me.s2 < 0) { me.s2 += 1; }
mash = null;
}
function copy(f, t) {
t.c = f.c;
t.s0 = f.s0;
t.s1 = f.s1;
t.s2 = f.s2;
return t;
}
Есть ещё такая штука, думаю, это тоже является каким-то псевдорандомом (по крайней мере, оно так же умножает в начале, как и в Alea.
function impl(seed, opts) {
var xg = new Alea(seed),
state = opts && opts.state,
prng = xg.next;
prng.int32 = function() { return (xg.next() * 0x100000000) | 0; };
prng.double = function() {
return prng() + (prng() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53
};
prng.quick = prng;
if (state) {
if (typeof(state) == 'object') copy(state, xg);
prng.state = function() { return copy(xg, {}); };
}
return prng;
}
function Mash() {
var n = 0xefc8249d;
var mash = function(data) {
data = String(data);
for (var i = 0; i < data.length; i++) {
n += data.charCodeAt(i);
var h = 0.02519603282416938 * n;
n = h >>> 0;
h -= n;
h *= n;
n = h >>> 0;
h -= n;
n += h * 0x100000000; // 2^32
}
return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
};
return mash;
}
if (module && module.exports) {
module.exports = impl;
} else if (define && define.amd) {
define(function() { return impl; });
} else {
this.alea = impl;
}
})(
commonjsGlobal,
module, // present in node.js
(typeof undefined) == 'function' // present with an AMD loader
);
} (alea$1));
var aleaExports = alea$1.exports;
var xor128$1 = {exports: {}};
xor128$1.exports;
(function (module) {
// A Javascript implementaion of the "xor128" prng algorithm by
// George Marsaglia. See http://www.jstatsoft.org/v08/i14/paper
(function(global, module, define) {
function XorGen(seed) {
var me = this, strseed = '';
me.x = 0;
me.y = 0;
me.z = 0;
me.w = 0;
// Set up generator function.
me.next = function() {
var t = me.x ^ (me.x << 11);
me.x = me.y;
me.y = me.z;
me.z = me.w;
return me.w ^= (me.w >>> 19) ^ t ^ (t >>> 8);
};
if (seed === (seed | 0)) {
// Integer seed.
me.x = seed;
} else {
// String seed.
strseed += seed;
}
// Mix in string seed, then discard an initial batch of 64 values.
for (var k = 0; k < strseed.length + 64; k++) {
me.x ^= strseed.charCodeAt(k) | 0;
me.next();
}
}
function copy(f, t) {
t.x = f.x;
t.y = f.y;
t.z = f.z;
t.w = f.w;
return t;
}
function impl(seed, opts) {
var xg = new XorGen(seed),
state = opts && opts.state,
prng = function() { return (xg.next() >>> 0) / 0x100000000; };
prng.double = function() {
do {
var top = xg.next() >>> 11,
bot = (xg.next() >>> 0) / 0x100000000,
result = (top + bot) / (1 << 21);
} while (result === 0);
return result;
};
prng.int32 = xg.next;
prng.quick = prng;
if (state) {
if (typeof(state) == 'object') copy(state, xg);
prng.state = function() { return copy(xg, {}); };
}
return prng;
}
if (module && module.exports) {
module.exports = impl;
} else if (define && define.amd) {
define(function() { return impl; });
} else {
this.xor128 = impl;
}
})(
commonjsGlobal,
module, // present in node.js
(typeof undefined) == 'function' // present with an AMD loader
);
} (xor128$1));
var xor128Exports = xor128$1.exports;
var xorwow$1 = {exports: {}};
xorwow$1.exports;
Насколько я понимаю, сайт растёт из-за чего товарищи программисты постарались над его общим видом, и защитой платёжной системы.
Раньше это выглядело как css-ная вставка, где в качестве примечания была написана рабочая "послеоплатная" ссылка (https://rumangalist.org/payment — она теперь всё равно не работает, так как путь заменён методом какого-то там разнообразного хеширования ииии я ещё не до конца разбираюсь в этой теме, но она меня ооооочень интригует). В общем, думаю, сайт будут развивать и дальше. Не зря же у них домен на год с чем-то вперёд проплачен?
Кстати. Вверху приведён кусок с МакОсными продуктами, но только потому, что у них самый красивый и ясный пример с этими данными, не то что бы мне принципиально. Ну вот и все новости на сегодня 〜(꒪꒳꒪)〜, так что на этом, пожалуй, всё.