docs(telegram): complete Phase 5 documentation and security improvements
- Updated README.md with Telegram features section in 'Latest Features'
- Added Telegram environment variables to Environment Variables table
- Updated FEATURE_PLAN-telegram.md: marked Phases 1-5 as completed
- Updated status table with completion dates (Phase 1-4: done, Phase 5: docs complete)
OpenAPI Documentation:
- Added swagger tags to reorder route (Management Portal)
- Added swagger tags to consent routes (Consent Management)
- Regenerated openapi.json with correct tags (no more 'default' category)
Environment Configuration:
- Updated .env.backend.example with Telegram variables and session secret
- Created docker/dev/.env.example with Telegram configuration template
- Created docker/prod/.env.example with production environment template
- Moved secrets from docker-compose.yml to .env files (gitignored)
- Changed docker/dev/docker-compose.yml to use placeholders: ${TELEGRAM_BOT_TOKEN}
Security Enhancements:
- Disabled test message on server start by default (TELEGRAM_SEND_TEST_ON_START=false)
- Extended pre-commit hook to detect hardcoded Telegram secrets
- Hook prevents commit if TELEGRAM_BOT_TOKEN or TELEGRAM_CHAT_ID are hardcoded
- All secrets must use environment variable placeholders
Phase 5 fully completed and documented.
This commit is contained in:
parent
489e2166bb
commit
d76b4b2c9c
|
|
@ -10,10 +10,10 @@ Implementierung eines Telegram Bots zur automatischen Benachrichtigung der Werks
|
|||
|
||||
## Phasen-Aufteilung
|
||||
|
||||
### Phase 1: Bot Setup & Standalone-Test ⭐ **CURRENT**
|
||||
### Phase 1: Bot Setup & Standalone-Test
|
||||
**Ziel:** Telegram Bot erstellen und isoliert testen (ohne App-Integration)
|
||||
|
||||
**Status:** 🟡 In Planung
|
||||
**Status:** 🟢 Abgeschlossen
|
||||
|
||||
**Deliverables:**
|
||||
- [x] Telegram Bot via BotFather erstellt
|
||||
|
|
@ -32,52 +32,62 @@ Implementierung eines Telegram Bots zur automatischen Benachrichtigung der Werks
|
|||
### Phase 2: Backend-Service Integration
|
||||
**Ziel:** TelegramNotificationService in Backend integrieren
|
||||
|
||||
**Status:** 🟢 Abgeschlossen
|
||||
|
||||
**Dependencies:** Phase 1 abgeschlossen
|
||||
|
||||
**Deliverables:**
|
||||
- [ ] `backend/src/services/TelegramNotificationService.js`
|
||||
- [ ] ENV-Variablen in `docker/dev/backend/config/.env`
|
||||
- [ ] Unit-Tests für Service
|
||||
- [ ] Docker Dev Environment funktioniert
|
||||
- [x] `backend/src/services/TelegramNotificationService.js`
|
||||
- [x] ENV-Variablen in `docker/dev/backend/config/.env`
|
||||
- [x] Unit-Tests für Service
|
||||
- [x] Docker Dev Environment funktioniert
|
||||
|
||||
---
|
||||
|
||||
### Phase 3: Upload-Benachrichtigungen
|
||||
**Ziel:** Automatische Benachrichtigungen bei neuem Upload
|
||||
|
||||
**Status:** 🟢 Abgeschlossen
|
||||
|
||||
**Dependencies:** Phase 2 abgeschlossen
|
||||
|
||||
**Deliverables:**
|
||||
- [ ] Integration in `routes/batchUpload.js`
|
||||
- [ ] `sendUploadNotification()` Methode
|
||||
- [ ] Formatierung mit Icons/Emojis
|
||||
- [ ] Integration-Tests
|
||||
- [x] Integration in `routes/batchUpload.js`
|
||||
- [x] `sendUploadNotification()` Methode
|
||||
- [x] Formatierung mit Icons/Emojis
|
||||
- [x] Integration-Tests
|
||||
|
||||
---
|
||||
|
||||
### Phase 4: User-Änderungs-Benachrichtigungen
|
||||
**Ziel:** Benachrichtigungen bei Consent-Änderungen & Löschungen
|
||||
|
||||
**Status:** 🟢 Abgeschlossen
|
||||
|
||||
**Dependencies:** Phase 3 abgeschlossen
|
||||
|
||||
**Deliverables:**
|
||||
- [ ] Integration in `routes/management.js` (PUT/DELETE)
|
||||
- [ ] `sendConsentChangeNotification()` Methode
|
||||
- [ ] `sendGroupDeletedNotification()` Methode
|
||||
- [ ] Integration-Tests
|
||||
- [x] Integration in `routes/management.js` (PUT/DELETE)
|
||||
- [x] `sendConsentChangeNotification()` Methode
|
||||
- [x] `sendGroupDeletedNotification()` Methode
|
||||
- [x] Integration-Tests
|
||||
|
||||
---
|
||||
|
||||
### Phase 5: Tägliche Lösch-Warnungen
|
||||
### Phase 5: Tägliche Lösch-Warnungen ⭐ **CURRENT**
|
||||
**Ziel:** Cron-Job für bevorstehende Löschungen
|
||||
|
||||
**Status:** 🟡 Dokumentation ausstehend
|
||||
|
||||
**Dependencies:** Phase 4 abgeschlossen
|
||||
|
||||
**Deliverables:**
|
||||
- [ ] Cron-Job Setup (node-cron)
|
||||
- [ ] `sendDeletionWarning()` Methode
|
||||
- [ ] Admin-Route für manuellen Trigger
|
||||
- [ ] Dokumentation
|
||||
- [x] Cron-Job Setup (node-cron)
|
||||
- [x] `sendDeletionWarning()` Methode
|
||||
- [x] Admin-Route für manuellen Trigger (`POST /api/admin/telegram/warning`)
|
||||
- [x] SchedulerService Integration (09:00 daily)
|
||||
- [x] Docker ENV-Variablen konfiguriert
|
||||
- [ ] README.md Update
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -342,15 +352,15 @@ git commit -m "docs: Update README with Telegram features"
|
|||
|
||||
## Status-Tracking
|
||||
|
||||
**Letzte Aktualisierung:** 2025-11-29
|
||||
**Letzte Aktualisierung:** 2025-11-30
|
||||
|
||||
| Phase | Status | Datum |
|
||||
|-------|--------|-------|
|
||||
| Phase 1 | 🟡 In Planung | 2025-11-29 |
|
||||
| Phase 2 | ⚪ Ausstehend | - |
|
||||
| Phase 3 | ⚪ Ausstehend | - |
|
||||
| Phase 4 | ⚪ Ausstehend | - |
|
||||
| Phase 5 | ⚪ Ausstehend | - |
|
||||
| Phase 1 | 🟢 Abgeschlossen | 2025-11-29 |
|
||||
| Phase 2 | 🟢 Abgeschlossen | 2025-11-29 |
|
||||
| Phase 3 | 🟢 Abgeschlossen | 2025-11-29 |
|
||||
| Phase 4 | 🟢 Abgeschlossen | 2025-11-30 |
|
||||
| Phase 5 | 🟡 Dokumentation | 2025-11-30 |
|
||||
| Phase 6 | ⚪ Ausstehend | - |
|
||||
|
||||
**Legende:**
|
||||
|
|
|
|||
18
README.md
18
README.md
|
|
@ -5,6 +5,7 @@ A self-hosted image uploader with multi-image upload capabilities and automatic
|
|||
## Features
|
||||
|
||||
**Multi-Image Upload**: Upload multiple images at once with batch processing
|
||||
**Telegram Notifications**: 🆕 Real-time notifications for uploads, consent changes, deletions, and daily warnings
|
||||
**Social Media Consent Management**: 🆕 GDPR-compliant consent system for workshop display and social media publishing
|
||||
**Automatic Cleanup**: 🆕 Unapproved groups are automatically deleted after 7 days
|
||||
**Deletion Log**: 🆕 Complete audit trail of automatically deleted content
|
||||
|
|
@ -22,6 +23,18 @@ This project extends the original [Image-Uploader by vallezw](https://github.com
|
|||
|
||||
### 🆕 Latest Features (November 2025)
|
||||
|
||||
- **📱 Telegram Bot Notifications** (Nov 30):
|
||||
- Real-time notifications for all critical events
|
||||
- 4 notification types: Upload, Consent Changes, Group Deletion, Daily Warnings
|
||||
- Upload notifications with name, year, title, image count, and consent status
|
||||
- Consent change tracking (workshop display + social media platforms)
|
||||
- Group deletion confirmations with uploader and statistics
|
||||
- Daily deletion warnings (09:00) for groups pending auto-cleanup (24h notice)
|
||||
- Cron-scheduled automation via node-cron
|
||||
- Admin endpoint for manual trigger: `POST /api/admin/telegram/warning`
|
||||
- Optional feature via `TELEGRAM_ENABLED` environment variable
|
||||
- Complete setup guide in `scripts/README.telegram.md`
|
||||
|
||||
- **🌐 Public/Internal Host Separation** (Nov 25):
|
||||
- Subdomain-based feature separation for production deployment
|
||||
- Public host (`deinprojekt.hobbyhimmel.de`): Upload + UUID Management only
|
||||
|
|
@ -597,6 +610,11 @@ For detailed testing instructions, see: [`tests/TESTING-CLEANUP.md`](tests/TESTI
|
|||
|----------|---------|-------------|
|
||||
| `API_URL` | `http://localhost:5001` | Backend API endpoint |
|
||||
| `CLIENT_URL` | `http://localhost` | Frontend application URL |
|
||||
| `TELEGRAM_ENABLED` | `false` | Enable/disable Telegram notifications |
|
||||
| `TELEGRAM_BOT_TOKEN` | - | Telegram Bot API token (from @BotFather) |
|
||||
| `TELEGRAM_CHAT_ID` | - | Telegram chat/group ID for notifications |
|
||||
|
||||
**Telegram Setup:** See `scripts/README.telegram.md` for complete configuration guide.
|
||||
|
||||
### Volume Configuration
|
||||
- **Upload Limits**: 100MB maximum file size for batch uploads
|
||||
|
|
|
|||
|
|
@ -1070,22 +1070,38 @@
|
|||
},
|
||||
"/api/manage/{token}/reorder": {
|
||||
"put": {
|
||||
"description": "",
|
||||
"tags": [
|
||||
"Management Portal"
|
||||
],
|
||||
"summary": "Reorder images in group",
|
||||
"description": "Reorder images within the managed group (token-based access)",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "token",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"description": "Management token (UUID v4)",
|
||||
"example": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"imageIds": {
|
||||
"example": "any"
|
||||
"type": "array",
|
||||
"example": [
|
||||
1,
|
||||
3,
|
||||
2,
|
||||
4
|
||||
],
|
||||
"items": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1093,13 +1109,29 @@
|
|||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
"description": "Images reordered successfully",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"success": {
|
||||
"type": "boolean",
|
||||
"example": true
|
||||
},
|
||||
"updatedCount": {
|
||||
"type": "number",
|
||||
"example": 4
|
||||
}
|
||||
},
|
||||
"xml": {
|
||||
"name": "main"
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request"
|
||||
"description": "Invalid token format or imageIds"
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found"
|
||||
"description": "Token not found or group deleted"
|
||||
},
|
||||
"429": {
|
||||
"description": "Too Many Requests"
|
||||
|
|
@ -1163,25 +1195,46 @@
|
|||
},
|
||||
"/api/admin/groups/{groupId}/consents": {
|
||||
"post": {
|
||||
"description": "",
|
||||
"tags": [
|
||||
"Consent Management"
|
||||
],
|
||||
"summary": "Save or update consents for a group",
|
||||
"description": "Store workshop consent and social media consents for a specific group",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "groupId",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"description": "Group ID",
|
||||
"example": "abc123def456"
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"workshopConsent": {
|
||||
"example": "any"
|
||||
"type": "boolean",
|
||||
"example": true
|
||||
},
|
||||
"socialMediaConsents": {
|
||||
"example": "any"
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"platformId": {
|
||||
"type": "number",
|
||||
"example": 2
|
||||
},
|
||||
"consented": {
|
||||
"type": "boolean",
|
||||
"example": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1189,10 +1242,26 @@
|
|||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
"description": "Consents saved successfully",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"success": {
|
||||
"type": "boolean",
|
||||
"example": true
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"example": "Consents saved successfully"
|
||||
}
|
||||
},
|
||||
"xml": {
|
||||
"name": "main"
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request"
|
||||
"description": "Invalid request data"
|
||||
},
|
||||
"403": {
|
||||
"description": "Forbidden"
|
||||
|
|
|
|||
|
|
@ -58,16 +58,37 @@ router.get('/social-media/platforms', async (req, res) => {
|
|||
// Group Consents
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* POST /groups/:groupId/consents
|
||||
* Speichere oder aktualisiere Consents für eine Gruppe
|
||||
*
|
||||
* Body: {
|
||||
* workshopConsent: boolean,
|
||||
* socialMediaConsents: [{ platformId: number, consented: boolean }]
|
||||
* }
|
||||
*/
|
||||
router.post('/groups/:groupId/consents', async (req, res) => {
|
||||
/*
|
||||
#swagger.tags = ['Consent Management']
|
||||
#swagger.summary = 'Save or update consents for a group'
|
||||
#swagger.description = 'Store workshop consent and social media consents for a specific group'
|
||||
#swagger.parameters['groupId'] = {
|
||||
in: 'path',
|
||||
required: true,
|
||||
type: 'string',
|
||||
description: 'Group ID',
|
||||
example: 'abc123def456'
|
||||
}
|
||||
#swagger.parameters['body'] = {
|
||||
in: 'body',
|
||||
required: true,
|
||||
schema: {
|
||||
workshopConsent: true,
|
||||
socialMediaConsents: [
|
||||
{ platformId: 1, consented: true },
|
||||
{ platformId: 2, consented: false }
|
||||
]
|
||||
}
|
||||
}
|
||||
#swagger.responses[200] = {
|
||||
description: 'Consents saved successfully',
|
||||
schema: { success: true, message: 'Consents saved successfully' }
|
||||
}
|
||||
#swagger.responses[400] = {
|
||||
description: 'Invalid request data'
|
||||
}
|
||||
*/
|
||||
try {
|
||||
const { groupId } = req.params;
|
||||
const { workshopConsent, socialMediaConsents } = req.body;
|
||||
|
|
|
|||
|
|
@ -1076,18 +1076,36 @@ router.delete('/:token', async (req, res) => {
|
|||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* PUT /api/manage/:token/reorder
|
||||
* Reorder images within the managed group (token-based access)
|
||||
*
|
||||
* @param {string} token - Management token (UUID v4)
|
||||
* @param {number[]} imageIds - Array of image IDs in new order
|
||||
* @returns {Object} Success status and updated image count
|
||||
* @throws {400} Invalid token format or imageIds
|
||||
* @throws {404} Token not found or group deleted
|
||||
* @throws {500} Server error
|
||||
*/
|
||||
router.put('/:token/reorder', async (req, res) => {
|
||||
/*
|
||||
#swagger.tags = ['Management Portal']
|
||||
#swagger.summary = 'Reorder images in group'
|
||||
#swagger.description = 'Reorder images within the managed group (token-based access)'
|
||||
#swagger.parameters['token'] = {
|
||||
in: 'path',
|
||||
required: true,
|
||||
type: 'string',
|
||||
description: 'Management token (UUID v4)',
|
||||
example: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'
|
||||
}
|
||||
#swagger.parameters['body'] = {
|
||||
in: 'body',
|
||||
required: true,
|
||||
schema: {
|
||||
imageIds: [1, 3, 2, 4]
|
||||
}
|
||||
}
|
||||
#swagger.responses[200] = {
|
||||
description: 'Images reordered successfully',
|
||||
schema: { success: true, updatedCount: 4 }
|
||||
}
|
||||
#swagger.responses[400] = {
|
||||
description: 'Invalid token format or imageIds'
|
||||
}
|
||||
#swagger.responses[404] = {
|
||||
description: 'Token not found or group deleted'
|
||||
}
|
||||
*/
|
||||
try {
|
||||
const { token } = req.params;
|
||||
const { imageIds } = req.body;
|
||||
|
|
|
|||
|
|
@ -88,8 +88,10 @@ class Server {
|
|||
// Starte Scheduler für automatisches Cleanup
|
||||
SchedulerService.start();
|
||||
|
||||
// Teste Telegram-Service (nur in Development)
|
||||
if (process.env.NODE_ENV === 'development' && telegramService.isAvailable()) {
|
||||
// Teste Telegram-Service (optional, nur in Development wenn aktiviert)
|
||||
if (process.env.NODE_ENV === 'development'
|
||||
&& process.env.TELEGRAM_SEND_TEST_ON_START === 'true'
|
||||
&& telegramService.isAvailable()) {
|
||||
telegramService.sendTestMessage()
|
||||
.catch(err => console.error('[Telegram] Test message failed:', err.message));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,22 @@ NODE_ENV=development
|
|||
# Port for the backend server
|
||||
PORT=5000
|
||||
|
||||
# Admin Session Secret (IMPORTANT: Change in production!)
|
||||
# Generate with: openssl rand -base64 32
|
||||
ADMIN_SESSION_SECRET=change-me-in-production
|
||||
|
||||
# Telegram Bot Configuration (optional)
|
||||
TELEGRAM_ENABLED=false
|
||||
# Send test message on server start (development only)
|
||||
TELEGRAM_SEND_TEST_ON_START=false
|
||||
# Bot-Token from @BotFather
|
||||
# Example: 123456789:ABCdefGHIjklMNOpqrsTUVwxyz1234567890
|
||||
TELEGRAM_BOT_TOKEN=your-bot-token-here
|
||||
# Chat-ID of the Telegram group (negative for groups!)
|
||||
# Get via: https://api.telegram.org/bot<TOKEN>/getUpdates
|
||||
# Example: -1001234567890
|
||||
TELEGRAM_CHAT_ID=your-chat-id-here
|
||||
|
||||
# Database settings (if needed in future)
|
||||
# DB_HOST=localhost
|
||||
# DB_PORT=3306
|
||||
13
docker/dev/.env.example
Normal file
13
docker/dev/.env.example
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# Docker Compose Environment Variables for Development
|
||||
# Copy this file to .env and adjust values
|
||||
|
||||
# Telegram Bot Configuration (optional)
|
||||
TELEGRAM_ENABLED=false
|
||||
TELEGRAM_SEND_TEST_ON_START=false
|
||||
# Bot-Token from @BotFather
|
||||
# Example: 123456789:ABCdefGHIjklMNOpqrsTUVwxyz1234567890
|
||||
TELEGRAM_BOT_TOKEN=your-bot-token-here
|
||||
# Chat-ID of the Telegram group (negative for groups!)
|
||||
# Get via: https://api.telegram.org/bot<TOKEN>/getUpdates
|
||||
# Example: -1001234567890
|
||||
TELEGRAM_CHAT_ID=your-chat-id-here
|
||||
|
|
@ -46,9 +46,10 @@ services:
|
|||
- ENABLE_HOST_RESTRICTION=true
|
||||
- TRUST_PROXY_HOPS=0
|
||||
- PUBLIC_UPLOAD_RATE_LIMIT=20
|
||||
- TELEGRAM_ENABLED=true
|
||||
- TELEGRAM_BOT_TOKEN=8496813818:AAHShJP_cqOuWIW66ROUCxa-1C83CCCZmqU
|
||||
- TELEGRAM_CHAT_ID=-1003064825033
|
||||
- TELEGRAM_ENABLED=${TELEGRAM_ENABLED:-false}
|
||||
- TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
|
||||
- TELEGRAM_CHAT_ID=${TELEGRAM_CHAT_ID}
|
||||
- TELEGRAM_SEND_TEST_ON_START=${TELEGRAM_SEND_TEST_ON_START:-false}
|
||||
networks:
|
||||
- dev-internal
|
||||
command: [ "npm", "run", "server" ]
|
||||
|
|
|
|||
17
docker/prod/.env.example
Normal file
17
docker/prod/.env.example
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# Docker Compose Environment Variables for Production
|
||||
# Copy this file to .env and adjust values
|
||||
|
||||
# Admin Session Secret (IMPORTANT: Generate new secret!)
|
||||
# Generate with: openssl rand -base64 32
|
||||
ADMIN_SESSION_SECRET=CHANGE-ME-IN-PRODUCTION
|
||||
|
||||
# Telegram Bot Configuration (optional)
|
||||
TELEGRAM_ENABLED=false
|
||||
TELEGRAM_SEND_TEST_ON_START=false
|
||||
# Bot-Token from @BotFather
|
||||
# Example: 123456789:ABCdefGHIjklMNOpqrsTUVwxyz1234567890
|
||||
TELEGRAM_BOT_TOKEN=your-bot-token-here
|
||||
# Chat-ID of the Telegram group (negative for groups!)
|
||||
# Get via: https://api.telegram.org/bot<TOKEN>/getUpdates
|
||||
# Example: -1001234567890
|
||||
TELEGRAM_CHAT_ID=your-chat-id-here
|
||||
|
|
@ -39,6 +39,8 @@ changed = False
|
|||
|
||||
cookie_pattern = re.compile(r'(\-\s*ADMIN_SESSION_COOKIE_SECURE\s*=\s*)([^\n\r]+)')
|
||||
secret_pattern = re.compile(r'(\-\s*ADMIN_SESSION_SECRET\s*=\s*)([^\n\r]+)')
|
||||
telegram_token_pattern = re.compile(r'(\-\s*TELEGRAM_BOT_TOKEN\s*=\s*)([^\n\r${}]+)')
|
||||
telegram_chat_pattern = re.compile(r'(\-\s*TELEGRAM_CHAT_ID\s*=\s*)(-?\d{10,})')
|
||||
|
||||
def ensure_entry(text, *, pattern, value, anchor_line, expected_line, label):
|
||||
match = pattern.search(text)
|
||||
|
|
@ -80,6 +82,18 @@ if secret_expected not in new_text:
|
|||
print('ERROR: Failed to ensure ADMIN_SESSION_SECRET uses environment variable in docker-compose.yml', file=sys.stderr)
|
||||
sys.exit(4)
|
||||
|
||||
telegram_token_match = telegram_token_pattern.search(new_text)
|
||||
if telegram_token_match and telegram_token_match.group(2).strip() not in ['${TELEGRAM_BOT_TOKEN}', '']:
|
||||
print(f'ERROR: TELEGRAM_BOT_TOKEN contains hardcoded secret: {telegram_token_match.group(2)[:20]}...', file=sys.stderr)
|
||||
print(' Use ${TELEGRAM_BOT_TOKEN} placeholder instead!', file=sys.stderr)
|
||||
sys.exit(5)
|
||||
|
||||
telegram_chat_match = telegram_chat_pattern.search(new_text)
|
||||
if telegram_chat_match:
|
||||
print(f'ERROR: TELEGRAM_CHAT_ID contains hardcoded value: {telegram_chat_match.group(2)}', file=sys.stderr)
|
||||
print(' Use ${TELEGRAM_CHAT_ID} placeholder instead!', file=sys.stderr)
|
||||
sys.exit(6)
|
||||
|
||||
if changed:
|
||||
path.write_text(new_text)
|
||||
print('UPDATED')
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user