Skip to content
This repository was archived by the owner on Oct 25, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
e776e24
feat: implement native child webview command for email rendering and …
FixeQD May 2, 2026
b2d1ec8
ui(webview): Use native child Webview overlay
FixeQD May 2, 2026
2239a8e
core(mail): Return ThreadView and ThreadMessage
FixeQD May 2, 2026
17fd444
db(mail): Stop sanitizing HTML body on save
FixeQD May 2, 2026
8f8d296
core(mail): Load message bodies from encrypted cache and IMAP
FixeQD May 2, 2026
1aa65ac
refactor: replace Tauri child webview with native GtkOverlay and webk…
FixeQD May 3, 2026
17416e3
feat: mark task 27.4 as complete in TODO list
FixeQD May 4, 2026
d4f6a8a
feat: implement email-webview capability with restricted permissions
FixeQD May 4, 2026
f3c0255
core(watchdog): Add watchdog state and email_heartbeat command
FixeQD May 4, 2026
dbb0f29
auth(security): Refactor TPM checks and add webview permissions
FixeQD May 4, 2026
efa3a39
core(watchdog): Inject heartbeat script and rotate nonce
FixeQD May 4, 2026
a658ef6
docs(todo): Mark JS heartbeat as complete
FixeQD May 4, 2026
71a0ab9
feat: watchdog loop with adaptive freeze threshold
FixeQD May 5, 2026
b9d7591
Merge branch 'dev/isolated-messageview' of github.com:FixeQD/postail-…
FixeQD May 6, 2026
7d09005
core(watchdog): add Emitter import for event handling
FixeQD May 6, 2026
ff0cbc4
core(webview): extract renderer PID after creation
FixeQD May 6, 2026
ec0516b
docs: mark adaptive timeout task as completed
FixeQD May 6, 2026
a95d1d9
core(watchdog): implement process freezing on timeout
FixeQD May 6, 2026
ab04a6f
core(watchdog): Add Windows process suspend support
FixeQD May 6, 2026
1f6581b
core(webview): Use sysinfo to detect renderer PID
FixeQD May 6, 2026
975b2ed
core(webview): Terminate WebView renderer on hide
FixeQD May 6, 2026
2901d43
docs(todo): Mark Rust webview cleanup TODO as done
FixeQD May 6, 2026
f9b7f44
Merge pull request #37 from FixeQD/main
FixeQD May 6, 2026
98cd6ea
core(watchdog): Record renderer memory in freeze stats
FixeQD May 6, 2026
1dbb73b
ui(inbox): Add EmailFreezeNotice component
FixeQD May 7, 2026
bdbd0ef
ui(MessageViewBody): Show freeze notice on watchdog events
FixeQD May 7, 2026
e65a441
ui(message-view): Render freeze notice as inline banner
FixeQD May 7, 2026
a04edda
core(watchdog): Add resume_email_webview command
FixeQD May 7, 2026
73d38a7
core(watchdog): Add resume cooldown handling
FixeQD May 7, 2026
603f380
config(capabilities): Add allow-email-heartbeat permission
FixeQD May 7, 2026
fbb171c
api: Move email heartbeat to HTTP endpoint
FixeQD May 7, 2026
c3a053f
ui(message-view): Use flex column layout in MessageView
FixeQD May 7, 2026
6f4a32e
core(protocol): Remove CSP stripping hack and meta tag
FixeQD May 7, 2026
70ddeda
api(email-view): Prepare Email HTML and reload webview
FixeQD May 8, 2026
991788c
core(permissions): cleanup that mess
FixeQD May 8, 2026
27e4ba4
core(protocol): route email link clicks to app
FixeQD May 8, 2026
7b8b7d1
core: move external link handling to native dialog and remove old
FixeQD May 9, 2026
a2d2247
config: add Cross.toml for Windows GNU target configuration
FixeQD May 10, 2026
7744872
core(webview): refactor email webview creation and bounds logic(windows)
FixeQD May 11, 2026
30e1163
core(webview): fix window lookup method
FixeQD May 11, 2026
48421e3
core(watchdog): fix thread handle creation on Windows
FixeQD May 12, 2026
2062bc2
core(calendar): fix Windows calendar event creation and listing
FixeQD May 12, 2026
c25a3ac
core(calendar): Move Windows WinRT calls to spawn_blocking
FixeQD May 12, 2026
a3cdc6d
core(calendar): Remove stray trailing newline
FixeQD May 12, 2026
bdd2575
core(webview): Use http postail.localhost for windows's webview
FixeQD May 12, 2026
7e5f360
config(cross): Remove Cross.toml
FixeQD May 12, 2026
a7db46a
config(cargo): Set MinGW linker for Windows GNU target
FixeQD May 14, 2026
0c8b206
core(webview): implement Windows COM support and state management
FixeQD May 17, 2026
7d8d0cd
core(webview): Update Windows WebView2 bindings
FixeQD May 24, 2026
f707f6c
core(webview): Use Result for HRESULT and mark Navigate unsafe
FixeQD May 24, 2026
1c4aea1
config(gitignore): Ignore graphify-out directory
FixeQD May 26, 2026
b827637
fix(windows > webview): add pending_bounds to WinViewInner struct
FixeQD Jun 2, 2026
d983042
fix(webview): add Windows WebView2 resource handler
FixeQD Jun 3, 2026
a898be2
chore: release profile to workspace Cargo.toml
FixeQD Jun 3, 2026
a906b5d
refactor(email_webview): Split email webview into platform modules
FixeQD Jun 10, 2026
cdc9544
feat(email-network): create email_network crate
FixeQD Jun 14, 2026
7e5fa7d
feat(email-webview): create email_webview crate
FixeQD Jun 14, 2026
1f4c927
refactor: integrate new crates into the main app
FixeQD Jun 14, 2026
6dbff44
fix: update Windows features and remove unused import
FixeQD Jun 14, 2026
4aadec7
refactor(tpm): consolidate cfg guards and fallback stubs
FixeQD Jun 14, 2026
a15cd4a
chore: cleanup imports and fix formatting
FixeQD Jun 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@ target
**/gen/schemas

TODO_plan.md

graphify-out/
96 changes: 85 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@
members = [
"src-tauri",
"crates/html_transpiler",
"crates/email_network",
"crates/email_webview",
]
resolver = "2"

default-members = ["src-tauri"]

[profile.release]
lto = "fat"
codegen-units = 1
strip = true
opt-level = "s"
panic = "abort"
42 changes: 21 additions & 21 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,25 +255,25 @@
- [ ] 26.8 - UI: Detect dates in emails and suggest "Add to Calendar"

- [ ] 27 - Isolated Webview with Watchdog
- [ ] 27.1 - Rust: Replace iframe with native Tauri Child Webview for email rendering
- [ ] 27.2 - UI: Create placeholder div in MessageViewBody for Child Webview positioning
- [ ] 27.3 - Rust: Position Child Webview as overlay aligned to the React placeholder bounds
- [ ] 27.4 - Rust: Serve email HTML to Child Webview via existing `postail://` protocol handler
- [ ] 27.5 - ACL: Create `email-webview` capability with zero permissions (deny all IPC)
- [ ] 27.6 - ACL: Whitelist only `email_heartbeat` command for the email webview window
- [ ] 27.7 - Rust: `email_heartbeat` command — accept token, rate-limit, update last-seen timestamp
- [ ] 27.8 - Rust: Inject heartbeat initialization script into Child Webview on creation
- [ ] 27.9 - JS: Heartbeat loop in injected script — invoke `email_heartbeat` every 100ms
- [ ] 27.10 - Rust: Watchdog task — spawn tokio task monitoring heartbeat timestamps per webview
- [ ] 27.11 - Rust: Extract Child Webview renderer PID after creation (platform-specific)
- [ ] 27.12 - Rust: Adaptive timeout — dynamically adjust watchdog threshold to avoid false positives
- [ ] 27.13 - Rust: Freeze process — SIGSTOP (Linux) / SuspendThread (Windows) on timeout
- [ ] 27.14 - Rust: Resume process — SIGCONT (Linux) / ResumeThread (Windows) on user request
- [ ] 27.15 - Rust: Optional per-process resource limits (memory/CPU) via /proc (Linux) / Job Objects (Windows)
- [ ] 27.16 - Rust: Emit `email_webview_frozen` event to frontend on freeze
- [ ] 27.17 - UI: `EmailFreezeNotice` component — overlay with freeze info, resume/keep-frozen buttons
- [ ] 27.18 - UI: Listen for `email_webview_frozen` in MessageView and show EmailFreezeNotice
- [ ] 27.19 - Rust: Emit `email_webview_resumed` event after successful resume
- [ ] 27.20 - UI: Handle resume event — hide notice, reset watchdog state display
- [ ] 27.21 - Rust: Cleanup — destroy Child Webview and kill process on message navigation
- [x] 27.1 - Rust: Replace iframe with native Tauri Child Webview for email rendering
- [x] 27.2 - UI: Create placeholder div in MessageViewBody for Child Webview positioning
- [x] 27.3 - Rust: Position Child Webview as overlay aligned to the React placeholder bounds
- [x] 27.4 - Rust: Serve email HTML to Child Webview via existing `postail://` protocol handler
- [x] 27.5 - ACL: Create `email-webview` capability with zero permissions (deny all IPC)
- [x] 27.6 - ACL: Whitelist only `email_heartbeat` command for the email webview window
- [x] 27.7 - Rust: `email_heartbeat` command — accept token, rate-limit, update last-seen timestamp
- [x] 27.8 - Rust: Inject heartbeat initialization script into Child Webview on creation
- [x] 27.9 - JS: Heartbeat loop in injected script — invoke `email_heartbeat` every 100ms
- [x] 27.10 - Rust: Watchdog task — spawn tokio task monitoring heartbeat timestamps per webview
- [x] 27.11 - Rust: Extract Child Webview renderer PID after creation (platform-specific)
- [x] 27.12 - Rust: Adaptive timeout — dynamically adjust watchdog threshold to avoid false positives
- [x] 27.13 - Rust: Freeze process — SIGSTOP (Linux) / SuspendThread (Windows) on timeout
- [x] 27.14 - Rust: Resume process — SIGCONT (Linux) / ResumeThread (Windows) on user request
- [x] 27.15 - Rust: Optional per-process resource limits (memory/CPU) via /proc (Linux) / Job Objects (Windows)
- [x] 27.16 - Rust: Emit `email_webview_frozen` event to frontend on freeze
- [x] 27.17 - UI: `EmailFreezeNotice` component — overlay with freeze info, resume/keep-frozen buttons
- [x] 27.18 - UI: Listen for `email_webview_frozen` in MessageView and show EmailFreezeNotice
- [x] 27.19 - Rust: Emit `email_webview_resumed` event after successful resume
- [x] 27.20 - UI: Handle resume event — hide notice, reset watchdog state display
- [x] 27.21 - Rust: Cleanup — destroy Child Webview and kill process on message navigation
- [ ] 27.22 - Integration: End-to-end test with heavy HTML email triggering freeze/resume cycle
26 changes: 26 additions & 0 deletions crates/email_network/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[package]
name = "email_network"
version = "0.1.0"
edition = "2021"
description = "Network layer for Postail"
authors = ["FixeQD"]

[dependencies]
base64 = "0.22"
futures = "0.3.31"
hex = "0.4"
indexmap = { version = "2", features = ["serde"] }
kuchikiki = "0.8.8-speedreader"
rand = { version = "0.9", features = ["small_rng"] }
reqwest = { version = "0.13", default-features = false, features = [
"json",
"form",
"http2",
"native-tls",
] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
sha2 = "0.10"
thiserror = "2"
tokio = { version = "1", features = ["full"] }
tracing = "0.1"
40 changes: 40 additions & 0 deletions crates/email_network/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use thiserror::Error;

#[derive(Debug, Error)]
pub enum NetworkError {
#[error("request failed: {0}")]
Request(#[from] reqwest::Error),

#[error("server returned {status} for {url}")]
BadStatus { status: u16, url: String },

#[error("resource at {url} exceeds size limit ({size} bytes)")]
TooLarge { url: String, size: usize },
}

impl From<NetworkError> for String {
fn from(err: NetworkError) -> Self {
err.to_string()
}
}

#[derive(Debug, Error)]
pub enum CacheError {
#[error("encryption failed: {0}")]
Encryption(String),

#[error("decryption failed: {0}")]
Decryption(String),

#[error("io error: {0}")]
Io(#[from] std::io::Error),

#[error("metadata serialization failed: {0}")]
Metadata(String),
}

impl From<CacheError> for String {
fn from(err: CacheError) -> Self {
err.to_string()
}
}
2 changes: 2 additions & 0 deletions crates/email_network/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod error;
pub mod network;
Loading
Loading