From 9a8305d986ed29eed3bd7c36663d162fbef4e311 Mon Sep 17 00:00:00 2001 From: Codex Agent Date: Fri, 30 Jan 2026 11:12:15 +0100 Subject: [PATCH] Add Uptime Kuma monitoring template --- .beads/last-touched | 2 +- docker-compose.dokploy.yml | 12 + docker-compose.yml | 9 + docs/archive/implementation-roadmap.md | 1 - docs/ops/deployment/join-token-analytics.md | 28 - .../public-api-incident-playbook.md | 28 +- .../uptime-kuma-import.template.json | 718 ++++++++++++++++++ 7 files changed, 767 insertions(+), 31 deletions(-) delete mode 100644 docs/ops/deployment/join-token-analytics.md create mode 100644 docs/ops/deployment/uptime-kuma-import.template.json diff --git a/.beads/last-touched b/.beads/last-touched index a5880db..6268903 100644 --- a/.beads/last-touched +++ b/.beads/last-touched @@ -1 +1 @@ -fotospiel-app-v5dd +fotospiel-app-v00l diff --git a/docker-compose.dokploy.yml b/docker-compose.dokploy.yml index 4df1ca3..32f971f 100644 --- a/docker-compose.dokploy.yml +++ b/docker-compose.dokploy.yml @@ -297,6 +297,17 @@ services: retries: 5 restart: unless-stopped + uptime-kuma: + image: louislam/uptime-kuma:1 + volumes: + - uptime-kuma-data:/app/data + ports: + - "${UPTIME_KUMA_PORT:-3001}:3001" + networks: + - default + - dokploy-network + restart: unless-stopped + volumes: app-code: app-storage: @@ -306,6 +317,7 @@ volumes: nuget-cache: mysql-data: redis-data: + uptime-kuma-data: networks: dokploy-network: diff --git a/docker-compose.yml b/docker-compose.yml index b409b2f..24dfbc2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -133,7 +133,16 @@ services: retries: 5 restart: unless-stopped + uptime-kuma: + image: louislam/uptime-kuma:1 + volumes: + - uptime-kuma-data:/app/data + ports: + - "${UPTIME_KUMA_PORT:-3001}:3001" + restart: unless-stopped + volumes: app-code: mysql-data: redis-data: + uptime-kuma-data: diff --git a/docs/archive/implementation-roadmap.md b/docs/archive/implementation-roadmap.md index 3443d66..67f4417 100644 --- a/docs/archive/implementation-roadmap.md +++ b/docs/archive/implementation-roadmap.md @@ -12,7 +12,6 @@ - `SEC-FE-01` CSP nonce utility. - Week 2 - `SEC-IO-02` refresh-token management UI. *(delivered 2025-10-23)* - - `SEC-GT-02` token analytics dashboards. - `SEC-API-02` incident response playbook. - `SEC-MS-02` streaming upload refactor. - `SEC-BILL-02` webhook signature freshness. diff --git a/docs/ops/deployment/join-token-analytics.md b/docs/ops/deployment/join-token-analytics.md deleted file mode 100644 index 58d4a11..0000000 --- a/docs/ops/deployment/join-token-analytics.md +++ /dev/null @@ -1,28 +0,0 @@ -# Join Token Analytics & Alerting (SEC-GT-02) - -## Data Sources -- Table `event_join_token_events` captures successes, failures, rate-limit hits, and uploads per join token. -- Each row records route, device id, IP, HTTP status, and context for post-incident drill downs. -- Logged automatically from `EventPublicController` for `/api/v1/events/*` and `/api/v1/gallery/*`. - -- Super Admin: Event resource → “Join Link / QR” modal now summarises total successes/failures, rate-limit hits, 24h volume, and last activity timestamp per token. -- Tenant Admin: identical modal surface so operators can monitor invite health. - -## Alert Thresholds (initial) -- **Rate limit spike**: >25 `token_rate_limited` entries for a token within 10 minutes → flag in monitoring (Grafana/Prometheus TODO). -- **Failure ratio**: failure_count / success_count > 0.5 over rolling hour triggers warning for support follow-up. -- **Inactivity**: tokens without access for >30 days should be reviewed; scheduled report TBD. - -Rate-limiter knobs (see `.env.example`): -- `JOIN_TOKEN_FAILURE_LIMIT` / `JOIN_TOKEN_FAILURE_DECAY` — repeated invalid attempts before temporary block (default 10 tries per 5 min). -- `JOIN_TOKEN_ACCESS_LIMIT` / `JOIN_TOKEN_ACCESS_DECAY` — successful request ceiling per token/IP (default 120 req per minute). -- `JOIN_TOKEN_DOWNLOAD_LIMIT` / `JOIN_TOKEN_DOWNLOAD_DECAY` — download ceiling per token/IP (default 60 downloads per minute). - -## Follow-up Tasks -1. Wire aggregated metrics into Grafana once metrics pipeline is ready (synthetic monitors pending SEC-GT-03). -2. Implement scheduled command to email tenants a weekly digest of token activity and stale tokens. -3. Consider anonymising device identifiers before long-term retention (privacy review). - -## Runbook Notes -- Analytics table may grow quickly for high-traffic events; plan nightly prune job (keep 90 days). -- Use `php artisan tinker` to inspect token activity: `EventJoinTokenEvent::where('event_join_token_id', $id)->latest()->limit(20)->get()`. diff --git a/docs/ops/deployment/public-api-incident-playbook.md b/docs/ops/deployment/public-api-incident-playbook.md index bfb0163..2a73da0 100644 --- a/docs/ops/deployment/public-api-incident-playbook.md +++ b/docs/ops/deployment/public-api-incident-playbook.md @@ -17,7 +17,7 @@ The playbook focuses on abuse, availability loss, and leaked content. | 4xx/5xx spikes | Application logs (`storage/logs/laravel.log`), centralized logging | Look for repeated `Join token access denied` / `token_rate_limited` or unexpected 5xx. | | Rate-limit triggers | Laravel log lines emitted from `EventPublicController::handleTokenFailure` | Contains IP + truncated token preview. | | CDN/WAF alerts | Reverse proxy (if enabled) | Ensure 429/403 anomalies are forwarded to incident channel. | -| Synthetic monitors | Planned via `SEC-API-03` | Placeholder until monitors exist. | +| Synthetic monitors | Uptime Kuma (SEC-API-03) | Public uptime + guest API + support API health checks. | Manual check commands: @@ -26,6 +26,32 @@ php artisan log:tail --lines=200 | grep "Join token" php artisan log:tail --lines=200 | grep "gallery" ``` +## 1.1 Synthetic Monitors (Uptime Kuma) + +Primary uptime: +- `GET /` (base domain) — HTTP 200-399. + +Guest API (stable synthetic event tokens required): +- `GET /api/v1/events/{token}` — expect JSON containing `"slug"` or `"engagement_mode"`. +- `GET /api/v1/gallery/{token}` — expect JSON containing `"event"` or `"branding"`. +- `GET /api/v1/gallery/{token}/photos` — expect JSON containing `"data"`. +- `GET /api/v1/events/{token}/photos` — expect JSON containing `"data"`. + +Support API health metrics (read-only token stored in Kuma): +- `GET /api/v1/support/tenants?per_page=1` +- `GET /api/v1/support/events?per_page=1` +- `GET /api/v1/support/photos?per_page=1` + +Defaults: +- Interval: 60s +- Timeout: 10s +- Retries before alert: 2 + +Notes: +- Do not store bearer tokens in the repo; configure them directly in Kuma. +- If synthetic tokens rotate, guest monitors will flap. Keep a dedicated synthetic event/token. +- Import template: `docs/ops/deployment/uptime-kuma-import.template.json` (replace placeholders before import). + ## 2. Severity Classification | Level | Criteria | Examples | diff --git a/docs/ops/deployment/uptime-kuma-import.template.json b/docs/ops/deployment/uptime-kuma-import.template.json new file mode 100644 index 0000000..73b9848 --- /dev/null +++ b/docs/ops/deployment/uptime-kuma-import.template.json @@ -0,0 +1,718 @@ +{ + "version": "1.23.16", + "notificationList": [], + "monitorList": [ + { + "id": 1, + "name": "Uptime: Web Root", + "description": null, + "pathName": "Uptime: Web Root", + "parent": null, + "childrenIDs": [], + "url": "https://fotospiel.app/", + "method": "GET", + "hostname": null, + "port": null, + "maxretries": 2, + "weight": 2000, + "active": true, + "forceInactive": false, + "type": "http", + "timeout": 10, + "interval": 60, + "retryInterval": 60, + "resendInterval": 0, + "keyword": null, + "invertKeyword": false, + "expiryNotification": false, + "ignoreTls": false, + "upsideDown": false, + "packetSize": 56, + "maxredirects": 10, + "accepted_statuscodes": [ + "200-399" + ], + "dns_resolve_type": "A", + "dns_resolve_server": "1.1.1.1", + "dns_last_result": null, + "docker_container": "", + "docker_host": null, + "proxyId": null, + "notificationIDList": {}, + "tags": [], + "maintenance": false, + "mqttTopic": "", + "mqttSuccessMessage": "", + "databaseQuery": null, + "authMethod": "", + "grpcUrl": null, + "grpcProtobuf": null, + "grpcMethod": null, + "grpcServiceName": null, + "grpcEnableTls": false, + "radiusCalledStationId": null, + "radiusCallingStationId": null, + "game": null, + "gamedigGivenPortOnly": true, + "httpBodyEncoding": "json", + "jsonPath": null, + "expectedValue": null, + "kafkaProducerTopic": null, + "kafkaProducerBrokers": [], + "kafkaProducerSsl": false, + "kafkaProducerAllowAutoTopicCreation": false, + "kafkaProducerMessage": null, + "screenshot": null, + "headers": null, + "body": null, + "grpcBody": null, + "grpcMetadata": null, + "basic_auth_user": null, + "basic_auth_pass": null, + "oauth_client_id": null, + "oauth_client_secret": null, + "oauth_token_url": null, + "oauth_scopes": null, + "oauth_auth_method": "client_secret_basic", + "pushToken": null, + "databaseConnectionString": null, + "radiusUsername": null, + "radiusPassword": null, + "radiusSecret": null, + "mqttUsername": "", + "mqttPassword": "", + "authWorkstation": null, + "authDomain": null, + "tlsCa": null, + "tlsCert": null, + "tlsKey": null, + "kafkaProducerSaslOptions": { + "mechanism": "None" + }, + "includeSensitiveData": false + }, + { + "id": 2, + "name": "Guest: Event", + "description": null, + "pathName": "Guest: Event", + "parent": null, + "childrenIDs": [], + "url": "https://fotospiel.app/api/v1/events/", + "method": "GET", + "hostname": null, + "port": null, + "maxretries": 2, + "weight": 2000, + "active": true, + "forceInactive": false, + "type": "keyword", + "timeout": 10, + "interval": 60, + "retryInterval": 60, + "resendInterval": 0, + "keyword": "slug", + "invertKeyword": false, + "expiryNotification": false, + "ignoreTls": false, + "upsideDown": false, + "packetSize": 56, + "maxredirects": 10, + "accepted_statuscodes": [ + "200-299" + ], + "dns_resolve_type": "A", + "dns_resolve_server": "1.1.1.1", + "dns_last_result": null, + "docker_container": "", + "docker_host": null, + "proxyId": null, + "notificationIDList": {}, + "tags": [], + "maintenance": false, + "mqttTopic": "", + "mqttSuccessMessage": "", + "databaseQuery": null, + "authMethod": "", + "grpcUrl": null, + "grpcProtobuf": null, + "grpcMethod": null, + "grpcServiceName": null, + "grpcEnableTls": false, + "radiusCalledStationId": null, + "radiusCallingStationId": null, + "game": null, + "gamedigGivenPortOnly": true, + "httpBodyEncoding": "json", + "jsonPath": null, + "expectedValue": null, + "kafkaProducerTopic": null, + "kafkaProducerBrokers": [], + "kafkaProducerSsl": false, + "kafkaProducerAllowAutoTopicCreation": false, + "kafkaProducerMessage": null, + "screenshot": null, + "headers": null, + "body": null, + "grpcBody": null, + "grpcMetadata": null, + "basic_auth_user": null, + "basic_auth_pass": null, + "oauth_client_id": null, + "oauth_client_secret": null, + "oauth_token_url": null, + "oauth_scopes": null, + "oauth_auth_method": "client_secret_basic", + "pushToken": null, + "databaseConnectionString": null, + "radiusUsername": null, + "radiusPassword": null, + "radiusSecret": null, + "mqttUsername": "", + "mqttPassword": "", + "authWorkstation": null, + "authDomain": null, + "tlsCa": null, + "tlsCert": null, + "tlsKey": null, + "kafkaProducerSaslOptions": { + "mechanism": "None" + }, + "includeSensitiveData": false + }, + { + "id": 3, + "name": "Guest: Gallery", + "description": null, + "pathName": "Guest: Gallery", + "parent": null, + "childrenIDs": [], + "url": "https://fotospiel.app/api/v1/gallery/", + "method": "GET", + "hostname": null, + "port": null, + "maxretries": 2, + "weight": 2000, + "active": true, + "forceInactive": false, + "type": "keyword", + "timeout": 10, + "interval": 60, + "retryInterval": 60, + "resendInterval": 0, + "keyword": "event", + "invertKeyword": false, + "expiryNotification": false, + "ignoreTls": false, + "upsideDown": false, + "packetSize": 56, + "maxredirects": 10, + "accepted_statuscodes": [ + "200-299" + ], + "dns_resolve_type": "A", + "dns_resolve_server": "1.1.1.1", + "dns_last_result": null, + "docker_container": "", + "docker_host": null, + "proxyId": null, + "notificationIDList": {}, + "tags": [], + "maintenance": false, + "mqttTopic": "", + "mqttSuccessMessage": "", + "databaseQuery": null, + "authMethod": "", + "grpcUrl": null, + "grpcProtobuf": null, + "grpcMethod": null, + "grpcServiceName": null, + "grpcEnableTls": false, + "radiusCalledStationId": null, + "radiusCallingStationId": null, + "game": null, + "gamedigGivenPortOnly": true, + "httpBodyEncoding": "json", + "jsonPath": null, + "expectedValue": null, + "kafkaProducerTopic": null, + "kafkaProducerBrokers": [], + "kafkaProducerSsl": false, + "kafkaProducerAllowAutoTopicCreation": false, + "kafkaProducerMessage": null, + "screenshot": null, + "headers": null, + "body": null, + "grpcBody": null, + "grpcMetadata": null, + "basic_auth_user": null, + "basic_auth_pass": null, + "oauth_client_id": null, + "oauth_client_secret": null, + "oauth_token_url": null, + "oauth_scopes": null, + "oauth_auth_method": "client_secret_basic", + "pushToken": null, + "databaseConnectionString": null, + "radiusUsername": null, + "radiusPassword": null, + "radiusSecret": null, + "mqttUsername": "", + "mqttPassword": "", + "authWorkstation": null, + "authDomain": null, + "tlsCa": null, + "tlsCert": null, + "tlsKey": null, + "kafkaProducerSaslOptions": { + "mechanism": "None" + }, + "includeSensitiveData": false + }, + { + "id": 4, + "name": "Guest: Gallery Photos", + "description": null, + "pathName": "Guest: Gallery Photos", + "parent": null, + "childrenIDs": [], + "url": "https://fotospiel.app/api/v1/gallery//photos", + "method": "GET", + "hostname": null, + "port": null, + "maxretries": 2, + "weight": 2000, + "active": true, + "forceInactive": false, + "type": "keyword", + "timeout": 10, + "interval": 60, + "retryInterval": 60, + "resendInterval": 0, + "keyword": "data", + "invertKeyword": false, + "expiryNotification": false, + "ignoreTls": false, + "upsideDown": false, + "packetSize": 56, + "maxredirects": 10, + "accepted_statuscodes": [ + "200-299" + ], + "dns_resolve_type": "A", + "dns_resolve_server": "1.1.1.1", + "dns_last_result": null, + "docker_container": "", + "docker_host": null, + "proxyId": null, + "notificationIDList": {}, + "tags": [], + "maintenance": false, + "mqttTopic": "", + "mqttSuccessMessage": "", + "databaseQuery": null, + "authMethod": "", + "grpcUrl": null, + "grpcProtobuf": null, + "grpcMethod": null, + "grpcServiceName": null, + "grpcEnableTls": false, + "radiusCalledStationId": null, + "radiusCallingStationId": null, + "game": null, + "gamedigGivenPortOnly": true, + "httpBodyEncoding": "json", + "jsonPath": null, + "expectedValue": null, + "kafkaProducerTopic": null, + "kafkaProducerBrokers": [], + "kafkaProducerSsl": false, + "kafkaProducerAllowAutoTopicCreation": false, + "kafkaProducerMessage": null, + "screenshot": null, + "headers": null, + "body": null, + "grpcBody": null, + "grpcMetadata": null, + "basic_auth_user": null, + "basic_auth_pass": null, + "oauth_client_id": null, + "oauth_client_secret": null, + "oauth_token_url": null, + "oauth_scopes": null, + "oauth_auth_method": "client_secret_basic", + "pushToken": null, + "databaseConnectionString": null, + "radiusUsername": null, + "radiusPassword": null, + "radiusSecret": null, + "mqttUsername": "", + "mqttPassword": "", + "authWorkstation": null, + "authDomain": null, + "tlsCa": null, + "tlsCert": null, + "tlsKey": null, + "kafkaProducerSaslOptions": { + "mechanism": "None" + }, + "includeSensitiveData": false + }, + { + "id": 5, + "name": "Guest: Event Photos", + "description": null, + "pathName": "Guest: Event Photos", + "parent": null, + "childrenIDs": [], + "url": "https://fotospiel.app/api/v1/events//photos", + "method": "GET", + "hostname": null, + "port": null, + "maxretries": 2, + "weight": 2000, + "active": true, + "forceInactive": false, + "type": "keyword", + "timeout": 10, + "interval": 60, + "retryInterval": 60, + "resendInterval": 0, + "keyword": "data", + "invertKeyword": false, + "expiryNotification": false, + "ignoreTls": false, + "upsideDown": false, + "packetSize": 56, + "maxredirects": 10, + "accepted_statuscodes": [ + "200-299" + ], + "dns_resolve_type": "A", + "dns_resolve_server": "1.1.1.1", + "dns_last_result": null, + "docker_container": "", + "docker_host": null, + "proxyId": null, + "notificationIDList": {}, + "tags": [], + "maintenance": false, + "mqttTopic": "", + "mqttSuccessMessage": "", + "databaseQuery": null, + "authMethod": "", + "grpcUrl": null, + "grpcProtobuf": null, + "grpcMethod": null, + "grpcServiceName": null, + "grpcEnableTls": false, + "radiusCalledStationId": null, + "radiusCallingStationId": null, + "game": null, + "gamedigGivenPortOnly": true, + "httpBodyEncoding": "json", + "jsonPath": null, + "expectedValue": null, + "kafkaProducerTopic": null, + "kafkaProducerBrokers": [], + "kafkaProducerSsl": false, + "kafkaProducerAllowAutoTopicCreation": false, + "kafkaProducerMessage": null, + "screenshot": null, + "headers": null, + "body": null, + "grpcBody": null, + "grpcMetadata": null, + "basic_auth_user": null, + "basic_auth_pass": null, + "oauth_client_id": null, + "oauth_client_secret": null, + "oauth_token_url": null, + "oauth_scopes": null, + "oauth_auth_method": "client_secret_basic", + "pushToken": null, + "databaseConnectionString": null, + "radiusUsername": null, + "radiusPassword": null, + "radiusSecret": null, + "mqttUsername": "", + "mqttPassword": "", + "authWorkstation": null, + "authDomain": null, + "tlsCa": null, + "tlsCert": null, + "tlsKey": null, + "kafkaProducerSaslOptions": { + "mechanism": "None" + }, + "includeSensitiveData": false + }, + { + "id": 6, + "name": "Support: Tenants", + "description": null, + "pathName": "Support: Tenants", + "parent": null, + "childrenIDs": [], + "url": "https://fotospiel.app/api/v1/support/tenants?per_page=1", + "method": "GET", + "hostname": null, + "port": null, + "maxretries": 2, + "weight": 2000, + "active": true, + "forceInactive": false, + "type": "keyword", + "timeout": 10, + "interval": 60, + "retryInterval": 60, + "resendInterval": 0, + "keyword": "data", + "invertKeyword": false, + "expiryNotification": false, + "ignoreTls": false, + "upsideDown": false, + "packetSize": 56, + "maxredirects": 10, + "accepted_statuscodes": [ + "200-299" + ], + "dns_resolve_type": "A", + "dns_resolve_server": "1.1.1.1", + "dns_last_result": null, + "docker_container": "", + "docker_host": null, + "proxyId": null, + "notificationIDList": {}, + "tags": [], + "maintenance": false, + "mqttTopic": "", + "mqttSuccessMessage": "", + "databaseQuery": null, + "authMethod": "", + "grpcUrl": null, + "grpcProtobuf": null, + "grpcMethod": null, + "grpcServiceName": null, + "grpcEnableTls": false, + "radiusCalledStationId": null, + "radiusCallingStationId": null, + "game": null, + "gamedigGivenPortOnly": true, + "httpBodyEncoding": "json", + "jsonPath": null, + "expectedValue": null, + "kafkaProducerTopic": null, + "kafkaProducerBrokers": [], + "kafkaProducerSsl": false, + "kafkaProducerAllowAutoTopicCreation": false, + "kafkaProducerMessage": null, + "screenshot": null, + "headers": "{\"Authorization\":\"Bearer \"}", + "body": null, + "grpcBody": null, + "grpcMetadata": null, + "basic_auth_user": null, + "basic_auth_pass": null, + "oauth_client_id": null, + "oauth_client_secret": null, + "oauth_token_url": null, + "oauth_scopes": null, + "oauth_auth_method": "client_secret_basic", + "pushToken": null, + "databaseConnectionString": null, + "radiusUsername": null, + "radiusPassword": null, + "radiusSecret": null, + "mqttUsername": "", + "mqttPassword": "", + "authWorkstation": null, + "authDomain": null, + "tlsCa": null, + "tlsCert": null, + "tlsKey": null, + "kafkaProducerSaslOptions": { + "mechanism": "None" + }, + "includeSensitiveData": false + }, + { + "id": 7, + "name": "Support: Events", + "description": null, + "pathName": "Support: Events", + "parent": null, + "childrenIDs": [], + "url": "https://fotospiel.app/api/v1/support/events?per_page=1", + "method": "GET", + "hostname": null, + "port": null, + "maxretries": 2, + "weight": 2000, + "active": true, + "forceInactive": false, + "type": "keyword", + "timeout": 10, + "interval": 60, + "retryInterval": 60, + "resendInterval": 0, + "keyword": "data", + "invertKeyword": false, + "expiryNotification": false, + "ignoreTls": false, + "upsideDown": false, + "packetSize": 56, + "maxredirects": 10, + "accepted_statuscodes": [ + "200-299" + ], + "dns_resolve_type": "A", + "dns_resolve_server": "1.1.1.1", + "dns_last_result": null, + "docker_container": "", + "docker_host": null, + "proxyId": null, + "notificationIDList": {}, + "tags": [], + "maintenance": false, + "mqttTopic": "", + "mqttSuccessMessage": "", + "databaseQuery": null, + "authMethod": "", + "grpcUrl": null, + "grpcProtobuf": null, + "grpcMethod": null, + "grpcServiceName": null, + "grpcEnableTls": false, + "radiusCalledStationId": null, + "radiusCallingStationId": null, + "game": null, + "gamedigGivenPortOnly": true, + "httpBodyEncoding": "json", + "jsonPath": null, + "expectedValue": null, + "kafkaProducerTopic": null, + "kafkaProducerBrokers": [], + "kafkaProducerSsl": false, + "kafkaProducerAllowAutoTopicCreation": false, + "kafkaProducerMessage": null, + "screenshot": null, + "headers": "{\"Authorization\":\"Bearer \"}", + "body": null, + "grpcBody": null, + "grpcMetadata": null, + "basic_auth_user": null, + "basic_auth_pass": null, + "oauth_client_id": null, + "oauth_client_secret": null, + "oauth_token_url": null, + "oauth_scopes": null, + "oauth_auth_method": "client_secret_basic", + "pushToken": null, + "databaseConnectionString": null, + "radiusUsername": null, + "radiusPassword": null, + "radiusSecret": null, + "mqttUsername": "", + "mqttPassword": "", + "authWorkstation": null, + "authDomain": null, + "tlsCa": null, + "tlsCert": null, + "tlsKey": null, + "kafkaProducerSaslOptions": { + "mechanism": "None" + }, + "includeSensitiveData": false + }, + { + "id": 8, + "name": "Support: Photos", + "description": null, + "pathName": "Support: Photos", + "parent": null, + "childrenIDs": [], + "url": "https://fotospiel.app/api/v1/support/photos?per_page=1", + "method": "GET", + "hostname": null, + "port": null, + "maxretries": 2, + "weight": 2000, + "active": true, + "forceInactive": false, + "type": "keyword", + "timeout": 10, + "interval": 60, + "retryInterval": 60, + "resendInterval": 0, + "keyword": "data", + "invertKeyword": false, + "expiryNotification": false, + "ignoreTls": false, + "upsideDown": false, + "packetSize": 56, + "maxredirects": 10, + "accepted_statuscodes": [ + "200-299" + ], + "dns_resolve_type": "A", + "dns_resolve_server": "1.1.1.1", + "dns_last_result": null, + "docker_container": "", + "docker_host": null, + "proxyId": null, + "notificationIDList": {}, + "tags": [], + "maintenance": false, + "mqttTopic": "", + "mqttSuccessMessage": "", + "databaseQuery": null, + "authMethod": "", + "grpcUrl": null, + "grpcProtobuf": null, + "grpcMethod": null, + "grpcServiceName": null, + "grpcEnableTls": false, + "radiusCalledStationId": null, + "radiusCallingStationId": null, + "game": null, + "gamedigGivenPortOnly": true, + "httpBodyEncoding": "json", + "jsonPath": null, + "expectedValue": null, + "kafkaProducerTopic": null, + "kafkaProducerBrokers": [], + "kafkaProducerSsl": false, + "kafkaProducerAllowAutoTopicCreation": false, + "kafkaProducerMessage": null, + "screenshot": null, + "headers": "{\"Authorization\":\"Bearer \"}", + "body": null, + "grpcBody": null, + "grpcMetadata": null, + "basic_auth_user": null, + "basic_auth_pass": null, + "oauth_client_id": null, + "oauth_client_secret": null, + "oauth_token_url": null, + "oauth_scopes": null, + "oauth_auth_method": "client_secret_basic", + "pushToken": null, + "databaseConnectionString": null, + "radiusUsername": null, + "radiusPassword": null, + "radiusSecret": null, + "mqttUsername": "", + "mqttPassword": "", + "authWorkstation": null, + "authDomain": null, + "tlsCa": null, + "tlsCert": null, + "tlsKey": null, + "kafkaProducerSaslOptions": { + "mechanism": "None" + }, + "includeSensitiveData": false + } + ] +}