chore: sprint D — sandbox, self-hosted fonts, logger с ротацией

#6  sandbox: true на обоих BrowserWindow (раньше false). Preload
    использует только contextBridge + ipcRenderer (оба sandbox-safe),
    никаких Node-built-ins. OS-уровневый sandbox изолирует renderer
    от GPU/IPC процессов; даже RCE в зависимости renderer'а не
    получит Node-доступа через preload.

#17 self-host шрифтов через @fontsource/* пакеты. Раньше тянулись
    с fonts.googleapis.com — внешняя CSP-зависимость + отсутствие
    интернета = шрифты не загружались. Теперь .woff/.woff2 в bundle
    (22 файла × 15-30KB = ~500KB).
    Подкрутили CSP: убрали https://fonts.* origins, добавили
    connect-src 'self', base-uri 'self', frame-ancestors 'none'.

#22 src/main/logger.ts — структурный лог с уровнями
    (debug/info/warn/error) и ротацией. Пишет в
    %APPDATA%/Exercise Reminder/logs/latest.log (≤1MB) и
    дублирует в console. При 1MB latest.log → prev.log
    (предыдущий prev.log удаляется). LAUDE_DEBUG=1 включает
    debug-уровень.

    Подключён в hot paths: store (corrupt/atomic write fails),
    updater (silent check errors), gsi-server (bad requests,
    handler throws), games/registry (GSI start, reconcile, match_end
    summary), games/dota2 (rejected token, POST_GAME detection).

    Особенно полезно для диагностики «челленджи не срабатывают»:
    лог покажет (а) пришёл ли вообще GSI payload (token verify),
    (б) детектировался ли POST_GAME, (в) сколько challenges были
    enabled и которые из них дали 0 reps.

    Logger — единственный файл с `eslint-disable no-console` (он
    намеренно дублирует в stderr).
This commit is contained in:
AnRil
2026-05-22 01:24:30 +07:00
parent e7ccca98e7
commit 34fb03b265
11 changed files with 254 additions and 27 deletions

34
package-lock.json generated
View File

@@ -1,13 +1,16 @@
{
"name": "laude",
"version": "0.5.1",
"version": "0.5.4",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "laude",
"version": "0.5.1",
"version": "0.5.4",
"dependencies": {
"@fontsource/bricolage-grotesque": "^5.2.10",
"@fontsource/jetbrains-mono": "^5.2.8",
"@fontsource/plus-jakarta-sans": "^5.2.8",
"electron-updater": "^6.8.3",
"framer-motion": "^11.11.17",
"lucide-react": "^0.460.0",
@@ -1264,6 +1267,33 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/@fontsource/bricolage-grotesque": {
"version": "5.2.10",
"resolved": "https://registry.npmjs.org/@fontsource/bricolage-grotesque/-/bricolage-grotesque-5.2.10.tgz",
"integrity": "sha512-V2xS+1P7C8IrSypXLUx/bLtX/LsTlYtV2k2CsU+S/0t8qepZ2hvKSlyJIx7Ub/iY8Bbnj+IjAuUF9nvFz+BbIg==",
"license": "OFL-1.1",
"funding": {
"url": "https://github.com/sponsors/ayuhito"
}
},
"node_modules/@fontsource/jetbrains-mono": {
"version": "5.2.8",
"resolved": "https://registry.npmjs.org/@fontsource/jetbrains-mono/-/jetbrains-mono-5.2.8.tgz",
"integrity": "sha512-6w8/SG4kqvIMu7xd7wt6x3idn1Qux3p9N62s6G3rfldOUYHpWcc2FKrqf+Vo44jRvqWj2oAtTHrZXEP23oSKwQ==",
"license": "OFL-1.1",
"funding": {
"url": "https://github.com/sponsors/ayuhito"
}
},
"node_modules/@fontsource/plus-jakarta-sans": {
"version": "5.2.8",
"resolved": "https://registry.npmjs.org/@fontsource/plus-jakarta-sans/-/plus-jakarta-sans-5.2.8.tgz",
"integrity": "sha512-P5qE49fqdeD+7DXH1KBxmMPlB17LTz1zvBhFH0tFzfnYTKVJVyb0pR6plh0ZGXxcB+Oayb54FZZw3V42/DawTw==",
"license": "OFL-1.1",
"funding": {
"url": "https://github.com/sponsors/ayuhito"
}
},
"node_modules/@gar/promisify": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",