Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
f9ce0b0
add: e2ee base
MuNeNICK Jan 7, 2026
2b1701b
add: key management
MuNeNICK Jan 7, 2026
1ee1dd4
add: support e2ee
MuNeNICK Jan 7, 2026
e6da74e
add: support yjs
MuNeNICK Jan 7, 2026
b31813b
add: support storage
MuNeNICK Jan 7, 2026
faed1d1
add: migrate api
MuNeNICK Jan 8, 2026
6fc755e
refactor: monaco to codemirror
MuNeNICK Jan 8, 2026
75cf99c
add: generate openapi client
MuNeNICK Jan 8, 2026
882daf3
add: key management
MuNeNICK Jan 9, 2026
cc43777
add: key management
MuNeNICK Jan 9, 2026
2738fb3
add: update yjs
MuNeNICK Jan 9, 2026
645299d
fix: errors
MuNeNICK Jan 9, 2026
ab08d04
add: support yjs
MuNeNICK Jan 10, 2026
3b0b8a4
fix: minor
MuNeNICK Jan 10, 2026
05d1e4b
refactor: render moves to frontend
MuNeNICK Jan 11, 2026
5277673
fix: tile
MuNeNICK Jan 11, 2026
8d100ef
refactor: search
MuNeNICK Jan 12, 2026
f40f022
refactor: tags
MuNeNICK Jan 12, 2026
57fb014
refactor: file attachment
MuNeNICK Jan 13, 2026
aeca760
fix: minor
MuNeNICK Jan 14, 2026
0dac61a
add: error log
MuNeNICK Jan 14, 2026
eef6c9f
fix: minor
MuNeNICK Jan 14, 2026
994742b
refactor: git
MuNeNICK Jan 14, 2026
d3144c7
fix: workspace
MuNeNICK Jan 14, 2026
009cd0f
fix: git import
MuNeNICK Jan 15, 2026
7c94265
refactor: plugin
MuNeNICK Jan 15, 2026
2002191
fix: plugin
MuNeNICK Jan 15, 2026
511a0c6
delete: legacy code
MuNeNICK Jan 16, 2026
dbd8641
refactor: rename function
MuNeNICK Jan 16, 2026
d613d49
refactor: app
MuNeNICK Jan 16, 2026
d93a93a
fix: minor
MuNeNICK Jan 16, 2026
b2ef972
fix: css
MuNeNICK Jan 16, 2026
55ad1b8
update: restore route
MuNeNICK Jan 16, 2026
a87b715
fix: shares
MuNeNICK Jan 16, 2026
a85353d
fix: public
MuNeNICK Jan 16, 2026
272c94f
feat: index
MuNeNICK Jan 16, 2026
effd33f
fix: minor
MuNeNICK Jan 16, 2026
fa57b88
refactor: export
MuNeNICK Jan 17, 2026
6f18fc2
fix: change packages
MuNeNICK Jan 17, 2026
7d5ba23
fix: key manager
MuNeNICK Jan 17, 2026
88be278
refactor: key manager
MuNeNICK Jan 17, 2026
de12ffb
refactor: app
MuNeNICK Jan 17, 2026
2c3f27b
fix: minor
MuNeNICK Jan 17, 2026
025492f
fix: bundle
MuNeNICK Jan 17, 2026
be5c3c4
fix: shares
MuNeNICK Jan 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
167 changes: 127 additions & 40 deletions api/Cargo.lock

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

3 changes: 0 additions & 3 deletions api/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ RUN apt-get update \
ca-certificates \
wget \
gosu \
pandoc \
wkhtmltopdf \
fonts-noto-cjk \
&& rm -rf /var/lib/apt/lists/*

ENV RUST_LOG=api=info,axum=info,tower_http=info \
Expand Down
1 change: 1 addition & 0 deletions api/crates/application/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ tracing = "0.1"
urlencoding = "2"
uuid = { version = "1", features = ["v4", "serde"] }
yrs = { version = "0.24", features = ["sync"] }
chacha20poly1305 = "0.10"
zip = { version = "0.6" }

[dev-dependencies]
Expand Down
35 changes: 35 additions & 0 deletions api/crates/application/src/core/ports/storage/storage_port.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,41 @@ pub trait StorageResolverPort: Send + Sync {
original_filename: Option<&str>,
bytes: &[u8],
) -> PortResult<StoredAttachment>;

// --- Public file storage (for E2EE decrypted files) ---

/// Store a public (decrypted) file for a published document
/// Returns the storage path: public/{workspace_id}/{document_id}/{file_id}
async fn store_public_file(
&self,
workspace_id: Uuid,
document_id: Uuid,
file_id: Uuid,
bytes: &[u8],
) -> PortResult<String>;

/// Read a public file
async fn read_public_file(
&self,
workspace_id: Uuid,
document_id: Uuid,
file_id: Uuid,
) -> PortResult<Vec<u8>>;

/// Delete a public file
async fn delete_public_file(
&self,
workspace_id: Uuid,
document_id: Uuid,
file_id: Uuid,
) -> PortResult<()>;

/// Delete all public files for a document
async fn delete_public_files_for_document(
&self,
workspace_id: Uuid,
document_id: Uuid,
) -> PortResult<()>;
}

#[async_trait]
Expand Down
1 change: 0 additions & 1 deletion api/crates/application/src/core/services/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,5 @@ pub mod markdown;
pub mod markdown_render;
pub mod metrics;
pub mod storage;
pub mod tagging;
pub mod utils;
pub mod worker;
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,29 @@ impl StorageIngestService {
}
Err(err) => return Err(err.into()),
};

// E2EE: Validate RME1 format
if bytes.len() < 4 || &bytes[0..4] != RME1_MAGIC {
warn!(
file_id = %file_id,
doc_id = %doc_id,
repo_path = repo_path,
"storage_ingest_attachment_invalid_rme1_format"
);
return Ok(());
}

let size = bytes.len() as i64;
let hash = sha256_hex(&bytes);
let encrypted_hash = sha256_hex(&bytes);
self.files_repo
.update_hash_and_size(file_id, size, &hash)
.update_size_and_hash(file_id, size, &encrypted_hash)
.await?;
let mut payload_obj = serde_json::Map::new();
payload_obj.insert("repo_path".into(), json!(repo_path));
payload_obj.insert("storage_path".into(), json!(rel_path));
payload_obj.insert("backend".into(), json!(event.backend.as_str()));
payload_obj.insert("size".into(), json!(size));
payload_obj.insert("content_hash".into(), json!(hash));
payload_obj.insert("encrypted_hash".into(), json!(encrypted_hash));
if let Some(prev) = previous_repo_path {
payload_obj.insert("previous_path".into(), json!(prev));
}
Expand Down
Loading