Mga ugat na sanhi
In-upload ng dating editor ang working file nito sa parent directory ng target, na kadalasang hindi masulatan ng SSH account sa ilalim ng /etc o /var. Walang ibinigay ang SFTP rename na awtorisadong daan para sa sudo, pagsusuri ng conflict laban sa baseline, pag-verify ng security metadata o maaasahang semantika ng pag-overwrite. Binura ng error handler nito ang pansamantalang kopya, kaya nawala ang materyal para sa recovery kahit hindi tiyak kung natapos ang pag-save.
Dati, ang estado lamang ng koneksyon ang ipinapakita ng status ng session. Walang ICMP o naka-authenticate na pagsukat ng tugon ng SSH na nagpapakain sa indicator ng terminal.
Protocol sa pag-save
- Binubuksan ng isang nakapirming SSH helper ang isang regular na file na may iisang link gamit ang mga descriptor-relative na operasyon at
O_NOFOLLOWpara sa bawat bahagi ng path. Kinukuha nito ang laman, SHA-256 hash, device/inode, UID, GID, kumpletong permission bit, mga oras ng pagbabago/modipikasyon sa nanosecond at lahat ng nababasang extended attribute. Bine-verify ng Core ang hash at mahigpit na dine-decode ang UTF-8, habang pinapanatili ang BOM. Nakakakuha ang bawat dokumento ng opaque naeditId, na nakasaklaw sa plugin, terminal session at pagkakakilanlan ng server nito. - Nire-resolve ng isang hindi privileged na operasyon sa paghahanda ang home ng naka-authenticate na account sa pamamagitan ng
pwd.getpwuid(os.getuid()), ginagawa ang$HOME/ch-j-sm/na may mode na0700, at gumagawa ng pribado at eksklusibong recovery journal. Tinatanggihan ang hindi ligtas na home, workspace na symlink o workspace na pagmamay-ari ng ibang account. - Nag-a-upload ang Core ng nakatagong
.tmpworking file na may random na 128-bit na pangalan sa pamamagitan ng SFTP na may eksklusibong paggawa (wx), mode na0600at animnapung segundong timeout ng channel/upload. Naglalaman ang journal ng target, ng orihinal na baseline at ng inaasahang hash ng working file; wala itong mga kredensyal. - Iisang SSH exec ang gumagawa ng buong finalization, opsyonal sa pamamagitan ng umiiral na sudo executor. Ligtas na binubuksan at hina-hash ng helper ang pribadong working copy at isinusulat ito sa disk (flush). Nila-lock nito ang orihinal na inode, sinusuri ang baseline nito, gumagawa ng eksklusibong destination file sa tabi ng target, isinusulat ang lahat ng laman, inilalapat at bine-verify ang metadata, muling sinusuri ang orihinal at isinusulat sa disk ang kapalit.
- Atomikong pinapalitan ng
os.replacesa parehong direktoryo ang target. Isinusulat sa disk ang parent directory at bine-verify ang huling path, hash, inode at metadata. Nananatiling available ang orihinal na path hanggang sa pagpapalit. Hindi kailanman inililipat ang working file sa ibang filesystem at hindi kailanman ito inaalis ng finalization. - Pagkatapos makatanggap ang Core ng na-verify na tagumpay, muling sinusuri ng hiwalay na cleanup ang huling laman at security metadata bago alisin ang working file at journal. Kahit mabigo ang cleanup, iniuulat pa rin ang kumpirmadong pag-save na may
recoveryAvailable: true.
Pinapanatili ng nabigong upload, nabigong sudo, conflict, error sa metadata o nabigong pagpapalit ang orihinal at anumang inihandang materyal. Kinikilala bilang ganoon ang mga hindi kumpletong upload at hindi maaaring i-recover bilang kumpletong na-edit na dokumento. Iniuulat bilang hindi alam ang nawalang komunikasyon sa SSH, nawawalang exit status, mga timeout at hindi inaasahang resulta ng finalization, hindi kailanman bilang na-save. Bina-block ng Core ang isa pang pag-save sa dokumentong hindi tiyak ang resulta; walang awtomatikong muling pagsubok ng pagpapalit.
Metadata, mga pribilehiyo at mga hangganan ng kaligtasan
Pinapanatili at bine-verify ng helper ang UID, GID at lahat ng POSIX permission bit, kasama ang executable, setuid, setgid at sticky bit. Ginagaya nito nang byte por byte ang mga extended attribute ng Linux, kasama ang mga POSIX ACL, capabilities at SELinux label. Itinatakda ang pagmamay-ari at laman ng file bago ang mga security attribute, dahil maaaring burahin ng pagsulat/chown ang capabilities o mga espesyal na permission bit. Inaalis ang mga minanang attribute sa destinasyon na wala sa orihinal. Ipinapakita ng oras ng modipikasyon ang bagong pagsulat at hindi ito kinokopya mula sa orihinal.
Hinihinto ng attribute na hindi mabasa o hindi maipakita ang operasyon; hindi tahimik na itinatapon ang metadata. Tahasang tinatanggihan ang mga IMA/EVM signature dahil magiging hindi wasto ang mga integrity signature na nakatali sa laman/inode kapag kinopya. Tinatanggihan ang mga symlink sa target o home path, mga file na may hard link at mga hindi regular na file. Walang ginagamit na in-place o mas mahinang fallback sa pag-overwrite sa SFTP.
Tumatakbo bilang SSH account ang mga karaniwang pag-save na may pahintulot sa pagsulat. Nangangailangan ang mga protektadong pag-save ng tahasang { sudo: true }; opsyonal ang sudo password para sa passwordless sudo. Bine-validate ang mga password at ipinapasa lamang sa stdin ng channel, hindi kailanman sa loob ng command, journal, working file, logger o remote error. Gumagamit ang mga root SSH session ng umiiral na direktang root executor. Iniiwang buo ng nabigong awtorisasyon ang orihinal at ang working copy. Tinatanggihan din ng lahat ng pag-save na tumatakbo bilang root (direktang root SSH o sudo) ang mga target directory/ancestor na pagmamay-ari o masusulatan ng ibang account, o may access ACL, sa halip na pagkatiwalaan ang privileged na pathname na kontrolado ng ibang account.
Tumatakbo ang nakapirming helper gamit ang python3 -I -B: hindi nito pinapansin ang mga Python path ng user, ang working directory at ang mga site package ng user, at hindi ito sumusulat ng bytecode. Shell-quoted sa Core ang mga path at JSON argument. Hindi kailanman nakakatanggap ang mga plugin ng arbitraryong SSH exec o mga SFTP handle. Patuloy na ginagamit ang umiiral na sandbox, CSP, mga pahintulot sa manifest, pag-verify ng host key at pag-verify ng update.
Plugin API at ang natitirang integrasyon ng Monaco
Wala sa checkout na ito ang hiwalay na ipinamamahaging Monaco/File Manager UI. Hindi maipatupad o masubukan dito ang integrasyon ng UI nito, ang sudo prompt, ang paghawak sa hindi pa naka-save na buffer at ang mga salin nito. Ang kasamang source ng plugin ay ang Hash & Checksum plugin. Walang inimbentong kapalit na source ng File Manager.
Nananatiling available ang mga umiiral na method. Inilalantad ng naka-sandbox na preload at ng runtime na sumusuri ng pahintulot ang mga karagdagang method/opsyon:
const opened = await chjPlugin.files.readText(sessionId, path);
// For a protected read, explicitly pass { sudo: true, sudoPassword }.
const result = await chjPlugin.files.saveText(sessionId, path, editor.getValue(), {
editId: opened.editId,
sudo: true, // Include only after the user authorizes elevation.
sudoPassword // Omit for passwordless sudo; never persist this value.
});
if (result.ok && result.value.status === "saved") {
// Mark this exact submitted editor version as saved. Later edits stay dirty.
} else {
// Keep the Monaco model dirty. Translate result.error.code/status.
// result.error.recoveryId/recoveryPath identify retained working material.
}
await chjPlugin.files.closeText(opened.editId);
const recovery = await chjPlugin.files.listRecovery(sessionId);
const copy = await chjPlugin.files.readRecovery(sessionId, recoveryId);
// Review copy.status and copy.text; open a fresh document before another save.
await chjPlugin.files.cleanupRecovery(sessionId, recoveryId);
// Cleanup rejects anything whose target is not currently confirmed.
Tumatanggap ang mga recovery method ng opsyonal na huling argument na { sudo: true, sudoPassword } kapag nangangailangan ng elevation ang pagsusuri sa target. Pinananatili nila ang workspace ng naka-authenticate na user kahit tumatakbo sa pamamagitan ng sudo. Nananatili ang mga journal pagkatapos i-restart ang app at muling kumonekta sa SSH; hindi kailanman awtomatikong inuulit ng recovery ang finalization. Suriin ang na-recover na buffer laban sa bagong bukas na target bago ito tahasang i-save.
Binabantayan ng files.read ang mga pagbasa, pagsusuri at pagpapakawala ng handle. Binabantayan ng files.write ang mga pag-save at ang cleanup ng recovery. Nagre-reject pa rin ang writeText kapag nabigo para sa mga umiiral na plugin; nagbabalik ang saveText ng structured na envelope na { ok, value/error } dahil itinatapon ng Electron ang mga custom na property sa mga na-reject na Error object. Maaaring gamitin ng legacy na writeText na may tatlong argument ang baseline ng iisang bukas na dokumento. Nangangailangan ng editId ang maraming live na dokumento para sa parehong path; ligtas na nabibigo ang malabong legacy na tawag sa halip na pumili ng baseline ng ibang dokumento. Dapat pakawalan ng mga plugin ang mga hindi ginagamit na handle.
Dapat agad na ipakita ng panlabas na UI ang pag-save, panatilihing hindi naka-save ang mga buffer kapag nabigo, mag-alok ng sudo pagkatapos lamang ng mga pagkabigo sa pahintulot/authentication, ipakita ang mga conflict nang hindi nag-o-overwrite, at mag-alok ng recovery pagkatapos mawala ang koneksyon o kapag hindi alam ang resulta. Dapat nitong isalin ang mga estadong ito sa Czech, German at English. Iminumungkahing teksto ng estado:
| Estado | Czech | German | English |
|---|---|---|---|
| Nagse-save | Ukládání… | Wird gespeichert… | Saving… |
| Kumpirmado | Uloženo | Gespeichert | Saved |
| Pagkabigo | Uložení selhalo | Speichern fehlgeschlagen | Save failed |
| Kailangan ng sudo | Vyžadováno oprávnění sudo | sudo-Autorisierung erforderlich | Sudo authorization required |
| Conflict | Původní soubor byl změněn | Originaldatei wurde geändert | Original file changed |
| Nadiskonekta | Spojení bylo přerušeno | Verbindung unterbrochen | Connection lost |
| Hindi alam | Výsledek uložení není znám | Speicherergebnis unbekannt | Save result unknown |
| Recovery | Obnova je dostupná | Wiederherstellung verfügbar | Recovery available |
Mga kahulugan ng latency at lifecycle
Ang Ping ay ang latency na iniuulat ng aktwal na ICMP echo reply sa panig ng client papunta sa na-resolve na IP na ginagamit ng SSH. Asynchronous na tinatawag ng Core ang ping executable ng platform gamit ang nakapirming argument array, nang walang shell o kinakailangang pagsisimula bilang administrator. Hiwalay na pinipili ang mga argument para sa Linux, macOS (kasama ang ping6) at Windows. Nagbibigay ng hindi available na value, hindi ng inimbentong numero, ang naka-block na ICMP, nawawalang executable, timeout, hindi wastong output o Windows reply na upper bound lamang tulad ng <1ms.
Ang SSH RTT ay ang monotonic na tagal ng performance.now() ng isang nakapirming true exec request sa umiiral na naka-authenticate na SSH client. Kasama rito ang pag-set up ng channel, pagproseso ng server at paghahatid ng tugon; hindi ito purong network RTT o tagal ng pag-login sa SSH. Ipinapaliwanag ng isinaling tooltip ng indicator ang pagkakaibang ito.
Nagsisimula ang pagsubaybay sa sandaling kumonekta ang terminal. Sabay-sabay at asynchronous na tumatakbo ang mga probe, na may limang segundong timeout ng kahilingan/proseso. Iniiskedyul ang susunod na sample labindalawang segundo pagkatapos matapos ang nakaraang sample, para maiwasan ang pagsasapaw. Hinihinto ng pagdiskonekta ang ICMP, nililinis ang mga timer, kinakansela ang nakabinbing gawain sa SSH at nililinis ang mga value. Pinipigilan ng mga pagsusuri sa pagkakakilanlan ng record na maglathala ang dating koneksyon pagkatapos muling kumonekta. Hindi kailanman binabago ng pagkabigo ng ICMP ang estado ng koneksyon sa SSH.
Dumadaan ang latency sa loob ng umiiral na IPC payload ng state event / ssh:state:
latency: { pingMs: 24.1, sshRttMs: 31.25, measuredAt: "…" }
null ang mga numerong hindi available. Gumagamit ang compact na indicator ng terminal ng millisecond, naka-localize na teksto para sa hindi available, at mga label sa Czech/German/English. Nagtatago ito kapag nadiskonekta. Walang kinailangang karagdagang kakayahan sa pagpapatakbo ng renderer o IPC request.
Pag-validate at mga limitasyon sa operasyon
- Patakbuhin mula sa
app/:npm ci, pagkatapos aynpm test. - Huling lokal na resulta: 179 na test; 163 ang pumasa, 0 ang nabigo, 16 ang nilaktawan. Ang lahat ng nilaktawan ay mga kaso ng Linux filesystem sa macOS host na ito. Matagumpay na natapos ang
npm ci, ang syntax compilation ng Python at anggit diff --check. - Saklaw ng mga test ang pag-save/recovery ng Core, sudo protocol at pagtatago ng password, totoong POSIX shell quoting ng mapanganib na mga path, mga conflict, upload, nabigong cleanup, hindi tiyak na resulta, sabay-sabay na dokumento, mga pahintulot sa IPC at lifecycle ng latency.
- Pinapatakbo ng mga Linux filesystem test ang ipinadalang Python entry point, gamit ang pribadong paghahanap ng home ng test account: pagmamay-ari/mode/xattrs, POSIX ACL, mga symlink/hardlink, FIFO, pagkabigo ng upload at metadata, pagkabigo ng pagpapalit, mga race sa target, hindi alam na resulta pagkatapos ng pagpapalit at recovery. Gumagamit ang paghahanda sa ibang filesystem ng
/dev/shmat ng isa pang filesystem kapag available. Nilalaktawan ang mga test na ito sa mga host na hindi Linux; tahasang nilalaktawan ang mga nawawalang pasilidad para sa ACL/hiwalay na filesystem. - Pinapatakbo ng idinagdag na GitHub Actions job para sa Linux ang buong suite at inuulit ang mga kaso ng filesystem bilang root. Hindi pa naipapadala ang workflow na ito mula sa working tree na ito.
- Ginawa ang lokal na pag-validate sa macOS. Sinuri ang syntax ng Python source gamit ang direktang Python executable ng Command Line Tools. Nagbalik ng
0.071 msang isang totoong macOS loopback ICMP smoke check. Walang live na remote SSH server, Windows runtime, Linux runtime, SELinux deployment o panlabas na Monaco UI na nasubukan nang lokal. - Nangangailangan na ngayon ang remote na pag-edit ng teksto ng Linux at Python 3 na may suporta sa descriptor-relative na filesystem/xattr. Tahasang nabibigo kapag nawawala ang interpreter. Sinasadyang tinatanggihan ng Core na ito ang hindi ligtas na metadata, mga link at configuration ng direktoryo.
- Advisory ang pag-lock: maaari pa ring mag-race ang mga prosesong hindi nakikipagtulungan sa makitid na pagitan ng huling pagsusuri sa baseline at ng atomikong rename. Walang ibinibigay ang Linux na pangkalahatang atomikong operasyon na naghahambing ng content hash at nagpapalit. Natutukoy ng mga pagsusuri ang mga pagbabago bago ang pagitang iyon; sinusuportahan ng mga naiwang working copy ang recovery pagkatapos.
- Nananatili sa remote na account ang data ng recovery hanggang sa kumpirmadong cleanup. Hindi kailanman tahimik na itinatapon ang mga hindi kumpleto, may conflict at hindi masuring journal. Walang awtomatikong pag-expire ng recovery file at walang opsyon para sa sapilitang pag-overwrite.
- Nag-ulat ang
npm cing 17 natuklasan sa dependency audit (9 katamtaman, 8 mataas). Hindi binabago ng pagbabagong ito ang mga dependency o ang modelo ng tiwala sa update ng application.
Hiniling ng user na panatilihin ang mga pagbabago sa umiiral na working tree, kasalukuyang feature/hash-checksum-plugin; walang ginawang paglipat ng branch o hindi kaugnay na paglilinis.
Mga file na binago para sa gawaing ito
src/main/files/remoteFileService.jssrc/main/files/remoteEditor.py(bago)src/main/sessions/sessionManager.jssrc/main/sessions/latencyMonitor.js(bago)src/main/plugins/pluginRuntime.jssrc/preload/pluginPreload.jssrc/renderer/app.jssrc/renderer/index.htmlsrc/renderer/styles.csssrc/renderer/i18n.jstest/remoteFileService.test.jstest/sessionManager.test.jstest/pluginRuntime.test.jstest/remoteEditor.test.js(bago)test/remoteEditorProtocol.test.js(bago)test/remoteEditorLinux.test.js(bago)test/fixtures/remoteEditorLinux.py(bago)test/latencyMonitor.test.js(bago)README.mddocs/remote-editor-latency.md(ang file na ito)../.github/workflows/remote-editor-tests.yml(bago)