Remove excessive documentation files
This commit is contained in:
73
SCHEMA.md
73
SCHEMA.md
@@ -1,73 +0,0 @@
|
||||
# Plugin Schema
|
||||
|
||||
All plugin definitions must be valid JSON files following this schema.
|
||||
|
||||
## Required Fields
|
||||
|
||||
| Field | Type | Description | Example |
|
||||
|-------|------|-------------|---------|
|
||||
| `id` | string | Unique identifier (must match filename) | `"awesome-plugin"` |
|
||||
| `name` | string | Display name | `"Awesome Plugin"` |
|
||||
| `version` | string | Semantic version | `"1.0.0"` |
|
||||
| `description` | string | What the plugin does | `"Does awesome things"` |
|
||||
| `author` | string | Gitea username of creator | `"litruv"` |
|
||||
| `repository` | string | Git repository URL | `"http://synbox.ruv.wtf:8418/litruv/awesome-plugin.git"` |
|
||||
|
||||
## Optional Fields
|
||||
|
||||
| Field | Type | Description | Example |
|
||||
|-------|------|-------------|---------|
|
||||
| `downloadUrl` | string | Direct download URL | `"http://synbox.ruv.wtf:8418/litruv/awesome-plugin/archive/main.zip"` |
|
||||
| `homepage` | string | Plugin homepage or documentation | `"http://synbox.ruv.wtf:8418/litruv/awesome-plugin"` |
|
||||
| `tags` | array | Category tags | `["utility", "automation"]` |
|
||||
| `addedDate` | string | ISO 8601 date | `"2026-04-17T00:00:00.000Z"` |
|
||||
| `dependencies` | object | Required dependencies | `{"lodash": "^4.17.21"}` |
|
||||
|
||||
## Example
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "example-plugin",
|
||||
"name": "Example Plugin",
|
||||
"version": "1.0.0",
|
||||
"description": "An example plugin demonstrating the plugin system capabilities",
|
||||
"author": "litruv",
|
||||
"repository": "http://synbox.ruv.wtf:8418/litruv/Plugin-Example.git",
|
||||
"downloadUrl": "http://synbox.ruv.wtf:8418/litruv/Plugin-Example/archive/main.zip",
|
||||
"homepage": "http://synbox.ruv.wtf:8418/litruv/Plugin-Example",
|
||||
"tags": ["example", "demo"],
|
||||
"addedDate": "2026-04-17T00:00:00.000Z"
|
||||
}
|
||||
```
|
||||
|
||||
## Validation Rules
|
||||
|
||||
1. **Filename Match**: Plugin ID must match the filename (without .json extension)
|
||||
- ✅ `awesome-plugin.json` with `"id": "awesome-plugin"`
|
||||
- ❌ `awesome-plugin.json` with `"id": "different-name"`
|
||||
|
||||
2. **Version Format**: Must follow semantic versioning (X.Y.Z)
|
||||
- ✅ `"1.0.0"`, `"2.5.3"`, `"0.1.0"`
|
||||
- ❌ `"1.0"`, `"v1.0.0"`, `"latest"`
|
||||
|
||||
3. **Author Matching**: For new plugins, author must match PR creator
|
||||
- If PR is by user `litruv`, author field must be `"litruv"`
|
||||
|
||||
4. **Valid URLs**: Repository, downloadUrl, and homepage must be valid URLs
|
||||
- ✅ `"http://example.com/repo.git"`
|
||||
- ❌ `"not-a-url"`, `"//example.com"`
|
||||
|
||||
5. **Tags**: If present, must be an array of strings
|
||||
- ✅ `["tag1", "tag2"]`
|
||||
- ❌ `"tag1,tag2"`, `{"tag": "value"}`
|
||||
|
||||
## Submission Process
|
||||
|
||||
1. Create a JSON file in the `plugins/` directory
|
||||
2. Filename must be `{plugin-id}.json`
|
||||
3. Ensure all required fields are present
|
||||
4. Author field must match your Gitea username
|
||||
5. Create a Pull Request
|
||||
6. Automated validation will run
|
||||
7. If valid, PR auto-merges
|
||||
8. If invalid, you'll receive comments explaining what to fix
|
||||
137
SECURITY.md
137
SECURITY.md
@@ -1,137 +0,0 @@
|
||||
# Security Model
|
||||
|
||||
## Authentication vs Git Configuration
|
||||
|
||||
### How User Identity Works
|
||||
|
||||
**Question:** Can't I just set my git username to anything and bypass validation?
|
||||
|
||||
**Answer:** No. The validation uses **Gitea account authentication**, not git commit authors.
|
||||
|
||||
#### Git Commit Author (NOT used for validation)
|
||||
```bash
|
||||
# This can be set to anything locally
|
||||
git config user.name "anyone"
|
||||
git config user.email "anyone@example.com"
|
||||
git commit -m "My commit"
|
||||
```
|
||||
These values are **NOT** used for plugin ownership validation.
|
||||
|
||||
#### PR Creator (used for validation)
|
||||
When you create a Pull Request:
|
||||
1. You must be logged into your Gitea account
|
||||
2. The PR is created through Gitea's authenticated API
|
||||
3. `github.event.pull_request.user.login` = your authenticated Gitea username
|
||||
|
||||
**This is what validation checks against.**
|
||||
|
||||
### Example Attack Scenario (Prevented)
|
||||
|
||||
❌ **Attacker tries:**
|
||||
```bash
|
||||
# Configure git to impersonate someone
|
||||
git config user.name "victim"
|
||||
git config user.email "victim@example.com"
|
||||
|
||||
# Modify victim's plugin
|
||||
vim plugins/victim-plugin.json
|
||||
# Change author to "attacker"
|
||||
|
||||
git commit -m "Update plugin"
|
||||
git push
|
||||
|
||||
# Create PR (must log into Gitea as "attacker" account)
|
||||
```
|
||||
|
||||
✅ **What happens:**
|
||||
1. PR is created by authenticated Gitea user: `attacker`
|
||||
2. Validation script receives: `prAuthor = "attacker"`
|
||||
3. Validation checks original plugin from main branch: `original.author = "victim"`
|
||||
4. Check fails: `"victim" !== "attacker"`
|
||||
5. **Result:** ❌ `Cannot modify plugin owned by "victim" (you are "attacker")`
|
||||
|
||||
The git commit author is irrelevant - what matters is **who is logged into Gitea when creating the PR**.
|
||||
|
||||
## Security Measures
|
||||
|
||||
### 1. Dual Checkout
|
||||
```yaml
|
||||
- Checkout main branch → base/ (trusted validation scripts)
|
||||
- Checkout PR branch → pr/ (untrusted user submissions)
|
||||
```
|
||||
Validation script always runs from `base/`, never from PR branch.
|
||||
|
||||
### 2. Infrastructure Protection
|
||||
PRs that modify `.gitea/` directory are automatically rejected.
|
||||
|
||||
### 3. Ownership Verification
|
||||
All modifications/deletions check **original ownership from main branch**:
|
||||
```javascript
|
||||
// Check original plugin from main (base/)
|
||||
const originalPlugin = readFile('../base/plugins/example.json');
|
||||
|
||||
// User can only modify if they own the original
|
||||
if (originalPlugin.author !== prAuthor) {
|
||||
reject("Cannot modify plugin owned by someone else");
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Author Field Validation
|
||||
New plugins must have `author` field matching the PR creator's authenticated Gitea username.
|
||||
|
||||
## What About Collaboration?
|
||||
|
||||
**Q:** What if I want someone else to update my plugin?
|
||||
|
||||
**A:** They cannot submit PRs directly. Options:
|
||||
1. Transfer ownership by updating the `author` field yourself
|
||||
2. They fork your plugin repo and create their own plugin entry
|
||||
3. Add them as collaborators to your plugin repository (not the directory)
|
||||
|
||||
## Trust Model
|
||||
|
||||
### Trusted Components
|
||||
- Main branch content (validated history)
|
||||
- Gitea authentication system
|
||||
- GitHub Actions runner environment
|
||||
- Validation scripts on main branch
|
||||
|
||||
### Untrusted Components
|
||||
- PR branch content (user submissions)
|
||||
- Git commit metadata (names, emails)
|
||||
- PR descriptions and comments
|
||||
|
||||
### Validation Flow
|
||||
```
|
||||
1. User authenticates to Gitea → Trusted user identity
|
||||
2. User creates PR → github.event.pull_request.user.login
|
||||
3. Validation runs from main branch scripts → Trusted code
|
||||
4. Checks plugin ownership against main → Trusted ownership data
|
||||
5. Validates PR author matches plugin author → Secure check
|
||||
```
|
||||
|
||||
## Reporting Security Issues
|
||||
|
||||
If you find a security vulnerability in the plugin directory system:
|
||||
1. **Do NOT create a public issue or PR**
|
||||
2. Contact the repository maintainer directly
|
||||
3. Provide detailed reproduction steps
|
||||
4. Allow time for a fix before public disclosure
|
||||
|
||||
## Additional Safeguards
|
||||
|
||||
### Rate Limiting
|
||||
Gitea's built-in rate limiting prevents spam PR attacks.
|
||||
|
||||
### Branch Protection
|
||||
The `main` branch is protected:
|
||||
- Direct pushes disabled
|
||||
- All changes via PR
|
||||
- Auto-merge only after validation passes
|
||||
|
||||
### Audit Trail
|
||||
All changes are tracked in git history:
|
||||
- Who created the PR (Gitea account)
|
||||
- What changed (git diff)
|
||||
- When it was merged (git commit timestamp)
|
||||
- Why validation passed (CI logs)
|
||||
@@ -1,200 +0,0 @@
|
||||
# Plugin Validation Rules
|
||||
|
||||
All plugin submissions are automatically validated before being merged. PRs must pass all validation checks to be auto-merged.
|
||||
|
||||
## Security
|
||||
|
||||
**The validation script runs from the main branch, not from your PR branch.** This prevents malicious PRs from modifying the validation logic. PRs that attempt to modify `.gitea/` directory files will be automatically rejected.
|
||||
|
||||
## File Requirements
|
||||
|
||||
### 1. Location
|
||||
- ✅ Only modify files in `plugins/` directory
|
||||
- ❌ Cannot modify files outside `plugins/`
|
||||
- ❌ Cannot modify `.gitea/` infrastructure files
|
||||
- ⚠️ `plugins/index.json` is auto-generated - don't manually edit it
|
||||
|
||||
### 2. File Naming
|
||||
- **Filename must be prefixed with your username**
|
||||
- Format: `username-plugin-name.json`
|
||||
- Example: `litruv-example-plugin.json`
|
||||
- ❌ Invalid: `example-plugin.json` (missing username prefix)
|
||||
- ❌ Invalid: `otheruser-plugin.json` (wrong username)
|
||||
|
||||
This prevents naming conflicts and makes ownership visible.
|
||||
|
||||
### 3. File Type
|
||||
- ✅ Only `.json` files are allowed in `plugins/` directory
|
||||
- ❌ No other file types (images, scripts, etc. must be in plugin repo)
|
||||
|
||||
## Plugin JSON Schema
|
||||
|
||||
### Required Fields
|
||||
Every plugin JSON must have these fields:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "string",
|
||||
"name": "string",
|
||||
"version": "string",
|
||||
"description": "string",
|
||||
"author": "string",
|
||||
"repository": "string"
|
||||
}
|
||||
```
|
||||
|
||||
### Field Validation Rules
|
||||
|
||||
#### `id` (required)
|
||||
- Must match the filename
|
||||
- Example: `litruv-example-plugin.json` → `"id": "litruv-example-plugin"`
|
||||
- Must include username prefix matching filename
|
||||
- Lowercase, hyphens allowed, no spaces
|
||||
|
||||
#### `name` (required)
|
||||
- Display name for the plugin
|
||||
- Human-readable, any format
|
||||
|
||||
#### `version` (required)
|
||||
- Must follow semantic versioning: `x.y.z`
|
||||
- Example: `"1.0.0"`, `"2.1.3"`
|
||||
- ❌ Invalid: `"v1.0"`, `"1.0"`, `"latest"`
|
||||
|
||||
#### `description` (required)
|
||||
- Short description of what the plugin does
|
||||
- Will be shown in the plugin browser
|
||||
|
||||
#### `author` (required)
|
||||
- **MUST MATCH YOUR GITEA USERNAME**
|
||||
- This enforces ownership - you can only submit/remove plugins authored by you
|
||||
- Case-sensitive
|
||||
|
||||
#### `repository` (required)
|
||||
- Git repository URL where the plugin code lives
|
||||
- Must be a valid URL
|
||||
- Example: `"http://synbox.ruv.wtf:8418/username/Plugin-Name.git"`
|
||||
|
||||
#### `thumbnail` (optional)
|
||||
- URL to plugin thumbnail image
|
||||
- **Requirements:**
|
||||
- Format: PNG, JPG, or GIF only
|
||||
- Max dimensions: 512×512 pixels
|
||||
- Max file size: 2MB
|
||||
- Must be accessible via HTTP/HTTPS
|
||||
- Example: `"http://synbox.ruv.wtf:8418/username/Plugin-Name/raw/branch/main/thumbnail.png"`
|
||||
- Validation checks actual image format (magic bytes), dimensions, and size
|
||||
|
||||
### Optional Fields
|
||||
You can include any additional fields for metadata:
|
||||
- `homepage` - Project homepage URL
|
||||
- `downloadUrl` - Direct download link
|
||||
- `tags` - Array of tags
|
||||
- `addedDate` - ISO timestamp
|
||||
|
||||
## Ownership Rules
|
||||
|
||||
### Adding Plugins
|
||||
- The `author` field must match your Gitea username
|
||||
- This is checked automatically
|
||||
|
||||
### Modifying Plugins
|
||||
- **You can only modify plugins where the ORIGINAL author (on main branch) is you**
|
||||
- Even if you change the `author` field in your PR, validation checks against the original
|
||||
- Attempting to modify someone else's plugin will fail validation with:
|
||||
```
|
||||
❌ plugins/their-plugin.json: Cannot modify plugin owned by "them" (you are "you")
|
||||
```
|
||||
|
||||
### Removing Plugins
|
||||
- **You can only remove plugins where the ORIGINAL author (on main branch) is you**
|
||||
- The validation checks the plugin's author from the main branch, not from your PR
|
||||
- Attempting to remove someone else's plugin will fail validation with:
|
||||
```
|
||||
❌ plugins/their-plugin.json: Cannot remove plugin owned by "them" (you are "you")
|
||||
```
|
||||
|
||||
**Security Note:** All ownership checks use the plugin data from the `main` branch, not from your PR. You cannot bypass ownership by modifying the `author` field.
|
||||
|
||||
## Validation Process
|
||||
|
||||
1. **File check**: Ensures only `plugins/*.json` files are modified
|
||||
2. **Infrastructure check**: Blocks any `.gitea/` modifications
|
||||
3. **JSON parsing**: Validates JSON syntax
|
||||
4. **Schema validation**: Checks all required fields exist
|
||||
5. **Field validation**: Validates each field's format and rules
|
||||
6. **Thumbnail validation** (if provided): Downloads and validates image
|
||||
7. **Author matching**: Ensures `author` field matches PR creator
|
||||
8. **Auto-merge**: If all checks pass, PR is automatically merged
|
||||
|
||||
## Testing Locally
|
||||
|
||||
You can test your plugin JSON before submitting:
|
||||
|
||||
```bash
|
||||
cd Plugin-Directory
|
||||
node .gitea/scripts/validate-pr.js "your-username" "plugins/your-plugin.json"
|
||||
```
|
||||
|
||||
## Common Errors
|
||||
|
||||
### ❌ Author mismatch
|
||||
```
|
||||
❌ plugins/example-plugin.json: Author "someone" must match PR creator "you"
|
||||
```
|
||||
**Fix**: Change `"author": "someone"` to `"author": "you"`
|
||||
|
||||
### ❌ ID doesn't match filename
|
||||
```litruv-my-plugin.json: Plugin ID "different-name" doesn't match filename "litruv-my-plugin.json"
|
||||
```
|
||||
**Fix**: Change `"id": "different-name"` to `"id": "litruv-my-plugin"`
|
||||
|
||||
### ❌ Filename missing username prefix
|
||||
```
|
||||
❌ plugins/my-plugin.json: Filename must start with your username "litruv-" (e.g., "litruv-my-plugin.json")
|
||||
```
|
||||
**Fix**: Rename file from `my-plugin.json` to `litruv-my-plugin.json` and update the `id` field
|
||||
**Fix**: Change `"id": "different-name"` to `"id": "my-plugin"`
|
||||
|
||||
### ❌ Invalid version
|
||||
```
|
||||
❌ plugins/example-plugin.json: Invalid version format: v1.0
|
||||
```
|
||||
**Fix**: Use semantic versioning like `"version": "1.0.0"`
|
||||
|
||||
### ❌ Thumbnail too large
|
||||
```
|
||||
❌ plugins/example-plugin.json: Thumbnail validation failed: Thumbnail exceeds 2MB limit (3.45MB)
|
||||
```
|
||||
**Fix**: Compress your thumbnail to under 2MB
|
||||
|
||||
### ❌ Thumbnail dimensions too large
|
||||
```
|
||||
❌ plugins/example-plugin.json: Thumbnail validation failed: Thumbnail dimensions 1024x768 exceed 512x512
|
||||
```
|
||||
**Fix**: litruv-example-plugin",
|
||||
"name": "Example Plugin",
|
||||
"version": "1.0.0",
|
||||
"description": "An example plugin demonstrating the plugin system capabilities",
|
||||
"author": "litruv",
|
||||
"repository": "http://synbox.ruv.wtf:8418/litruv/Plugin-Example.git",
|
||||
"thumbnail": "http://synbox.ruv.wtf:8418/litruv/Plugin-Example/raw/branch/main/thumbnail.png",
|
||||
"homepage": "http://synbox.ruv.wtf:8418/litruv/Plugin-Example",
|
||||
"tags": ["example", "demo"]
|
||||
}
|
||||
```
|
||||
|
||||
Filename: `litruv-example-plugin.json"author": "litruv",
|
||||
"repository": "http://synbox.ruv.wtf:8418/litruv/Plugin-Example.git",
|
||||
"thumbnail": "http://synbox.ruv.wtf:8418/litruv/Plugin-Example/raw/branch/main/thumbnail.png",
|
||||
"homepage": "http://synbox.ruv.wtf:8418/litruv/Plugin-Example",
|
||||
"tags": ["example", "demo"]
|
||||
}
|
||||
```
|
||||
|
||||
## Security Note
|
||||
|
||||
**Never include sensitive information in plugin JSON files.** These files are public and will be served to all plugin host users. Do not include:
|
||||
- API keys or tokens
|
||||
- Passwords
|
||||
- Private URLs or endpoints
|
||||
- Personal information
|
||||
Reference in New Issue
Block a user