added path security, documented api endpoints

This commit is contained in:
Gamosoft 2025-11-26 12:01:50 +01:00
parent 54df891e94
commit 8d78c278ee
3 changed files with 164 additions and 2 deletions

View File

@ -783,7 +783,8 @@ async def get_notes_by_tag_endpoint(tag_name: str):
# --- Template Endpoints --- # --- Template Endpoints ---
@api_router.get("/templates") @api_router.get("/templates")
async def list_templates(): @limiter.limit("120/minute")
async def list_templates(request: Request):
""" """
List all available templates from _templates folder. List all available templates from _templates folder.
@ -798,7 +799,8 @@ async def list_templates():
@api_router.get("/templates/{template_name}") @api_router.get("/templates/{template_name}")
async def get_template(template_name: str): @limiter.limit("120/minute")
async def get_template(request: Request, template_name: str):
""" """
Get content of a specific template. Get content of a specific template.

View File

@ -668,9 +668,19 @@ def get_templates(notes_dir: str) -> List[Dict]:
if not templates_path.exists(): if not templates_path.exists():
return templates return templates
# Security check: ensure _templates folder is within notes directory
if not validate_path_security(notes_dir, templates_path):
print(f"Security: Templates directory is outside notes directory: {templates_path}")
return templates
try: try:
for template_file in templates_path.glob("*.md"): for template_file in templates_path.glob("*.md"):
try: try:
# Security check: ensure each template is within notes directory
if not validate_path_security(notes_dir, template_file):
print(f"Security: Skipping template outside notes directory: {template_file}")
continue
stat = template_file.stat() stat = template_file.stat()
templates.append({ templates.append({
"name": template_file.stem, "name": template_file.stem,

View File

@ -295,6 +295,120 @@ Self-documenting endpoint listing all available API routes.
--- ---
## 🏷️ Tags
### List All Tags
`GET /api/tags`
Returns all tags found in notes with their usage counts.
**Response:**
```json
{
"tags": {
"python": 5,
"tutorial": 3,
"backend": 2
}
}
```
### Get Notes by Tag
`GET /api/tags/{tag_name}`
Returns all notes that have a specific tag.
**Response:**
```json
{
"tag": "python",
"notes": [
{
"path": "tutorials/python-basics.md",
"name": "python-basics",
"folder": "tutorials",
"tags": ["python", "tutorial"]
}
]
}
```
---
## 📄 Templates
### List Templates
`GET /api/templates`
Returns all available note templates from the `_templates` folder.
**Response:**
```json
{
"templates": [
{
"name": "meeting-notes",
"path": "_templates/meeting-notes.md",
"modified": "2025-11-26T10:30:00"
},
{
"name": "daily-journal",
"path": "_templates/daily-journal.md",
"modified": "2025-11-26T10:25:00"
}
]
}
```
### Get Template Content
`GET /api/templates/{template_name}`
Returns the content of a specific template.
**Parameters:**
- `template_name` - Template name (without .md extension)
**Response:**
```json
{
"name": "meeting-notes",
"content": "# Meeting Notes\n\nDate: {{date}}\n..."
}
```
### Create Note from Template
`POST /api/templates/create-note`
Creates a new note from a template with placeholder replacement.
**Request Body:**
```json
{
"templateName": "meeting-notes",
"notePath": "meetings/weekly-sync.md"
}
```
**Placeholders:**
- `{{date}}` - Current date (YYYY-MM-DD)
- `{{time}}` - Current time (HH:MM:SS)
- `{{datetime}}` - Current datetime
- `{{timestamp}}` - Unix timestamp
- `{{title}}` - Note name without extension
- `{{folder}}` - Parent folder name
**Response:**
```json
{
"success": true,
"path": "meetings/weekly-sync.md",
"message": "Note created from template successfully",
"content": "# Meeting Notes\n\nDate: 2025-11-26\n..."
}
```
---
## 📝 Response Format ## 📝 Response Format
All endpoints return JSON responses: All endpoints return JSON responses:
@ -315,5 +429,41 @@ All endpoints return JSON responses:
``` ```
--- ---
---
## 🔒 Security & Rate Limiting
### Authentication
When authentication is enabled (via `AUTHENTICATION_ENABLED` environment variable or `config.yaml`), all API endpoints require a valid session cookie obtained through the `/login` endpoint.
### Rate Limiting
When `DEMO_MODE` is enabled, the following rate limits are enforced:
**Read Operations:**
- `GET /api/notes` - 120/minute
- `GET /api/templates` - 120/minute
- `GET /api/templates/{template_name}` - 120/minute
- `GET /api/tags` - 120/minute
- `GET /api/tags/{tag}` - 120/minute
**Write Operations:**
- `POST /api/notes` - 60/minute
- `DELETE /api/notes/*` - 60/minute
- `POST /api/folders` - 60/minute
- `DELETE /api/folders/*` - 60/minute
- `POST /api/images/upload` - 30/minute
- `DELETE /api/images/*` - 60/minute
- `POST /api/templates/create-note` - 60/minute
- `POST /api/plugins/*/toggle` - 60/minute
### Path Security
All file operations validate that paths are within the configured `notes_dir` to prevent directory traversal attacks. This includes:
- Note operations
- Folder operations
- Image operations
- Template operations
---
💡 **Tip:** Use the `/api` endpoint to get a live, self-documented list of all available endpoints! 💡 **Tip:** Use the `/api` endpoint to get a live, self-documented list of all available endpoints!