Milestone 2.

This commit is contained in:
2025-08-18 21:40:41 +02:00
parent 1646d7b827
commit e283e9f696
13 changed files with 615 additions and 107 deletions

32
app/routes/attachments.py Normal file
View File

@@ -0,0 +1,32 @@
from __future__ import annotations
import os
from pathlib import Path
from flask import Blueprint, abort, current_app, send_from_directory
from app.services.vault import Vault
bp = Blueprint("attachments", __name__, url_prefix="/attachments")
@bp.get("/<path:subpath>")
def serve_attachment(subpath: str):
# Resolve within the vault attachments directory
vault_path = current_app.config.get("KB_VAULT_PATH")
if not vault_path:
abort(404)
v = Vault(vault_path)
attachments_dir = Path(v.paths.attachments).resolve()
requested = (attachments_dir / subpath).resolve()
# Prevent path traversal
try:
requested.relative_to(attachments_dir)
except Exception:
abort(403)
if not requested.exists() or not requested.is_file():
abort(404)
return send_from_directory(attachments_dir, os.path.relpath(str(requested), str(attachments_dir)))