Add ticketed events, Jitsi meeting integration, social features, and calendar system
- Ticketed events: full CRUD, ticket tiers (free/paid/donation), Stripe checkout, QR-based check-in scanner, public event pages, ticket confirmation emails - Event formats: IN_PERSON/ONLINE/HYBRID with auto Jitsi meeting room lifecycle, ticket-gated meeting access, moderator JWT tokens, feature-flag guarded - Social engagement: challenges with scoring/leaderboards, referral tracking, volunteer spotlight, impact stories, campaign celebrations, wall of fame - Social calendar: personal calendar layers, shared calendar items with recurrence, scheduling polls, mobile day view - MCP server: events tool pack with full admin CRUD + meeting token generation - Unified calendar: eventFormat-aware tags, online event indicators - Updated docs site, pangolin configs, and various admin UI improvements Bunker Admin
This commit is contained in:
@@ -7,10 +7,10 @@
|
||||
"stars_count": 0,
|
||||
"forks_count": 0,
|
||||
"open_issues_count": 23,
|
||||
"updated_at": "2026-02-21T11:52:28-07:00",
|
||||
"updated_at": "2026-03-03T14:22:46-07:00",
|
||||
"created_at": "2025-05-28T14:54:59-06:00",
|
||||
"clone_url": "https://gitea.bnkops.com/admin/changemaker.lite.git",
|
||||
"ssh_url": "git@gitea.bnkops.com:admin/changemaker.lite.git",
|
||||
"default_branch": "main",
|
||||
"last_build_update": "2026-02-21T11:52:28-07:00"
|
||||
"last_build_update": "2026-03-03T14:22:46-07:00"
|
||||
}
|
||||
@@ -4,13 +4,13 @@
|
||||
"description": "Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.",
|
||||
"html_url": "https://github.com/anthropics/claude-code",
|
||||
"language": "Shell",
|
||||
"stars_count": 70476,
|
||||
"forks_count": 5568,
|
||||
"open_issues_count": 6924,
|
||||
"updated_at": "2026-02-26T14:25:29Z",
|
||||
"stars_count": 73218,
|
||||
"forks_count": 5806,
|
||||
"open_issues_count": 5500,
|
||||
"updated_at": "2026-03-03T21:40:58Z",
|
||||
"created_at": "2025-02-22T17:41:21Z",
|
||||
"clone_url": "https://github.com/anthropics/claude-code.git",
|
||||
"ssh_url": "git@github.com:anthropics/claude-code.git",
|
||||
"default_branch": "main",
|
||||
"last_build_update": "2026-02-26T12:05:37Z"
|
||||
"last_build_update": "2026-03-02T16:38:30Z"
|
||||
}
|
||||
@@ -4,13 +4,13 @@
|
||||
"description": "VS Code in the browser",
|
||||
"html_url": "https://github.com/coder/code-server",
|
||||
"language": "TypeScript",
|
||||
"stars_count": 76383,
|
||||
"forks_count": 6527,
|
||||
"open_issues_count": 184,
|
||||
"updated_at": "2026-02-26T13:37:54Z",
|
||||
"stars_count": 76454,
|
||||
"forks_count": 6532,
|
||||
"open_issues_count": 174,
|
||||
"updated_at": "2026-03-03T21:35:43Z",
|
||||
"created_at": "2019-02-27T16:50:41Z",
|
||||
"clone_url": "https://github.com/coder/code-server.git",
|
||||
"ssh_url": "git@github.com:coder/code-server.git",
|
||||
"default_branch": "main",
|
||||
"last_build_update": "2026-02-25T22:36:16Z"
|
||||
"last_build_update": "2026-03-03T21:35:38Z"
|
||||
}
|
||||
@@ -4,13 +4,13 @@
|
||||
"description": "A highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations.",
|
||||
"html_url": "https://github.com/gethomepage/homepage",
|
||||
"language": "JavaScript",
|
||||
"stars_count": 28611,
|
||||
"forks_count": 1795,
|
||||
"open_issues_count": 1,
|
||||
"updated_at": "2026-02-26T12:19:48Z",
|
||||
"stars_count": 28705,
|
||||
"forks_count": 1808,
|
||||
"open_issues_count": 6,
|
||||
"updated_at": "2026-03-03T21:17:50Z",
|
||||
"created_at": "2022-08-24T07:29:42Z",
|
||||
"clone_url": "https://github.com/gethomepage/homepage.git",
|
||||
"ssh_url": "git@github.com:gethomepage/homepage.git",
|
||||
"default_branch": "dev",
|
||||
"last_build_update": "2026-02-26T12:25:33Z"
|
||||
"last_build_update": "2026-03-03T12:22:06Z"
|
||||
}
|
||||
@@ -4,13 +4,13 @@
|
||||
"description": "Git with a cup of tea! Painless self-hosted all-in-one software development service, including Git hosting, code review, team collaboration, package registry and CI/CD",
|
||||
"html_url": "https://github.com/go-gitea/gitea",
|
||||
"language": "Go",
|
||||
"stars_count": 53910,
|
||||
"forks_count": 6399,
|
||||
"open_issues_count": 2843,
|
||||
"updated_at": "2026-02-26T13:59:20Z",
|
||||
"stars_count": 54043,
|
||||
"forks_count": 6420,
|
||||
"open_issues_count": 2841,
|
||||
"updated_at": "2026-03-03T21:25:00Z",
|
||||
"created_at": "2016-11-01T02:13:26Z",
|
||||
"clone_url": "https://github.com/go-gitea/gitea.git",
|
||||
"ssh_url": "git@github.com:go-gitea/gitea.git",
|
||||
"default_branch": "main",
|
||||
"last_build_update": "2026-02-26T11:57:03Z"
|
||||
"last_build_update": "2026-03-03T19:24:00Z"
|
||||
}
|
||||
@@ -4,13 +4,13 @@
|
||||
"description": "High performance, self-hosted, newsletter and mailing list manager with a modern dashboard. Single binary app.",
|
||||
"html_url": "https://github.com/knadh/listmonk",
|
||||
"language": "Go",
|
||||
"stars_count": 19131,
|
||||
"forks_count": 1936,
|
||||
"open_issues_count": 113,
|
||||
"updated_at": "2026-02-26T12:29:54Z",
|
||||
"stars_count": 19177,
|
||||
"forks_count": 1945,
|
||||
"open_issues_count": 115,
|
||||
"updated_at": "2026-03-03T21:29:08Z",
|
||||
"created_at": "2019-06-26T05:08:39Z",
|
||||
"clone_url": "https://github.com/knadh/listmonk.git",
|
||||
"ssh_url": "git@github.com:knadh/listmonk.git",
|
||||
"default_branch": "master",
|
||||
"last_build_update": "2026-02-26T13:26:07Z"
|
||||
"last_build_update": "2026-03-03T03:44:33Z"
|
||||
}
|
||||
@@ -4,13 +4,13 @@
|
||||
"description": "Create & scan cute qr codes easily \ud83d\udc7e",
|
||||
"html_url": "https://github.com/lyqht/mini-qr",
|
||||
"language": "Vue",
|
||||
"stars_count": 1878,
|
||||
"stars_count": 1883,
|
||||
"forks_count": 240,
|
||||
"open_issues_count": 24,
|
||||
"updated_at": "2026-02-26T06:04:32Z",
|
||||
"open_issues_count": 21,
|
||||
"updated_at": "2026-03-03T15:21:16Z",
|
||||
"created_at": "2023-04-21T14:20:14Z",
|
||||
"clone_url": "https://github.com/lyqht/mini-qr.git",
|
||||
"ssh_url": "git@github.com:lyqht/mini-qr.git",
|
||||
"default_branch": "main",
|
||||
"last_build_update": "2025-10-31T15:20:31Z"
|
||||
"last_build_update": "2026-03-02T11:52:10Z"
|
||||
}
|
||||
@@ -4,13 +4,13 @@
|
||||
"description": "Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.",
|
||||
"html_url": "https://github.com/n8n-io/n8n",
|
||||
"language": "TypeScript",
|
||||
"stars_count": 176496,
|
||||
"forks_count": 55212,
|
||||
"open_issues_count": 1408,
|
||||
"updated_at": "2026-02-26T14:25:19Z",
|
||||
"stars_count": 177388,
|
||||
"forks_count": 55378,
|
||||
"open_issues_count": 1397,
|
||||
"updated_at": "2026-03-03T21:42:29Z",
|
||||
"created_at": "2019-06-22T09:24:21Z",
|
||||
"clone_url": "https://github.com/n8n-io/n8n.git",
|
||||
"ssh_url": "git@github.com:n8n-io/n8n.git",
|
||||
"default_branch": "master",
|
||||
"last_build_update": "2026-02-26T14:25:24Z"
|
||||
"last_build_update": "2026-03-03T21:30:53Z"
|
||||
}
|
||||
@@ -4,13 +4,13 @@
|
||||
"description": "\ud83d\udd25 \ud83d\udd25 \ud83d\udd25 A Free & Self-hostable Airtable Alternative",
|
||||
"html_url": "https://github.com/nocodb/nocodb",
|
||||
"language": "TypeScript",
|
||||
"stars_count": 62217,
|
||||
"forks_count": 4647,
|
||||
"open_issues_count": 602,
|
||||
"updated_at": "2026-02-25T22:03:40Z",
|
||||
"stars_count": 62290,
|
||||
"forks_count": 4650,
|
||||
"open_issues_count": 621,
|
||||
"updated_at": "2026-03-03T21:35:23Z",
|
||||
"created_at": "2017-10-29T18:51:48Z",
|
||||
"clone_url": "https://github.com/nocodb/nocodb.git",
|
||||
"ssh_url": "git@github.com:nocodb/nocodb.git",
|
||||
"default_branch": "develop",
|
||||
"last_build_update": "2026-02-25T19:01:33Z"
|
||||
"last_build_update": "2026-03-03T15:07:07Z"
|
||||
}
|
||||
@@ -4,13 +4,13 @@
|
||||
"description": "Get up and running with Kimi-K2.5, GLM-5, MiniMax, DeepSeek, gpt-oss, Qwen, Gemma and other models.",
|
||||
"html_url": "https://github.com/ollama/ollama",
|
||||
"language": "Go",
|
||||
"stars_count": 163469,
|
||||
"forks_count": 14678,
|
||||
"open_issues_count": 2486,
|
||||
"updated_at": "2026-02-26T14:21:37Z",
|
||||
"stars_count": 163957,
|
||||
"forks_count": 14745,
|
||||
"open_issues_count": 2551,
|
||||
"updated_at": "2026-03-03T21:37:48Z",
|
||||
"created_at": "2023-06-26T19:39:32Z",
|
||||
"clone_url": "https://github.com/ollama/ollama.git",
|
||||
"ssh_url": "git@github.com:ollama/ollama.git",
|
||||
"default_branch": "main",
|
||||
"last_build_update": "2026-02-26T03:28:54Z"
|
||||
"last_build_update": "2026-03-03T21:23:42Z"
|
||||
}
|
||||
@@ -4,13 +4,13 @@
|
||||
"description": "Documentation that simply works",
|
||||
"html_url": "https://github.com/squidfunk/mkdocs-material",
|
||||
"language": "Python",
|
||||
"stars_count": 26122,
|
||||
"forks_count": 4047,
|
||||
"stars_count": 26161,
|
||||
"forks_count": 4048,
|
||||
"open_issues_count": 2,
|
||||
"updated_at": "2026-02-26T12:52:29Z",
|
||||
"updated_at": "2026-03-03T19:59:27Z",
|
||||
"created_at": "2016-01-28T22:09:23Z",
|
||||
"clone_url": "https://github.com/squidfunk/mkdocs-material.git",
|
||||
"ssh_url": "git@github.com:squidfunk/mkdocs-material.git",
|
||||
"default_branch": "master",
|
||||
"last_build_update": "2026-02-24T12:06:19Z"
|
||||
"last_build_update": "2026-03-03T19:59:22Z"
|
||||
}
|
||||
167
mkdocs/docs/docs/admin/services/crowdsec.md
Normal file
167
mkdocs/docs/docs/admin/services/crowdsec.md
Normal file
@@ -0,0 +1,167 @@
|
||||
---
|
||||
title: CrowdSec & Security
|
||||
description: CrowdSec Manager web UI, Tinyauth forward-auth, CrowdSec tuning, and Cloudflare Turnstile captcha on the Pangolin server.
|
||||
icon: material/shield-lock
|
||||
---
|
||||
|
||||
# CrowdSec Manager & Security Configuration
|
||||
|
||||
This page covers the CrowdSec Manager web UI on the Pangolin server, protected behind Tinyauth authentication, along with tuning of CrowdSec security rules and enabling Cloudflare Turnstile captcha for the CrowdSec bouncer.
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
User -->|HTTPS| Traefik
|
||||
Traefik -->|forwardAuth| Tinyauth
|
||||
Tinyauth -->|authenticated| Traefik
|
||||
Traefik -->|proxy| CrowdSec-Manager
|
||||
CrowdSec-Manager -->|API| CrowdSec
|
||||
Traefik -->|bouncer plugin| CrowdSec
|
||||
CrowdSec -->|captcha decision| Turnstile[Cloudflare Turnstile]
|
||||
```
|
||||
|
||||
All services run on the same Docker Compose stack and share the `pangolin` network. Traefik reaches them through Gerbil's network namespace.
|
||||
|
||||
---
|
||||
|
||||
## Components Added
|
||||
|
||||
### CrowdSec Manager
|
||||
|
||||
**Image:** `hhftechnology/crowdsec-manager:1.1.0`
|
||||
|
||||
A web UI for managing CrowdSec operations — viewing alerts, decisions, managing bouncers, and configuring scenarios. It has read-only access to Traefik and CrowdSec configs and read-write access to its own data and backups.
|
||||
|
||||
**Accessible at:** `https://crowdsec.bnkserve.org`
|
||||
|
||||
### Tinyauth
|
||||
|
||||
**Image:** `ghcr.io/steveiliop56/tinyauth:v4`
|
||||
|
||||
A lightweight forward-auth middleware that protects the CrowdSec Manager dashboard with a login screen. Traefik's `forwardAuth` middleware checks every request to the manager against Tinyauth before allowing access.
|
||||
|
||||
**Login page at:** `https://auth.bnkserve.org`
|
||||
|
||||
User credentials are stored in a users file (`/data/users`) mounted from the host, using bcrypt-hashed passwords.
|
||||
|
||||
!!! warning "Special Characters in Passwords"
|
||||
Tinyauth v4 has a known issue where special characters (`@`, `!`, etc.) in passwords can cause login failures through the browser, even though the bcrypt hash verifies correctly via the CLI. Use alphanumeric passwords to avoid this.
|
||||
|
||||
---
|
||||
|
||||
## Traefik Routing
|
||||
|
||||
### Routers
|
||||
|
||||
| Router | Domain | Middleware | Purpose |
|
||||
|--------|--------|------------|---------|
|
||||
| `crowdsec-manager-router` | `crowdsec.bnkserve.org` | `security-headers`, `tinyauth` | Dashboard (HTTPS) |
|
||||
| `crowdsec-manager-redirect` | `crowdsec.bnkserve.org` | `redirect-to-https` | HTTP → HTTPS redirect |
|
||||
| `tinyauth-router` | `auth.bnkserve.org` | `security-headers` | Auth login page (HTTPS) |
|
||||
| `tinyauth-redirect` | `auth.bnkserve.org` | `redirect-to-https` | HTTP → HTTPS redirect |
|
||||
|
||||
!!! danger "No tinyauth middleware on the tinyauth router"
|
||||
The `tinyauth-router` must **not** have the `tinyauth` forwardAuth middleware applied — this would create an infinite redirect loop.
|
||||
|
||||
### Middleware
|
||||
|
||||
The `tinyauth` forwardAuth middleware forwards every request to `http://tinyauth:3000/api/auth/traefik`. If the user has a valid session cookie (scoped to `.bnkserve.org`), the request passes through. Otherwise, the user is redirected to the Tinyauth login page.
|
||||
|
||||
```yaml
|
||||
tinyauth:
|
||||
forwardAuth:
|
||||
address: http://tinyauth:3000/api/auth/traefik
|
||||
trustForwardHeader: true
|
||||
authResponseHeaders:
|
||||
- X-Forwarded-User
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## CrowdSec Tuning
|
||||
|
||||
### Relaxed Crawl Detection
|
||||
|
||||
The `crowdsecurity/http-crawl-non_statics` scenario was triggering on legitimate Canadian users browsing the site. The local override at `/etc/crowdsec/scenarios/http-crawl-non_statics.yaml` (replacing the hub symlink) has relaxed thresholds:
|
||||
|
||||
| Parameter | Before | After | Effect |
|
||||
|-----------|--------|-------|--------|
|
||||
| `capacity` | 40 | 80 | Twice as many distinct pages before triggering |
|
||||
| `leakspeed` | 0.5s | 0.25s | Bucket drains twice as fast |
|
||||
|
||||
**Combined effect:** 4x more lenient — a user must hit 80+ distinct non-static pages faster than 1 every 0.25 seconds to trigger a captcha.
|
||||
|
||||
### Canadian ISP Whitelist
|
||||
|
||||
A whitelist expression in `/etc/crowdsec/parsers/s02-enrich/mywhitelists.yaml` exempts traffic from major Canadian ISPs from all CrowdSec scenarios:
|
||||
|
||||
```yaml
|
||||
expression:
|
||||
- evt.Meta.ASNNumber in ['812', '852', '6327', '5645', '20365', '25668', '577']
|
||||
```
|
||||
|
||||
| AS Number | ISP |
|
||||
|-----------|-----|
|
||||
| 812 | Rogers Communications |
|
||||
| 852 | TELUS Communications |
|
||||
| 6327 | Shaw Communications |
|
||||
| 5645 | TekSavvy |
|
||||
| 20365 | Freedom Mobile |
|
||||
| 25668 | CipherKey |
|
||||
| 577 | Bell Canada |
|
||||
|
||||
!!! note "Field name"
|
||||
The GeoIP enricher populates `evt.Meta.ASNNumber` (not `ASNumber`). This can be verified by inspecting `/etc/crowdsec/parsers/s02-enrich/geoip-enrich.yaml`.
|
||||
|
||||
---
|
||||
|
||||
## Cloudflare Turnstile Captcha
|
||||
|
||||
Previously, CrowdSec captcha decisions resulted in a hard 403 block because no captcha provider was configured. Now, users with a captcha decision see a Cloudflare Turnstile challenge page and can proceed after solving it.
|
||||
|
||||
Configuration added to the CrowdSec bouncer plugin in `dynamic_config.yml`:
|
||||
|
||||
```yaml
|
||||
captchaProvider: turnstile
|
||||
captchaSiteKey: <site-key>
|
||||
captchaSecretKey: <secret-key>
|
||||
captchaHTMLFilePath: /etc/traefik/captcha.html
|
||||
```
|
||||
|
||||
!!! warning "Captcha HTML template path"
|
||||
The `captcha.html` template is copied from the plugin source to `/etc/traefik/captcha.html` (the mounted config volume). Do **not** reference the `/plugins-storage/` path directly — the hash in that path changes on every Traefik restart.
|
||||
|
||||
---
|
||||
|
||||
## DNS Records
|
||||
|
||||
Two A records pointing to `72.11.155.21`:
|
||||
|
||||
| Record | Purpose |
|
||||
|--------|---------|
|
||||
| `crowdsec.bnkserve.org` | CrowdSec Manager dashboard |
|
||||
| `auth.bnkserve.org` | Tinyauth login page |
|
||||
|
||||
---
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
# Check containers are running and healthy
|
||||
docker ps --filter name=crowdsec-manager --filter name=tinyauth
|
||||
|
||||
# Check both are on the pangolin network
|
||||
docker network inspect pangolin --format '{{range .Containers}}{{.Name}} {{end}}'
|
||||
|
||||
# Verify no Canadian ISPs in active decisions
|
||||
docker exec crowdsec cscli decisions list | grep "CA"
|
||||
|
||||
# Check CrowdSec whitelist is loaded
|
||||
docker exec crowdsec cscli parsers inspect mywhitelists
|
||||
|
||||
# Check Traefik logs for captcha errors
|
||||
docker logs traefik 2>&1 | grep -i captcha
|
||||
```
|
||||
@@ -13,6 +13,7 @@ Manage the platform's infrastructure services, monitoring stack, and third-party
|
||||
## In This Section
|
||||
|
||||
- **[Tunnel](tunnel.md)** — Pangolin tunnel management for public access without port forwarding
|
||||
- **[CrowdSec & Security](crowdsec.md)** — CrowdSec Manager, Tinyauth forward-auth, ISP whitelisting, and Turnstile captcha on the Pangolin server
|
||||
- **[Monitoring](monitoring.md)** — Prometheus metrics, Grafana dashboards, and Alertmanager
|
||||
- **[Integrations](integrations.md)** — Chat, video conferencing, password manager, whiteboard, Git hosting, automation, and QR codes
|
||||
- **[User Provisioning](user-provisioning.md)** — automatic account sync across integrated services
|
||||
|
||||
@@ -39,6 +39,17 @@ The Newt container runs alongside nginx and tunnels traffic to your services:
|
||||
|
||||
---
|
||||
|
||||
## Security
|
||||
|
||||
The Pangolin server runs CrowdSec for intrusion detection with a web management UI protected by Tinyauth forward-auth. See **[CrowdSec & Security](crowdsec.md)** for details on:
|
||||
|
||||
- CrowdSec Manager dashboard (`crowdsec.bnkserve.org`)
|
||||
- Tinyauth authentication (`auth.bnkserve.org`)
|
||||
- Canadian ISP whitelisting and crawl detection tuning
|
||||
- Cloudflare Turnstile captcha integration
|
||||
|
||||
---
|
||||
|
||||
## Admin Routes
|
||||
|
||||
- `/app/pangolin` — tunnel status, setup wizard, and resource management
|
||||
|
||||
@@ -2815,6 +2815,10 @@
|
||||
<span class="dep-icon">📱</span>
|
||||
<span><strong>An Android phone</strong> — required for SMS campaigns (uses Termux as a bridge to send texts)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span class="dep-icon">💳</span>
|
||||
<span><strong>A Stripe account</strong> — for credit card payments and donations; e-Transfer also integrated for direct bank payments</span>
|
||||
</li>
|
||||
</ul>
|
||||
<p class="free-modal-footer">
|
||||
None of these are unique to Changemaker Lite — any self-hosted platform needs them. The software itself will always be free.
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
</script>
|
||||
<style>
|
||||
.md-banner {
|
||||
background: linear-gradient(135deg, #005a9c 0%, #007acc 100%) !important;
|
||||
background: linear-gradient(158deg, rgb(0,31,156) 0%, rgb(0,68,204) 100%) !important;
|
||||
color: #ffffff !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
@@ -101,7 +101,7 @@
|
||||
display: none !important;
|
||||
}
|
||||
.cm-header-nav {
|
||||
background: linear-gradient(135deg, #005a9c 0%, #007acc 100%);
|
||||
background: linear-gradient(158deg, rgb(0,31,156) 0%, rgb(0,68,204) 100%);
|
||||
height: 56px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
Reference in New Issue
Block a user