diff --git a/.gitignore b/.gitignore index 8994b5d..a054b2f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ data/ config/credentials config/nextcloud/ +scripts/setup/paperless/node_modules \ No newline at end of file diff --git a/ansible/roles/services/defaults/main.yml b/ansible/roles/services/defaults/main.yml index 3555dd9..168ea0f 100644 --- a/ansible/roles/services/defaults/main.yml +++ b/ansible/roles/services/defaults/main.yml @@ -20,4 +20,13 @@ sso_config: nextcloud-youpi: "youpi" # Default paths and settings -nextcloud_data_dir: "/var/www/html/data" \ No newline at end of file +nextcloud_data_dir: "/var/www/html/data" + +# ansible/roles/services/defaults/main.yml +paperless_oidc: + client_id: paperless + provider_url: "https://{{ keycloak_host }}" + realm: "{{ keycloak_realm }}" + sign_algo: "RS256" + verify_ssl: false + scopes: "openid profile email" \ No newline at end of file diff --git a/ansible/roles/services/tasks/main.yml b/ansible/roles/services/tasks/main.yml index c6f13f1..c64d421 100644 --- a/ansible/roles/services/tasks/main.yml +++ b/ansible/roles/services/tasks/main.yml @@ -120,4 +120,15 @@ - name: "Display SSO configuration" debug: - var: sso_config_verification.stdout \ No newline at end of file + var: sso_config_verification.stdout + +# ansible/roles/services/tasks/main.yml +- name: Configure Paperless + block: + - name: Setup Paperless Django settings + template: + src: paperless_django_settings.j2 + dest: "{{ paperless_config_dir }}/django/settings.py" + tags: + - paperless + - paperless-config \ No newline at end of file diff --git a/ansible/vars/defaults/main.yml b/ansible/vars/defaults/main.yml index 93934a6..e14a77f 100644 --- a/ansible/vars/defaults/main.yml +++ b/ansible/vars/defaults/main.yml @@ -19,3 +19,9 @@ nodered_port: 1880 # Docker-Konfiguration docker_compose_version: "2.21.0" + +# Paperless Variables +paperless_base_dir: /path/to/your/paperless +paperless_oidc_client_id: paperless +keycloak_host: auth.mrx8086.com +keycloak_realm: office-automation \ No newline at end of file diff --git a/config/nginx/sites-available/keycloak b/config/nginx/sites-available/keycloak index cf437a2..a24450e 100644 --- a/config/nginx/sites-available/keycloak +++ b/config/nginx/sites-available/keycloak @@ -1,5 +1,5 @@ upstream keycloak_upstream { - server 172.18.0.3:8080; + server 172.19.0.3:8080; } server { diff --git a/config/nginx/sites-available/nextcloud b/config/nginx/sites-available/nextcloud index 8357df3..3c24334 100644 --- a/config/nginx/sites-available/nextcloud +++ b/config/nginx/sites-available/nextcloud @@ -1,5 +1,5 @@ upstream nextcloud_upstream { - server 172.19.0.3:80; # SICHERSTELLEN, DASS DIES DIE KORREKTE IP IST + server 172.20.0.3:80; # SICHERSTELLEN, DASS DIES DIE KORREKTE IP IST } server { diff --git a/config/nginx/sites-available/paperless b/config/nginx/sites-available/paperless index 6a7b80c..41563c5 100644 --- a/config/nginx/sites-available/paperless +++ b/config/nginx/sites-available/paperless @@ -1,41 +1,61 @@ -# HTTP-Weiterleitung auf HTTPS +upstream paperless_upstream { + server 172.18.0.4:8000; # SICHERSTELLEN, DASS DIES DIE KORREKTE IP UND DER PORT IST +} + server { listen 80; server_name docs.mrx8086.com; - - # Weiterleitung von HTTP zu HTTPS return 301 https://$host$request_uri; } -# HTTPS-Server server { listen 443 ssl; server_name docs.mrx8086.com; - # SSL-Zertifikate einbinden + # SSL Configuration ssl_certificate /etc/nginx/ssl/mrx8086.com/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/mrx8086.com/privkey.pem; - # Empfohlene SSL-Einstellungen (optional) ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; - ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; - ssl_session_cache shared:SSL:10m; - ssl_session_timeout 10m; + ssl_ciphers 'TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305'; + ssl_session_timeout 1d; + ssl_session_cache shared:MozSSL:10m; + ssl_session_tickets off; + # Security headers + add_header X-Content-Type-Options nosniff always; + add_header X-XSS-Protection "1; mode=block" always; + add_header X-Frame-Options SAMEORIGIN always; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; - add_header X-Content-Type-Options nosniff; - add_header X-Frame-Options DENY; - add_header X-XSS-Protection "1; mode=block"; + add_header Content-Security-Policy "frame-ancestors 'self'; default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; connect-src 'self'; media-src 'self';" always; + + # Proxy settings + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port 443; + proxy_set_header Host $host; + proxy_http_version 1.1; - # Paperless-NGX Konfiguration + # Paperless specific settings + client_max_body_size 512M; + fastcgi_buffers 64 4K; + + # Root location location / { - proxy_pass http://127.0.0.1:8000; # Paperless läuft auf Port 8000 innerhalb des Docker-Containers - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto https; - proxy_set_header X-Forwarded-Port 443; + proxy_pass http://paperless_upstream; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; } -} + # Deny access to hidden files + location ~ /\. { + deny all; + return 404; + } +} \ No newline at end of file diff --git a/docker/.env b/docker/.env index 2a7c926..0993b0b 100644 --- a/docker/.env +++ b/docker/.env @@ -11,4 +11,49 @@ NEXTCLOUD_DB_USER=nextcloud NEXTCLOUD_DB_PASSWORD=YeTn4f1IIM9a7I3Q7oZNaEhs NEXTCLOUD_DB_ROOT_PASSWORD=rY26aXw9uMOqz2BjtevQ4oKB NEXTCLOUD_ADMIN_USER=admin -NEXTCLOUD_ADMIN_PASSWORD=jTjRBEJb2ZSAH0iJoqeZijYL \ No newline at end of file +NEXTCLOUD_ADMIN_PASSWORD=jTjRBEJb2ZSAH0iJoqeZijYL + + + +# ============================================================================== +# Paperless Environment Variables +# ============================================================================== + +# Datenbank-Konfiguration +# ------------------------------------------------------------------------------ +# Benutzername für die Paperless-Datenbank +PAPERLESS_DB_USER=paperless + +# Passwort für die Paperless-Datenbank +PAPERLESS_DB_PASSWORD=sq812ylB1Lfk49xbP8xxNSDA + +# Datenbank Name +PAPERLESS_DB_NAME=paperless + +# Paperless Admin User +# ------------------------------------------------------------------------------ +# Benutzername für den Paperless Admin Account +PAPERLESS_ADMIN_USER=admin + +# Passwort für den Paperless Admin Account +PAPERLESS_ADMIN_PASSWORD=GRnrM1lrMl63E16HgZk8PBXU + +# Paperless Secret Key +# ------------------------------------------------------------------------------ +# Geheimer Schlüssel für Paperless (wird für Django benötigt) +# Sollte ein zufälliger, sicherer String sein +PAPERLESS_SECRET_KEY=qfQ7MeGB79F6nbTgFk99K2Nx + +# Paperless OpenID Connect (Keycloak) Konfiguration +# ------------------------------------------------------------------------------ +# Client ID für Paperless in Keycloak +PAPERLESS_CLIENT_ID=paperless + +# Client Secret für Paperless in Keycloak +PAPERLESS_CLIENT_SECRET=CSbw9ldbZBUGGQSJoAUEg10QKgjdb6Tq + +# Die URL von Paperless +PAPERLESS_URL=https://docs.mrx8086.com + +# Erlaubte Hosts für Paperless +PAPERLESS_ALLOWED_HOSTS=docs.mrx8086.com \ No newline at end of file diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index ccbcd3b..d3bf016 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -117,8 +117,102 @@ services: networks: - nextcloud-network + paperless: + image: ghcr.io/paperless-ngx/paperless-ngx:latest + container_name: paperless + restart: unless-stopped + ports: + - "8000:8000" + volumes: + - ../data/paperless:/usr/src/paperless/data + - ../config/paperless/media:/usr/src/paperless/media + - ../config/paperless/export:/usr/src/paperless/export + - ../config/paperless/consume:/usr/src/paperless/consume + environment: + # Basis-Konfiguration + - PAPERLESS_ADMIN_USER=${PAPERLESS_ADMIN_USER} + - PAPERLESS_ADMIN_PASSWORD=${PAPERLESS_ADMIN_PASSWORD} + - PAPERLESS_SECRET_KEY=${PAPERLESS_SECRET_KEY} + - PAPERLESS_URL=https://docs.mrx8086.com + - PAPERLESS_ALLOWED_HOSTS=docs.mrx8086.com + - PAPERLESS_REDIS=redis://paperless-redis:6379 + - PAPERLESS_LOGGING_DIR=/dev/stdout + - PAPERLESS_LOGGING_LEVEL=DEBUG + - DJANGO_LOG_LEVEL=DEBUG + + # OIDC Basis-Einstellungen + - PAPERLESS_ENABLE_OIDC=true + - PAPERLESS_OIDC_RP_PROVIDER_URL=https://auth.mrx8086.com/realms/office-automation + - PAPERLESS_OIDC_RP_CLIENT_ID=paperless + - PAPERLESS_OIDC_RP_CLIENT_SECRET=${PAPERLESS_CLIENT_SECRET} + + # OIDC Endpoints + - PAPERLESS_OIDC_AUTH_ENDPOINT=https://auth.mrx8086.com/realms/office-automation/protocol/openid-connect/auth + - PAPERLESS_OIDC_TOKEN_ENDPOINT=https://auth.mrx8086.com/realms/office-automation/protocol/openid-connect/token + - PAPERLESS_OIDC_USERINFO_ENDPOINT=https://auth.mrx8086.com/realms/office-automation/protocol/openid-connect/userinfo + - PAPERLESS_OIDC_JWKS_ENDPOINT=https://auth.mrx8086.com/realms/office-automation/protocol/openid-connect/certs + + # OIDC Claims und Scopes + - PAPERLESS_OIDC_RP_SCOPE=openid profile email + - PAPERLESS_OIDC_RP_USERNAME_CLAIM=preferred_username + - PAPERLESS_OIDC_RP_NAME_CLAIM=name + - PAPERLESS_OIDC_RP_EMAIL_CLAIM=email + + # OIDC Sicherheitseinstellungen + - PAPERLESS_OIDC_RP_SIGN_ALGO=RS256 + - PAPERLESS_OIDC_RP_VERIFY_SSL=false + - PAPERLESS_OIDC_USE_PKCE=true + + # OIDC Token-Management + - PAPERLESS_OIDC_RP_RENEW_TOKEN_BEFORE_EXPIRY=true + + depends_on: + - paperless-db + - paperless-redis + networks: + - paperless-network + extra_hosts: + - "auth.mrx8086.com:172.23.171.133" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8000/"] + interval: 30s + timeout: 10s + retries: 3 + + paperless-db: + image: postgres:15 + container_name: paperless-db + restart: unless-stopped + environment: + POSTGRES_USER: ${PAPERLESS_DB_USER} + POSTGRES_PASSWORD: ${PAPERLESS_DB_PASSWORD} + POSTGRES_DB: paperless + volumes: + - ../data/paperless-db:/var/lib/postgresql/data + networks: + - paperless-network + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${PAPERLESS_DB_USER} -d paperless"] + interval: 10s + timeout: 5s + retries: 5 + + paperless-redis: + image: redis:7 + container_name: paperless-redis + restart: unless-stopped + networks: + - paperless-network + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 5s + retries: 5 + networks: keycloak-network: driver: bridge nextcloud-network: + driver: bridge + paperless-network: driver: bridge \ No newline at end of file diff --git a/docs/context/configuration/docker-compose.yml b/docs/context/configuration/docker-compose.yml index 86b29d1..d36b088 100644 --- a/docs/context/configuration/docker-compose.yml +++ b/docs/context/configuration/docker-compose.yml @@ -100,8 +100,66 @@ services: networks: - nextcloud-network + paperless: + image: ghcr.io/paperless-ngx/paperless-ngx:latest + container_name: paperless + restart: unless-stopped + ports: + - "8000:8000" + volumes: + - ../data/paperless:/usr/src/paperless/data + - ../config/paperless/media:/usr/src/paperless/media + - ../config/paperless/export:/usr/src/paperless/export + - ../config/paperless/consume:/usr/src/paperless/consume + environment: + - PAPERLESS_ADMIN_USER=${PAPERLESS_ADMIN_USER} + - PAPERLESS_ADMIN_PASSWORD=${PAPERLESS_ADMIN_PASSWORD} + - PAPERLESS_SECRET_KEY=${PAPERLESS_SECRET_KEY} + - PAPERLESS_URL=https://docs.mrx8086.com + - PAPERLESS_ALLOWED_HOSTS=docs.mrx8086.com + - PAPERLESS_ENABLE_OIDC=true + - PAPERLESS_OIDC_RP_CLIENT_ID=${PAPERLESS_CLIENT_ID} + - PAPERLESS_OIDC_RP_CLIENT_SECRET=${PAPERLESS_CLIENT_SECRET} + - PAPERLESS_OIDC_RP_PROVIDER_URL=https://auth.mrx8086.com/realms/office-automation + - PAPERLESS_OIDC_RP_USERNAME_CLAIM=preferred_username + - PAPERLESS_OIDC_RP_NAME_CLAIM=name + - PAPERLESS_OIDC_RP_EMAIL_CLAIM=email + - PAPERLESS_OIDC_RP_RENEW_TOKEN_BEFORE_EXPIRY=true + - PAPERLESS_OIDC_RP_VERIFY_SSL=false + depends_on: + - paperless-db + networks: + - paperless-network + extra_hosts: + - "auth.mrx8086.com:172.23.171.133" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8000/"] + interval: 30s + timeout: 10s + retries: 3 + + paperless-db: + image: postgres:15 + container_name: paperless-db + restart: unless-stopped + environment: + POSTGRES_USER: ${PAPERLESS_DB_USER} + POSTGRES_PASSWORD: ${PAPERLESS_DB_PASSWORD} + POSTGRES_DB: paperless + volumes: + - ../data/paperless-db:/var/lib/postgresql/data + networks: + - paperless-network + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${PAPERLESS_DB_USER} -d paperless"] + interval: 10s + timeout: 5s + retries: 5 + networks: keycloak-network: driver: bridge nextcloud-network: + driver: bridge + paperless-network: driver: bridge \ No newline at end of file diff --git a/git_diff.txt b/git_diff.txt index bfb2d94..2f87fcb 100644 --- a/git_diff.txt +++ b/git_diff.txt @@ -1,823 +0,0 @@ -Vielen Dank für die Bereitstellung der Dateien. Ich habe alle notwendigen Informationen, um die Dokumentation zu erstellen. Hier ist der Inhalt der finalen Dokumentationsdateien: - -```markdown -# Automatisiertes Büro 2.0 - Projektdokumentation - -## Inhaltsverzeichnis -1. [Projektübersicht](#projektübersicht) -2. [Systemarchitektur](#systemarchitektur) -3. [Entwicklungsumgebung](#entwicklungsumgebung) -4. [Konfigurationen](#konfigurationen) -5. [Installationsanleitung](#installationsanleitung) -6. [Workflows](#workflows) -7. [Sicherheitskonzept](#sicherheitskonzept) -8. [Wartung und Monitoring](#wartung-und-monitoring) -9. [Troubleshooting](#troubleshooting) - -## Projektübersicht - -### Projektziele -- Vollständige Automatisierung administrativer und kaufmännischer Prozesse -- Kostensenkung durch lokale Open-Source-Lösungen -- Unabhängigkeit von externen Diensten -- Zentralisierte Verwaltung aller Geschäftsprozesse - -### Projektumfang -- Integration aller Kommunikationskanäle -- Automatisierte Dokumentenverarbeitung -- Prozessautomatisierung -- Zentrale Authentifizierung -- KI-gestützte Korrespondenz - -#### Keycloak-Rolle -Keycloak spielt eine zentrale Rolle als Authentifizierungsstelle. Es stellt die Single-Sign-On (SSO) Funktionalität für alle Dienste der zentralen Plattform bereit und sichert somit den Zugriff auf die verschiedenen Anwendungen. - -## Systemarchitektur - -#### Architekturübersicht - -```mermaid -graph TB - subgraph Eingangssysteme - Email[E-Mail] - WhatsApp[WhatsApp] - Post[Physische Post] - Teams[Teams/Webex] - end - - subgraph Zentrale_Plattform - NC[Nextcloud - Dokumentenverwaltung] - PL[Paperless - Dokumentenmanagement] - NR[Node-RED - Prozessautomatisierung] - KC[Keycloak - SSO] - OUI[OpenWebUI - KI-Korrespondenz] - KI[Kimai - Zeiterfassung] - end - - subgraph Monitoring_Analytics - ELK[ELK Stack - Logging & Analyse] - end - - subgraph Geschäftsprozesse - TP[Task-Priorisierung] - subgraph Finanzen - RE[Rechnungserstellung] - ZA[Zahlungsabwicklung] - BA[Banken-API] - end - subgraph Verwaltung - KV[Kundenverwaltung] - ZE[Zeiterfassung] - DO[Dokumentenarchiv] - end - end - - Email --> NC - WhatsApp --> NC - Post --> PL - Teams --> NC - - NC --> NR - PL --> NR - NR --> TP - KI --> TP - - TP --> RE - TP --> ZA - TP --> KV - TP --> ZE - TP --> DO - - ZA <--> BA - - KC -.->|Authentifizierung| NC - KC -.->|Authentifizierung| PL - KC -.->|Authentifizierung| NR - KC -.->|Authentifizierung| OUI - KC -.->|Authentifizierung| KI - - NR --> ELK - OUI --> NR - - classDef container fill:#e1f5fe,stroke:#01579b - classDef process fill:#e8f5e9,stroke:#2e7d32 - classDef auth fill:#fff3e0,stroke:#ef6c00 - classDef monitoring fill:#fce4ec,stroke:#c2185b - - class NC,PL,NR,KI container - class TP,RE,ZA,KV,ZE,DO process - class KC auth - class ELK monitoring -``` - -#### Beschreibung der Architekturkomponenten - -Die Systemarchitektur ist in vier Hauptbereiche gegliedert: - -1. **Eingangssysteme:** - - Erfassen verschiedene Kommunikationskanäle zentral. - - Sorgen für eine einheitliche Weiterverarbeitung aller Eingänge. - -2. **Zentrale Plattform:** - - **Nextcloud (NC):** Dient als zentraler Hub für die Dateiverwaltung und Kollaboration. - - **Paperless (PL):** Zuständig für das Dokumentenmanagement und die optische Zeichenerkennung (OCR). - - **Node-RED (NR):** Automatisierung von Workflows und Geschäftsprozessen. - - **Keycloak (KC):** Bereitstellung von Single-Sign-On (SSO) und Identitätsmanagement. - - Keycloak wird als zentrale Authentifizierungsstelle für alle Dienste der zentralen Plattform verwendet, wodurch ein sicherer und zentralisierter Zugriff gewährleistet wird. - - **OpenWebUI (OUI):** KI-gestützte Kommunikation und Integration in die Workflow-Automatisierung - - **Kimai (KI):** Zeiterfassungslösung zur Verwaltung von Arbeitszeiten und Projekten. - -3. **Geschäftsprozesse:** - - Automatisierte Task-Priorisierung (TP) für eine effiziente Aufgabenverteilung. - - Integrierte Finanzprozesse mit Bankenanbindung (RE, ZA, BA). - - Zentralisierte Verwaltungsprozesse (KV, ZE, DO). - -4. **Monitoring & Analytics:** - - **ELK Stack (ELK):** Ermöglicht umfassendes Logging und Analyse in Echtzeit zur Überwachung aller Systeme. - -#### Containerstruktur -- Docker als Containerisierungsplattform -- Microservices-Architektur -- Interne Netzwerkkonfiguration - -### Komponenten -#### Nextcloud -- Funktion: Zentrale Dateiverwaltung und Kollaboration -- Version: `[VERSION]` -- Besondere Konfigurationen: - - [Wird ergänzt] - -#### Paperless -- Funktion: Dokumentenmanagement und OCR -- Version: `[VERSION]` -- Besondere Konfigurationen: - - [Wird ergänzt] - -#### Keycloak -- Funktion: Single-Sign-On und Identitätsmanagement -- Version: `[VERSION]` -- Besondere Konfigurationen: - - [Wird ergänzt] - -#### Node-RED -- Funktion: Workflow-Automatisierung -- Version: `[VERSION]` -- Implementierte Flows: - - [Wird ergänzt] - -#### ELK Stack -- Funktion: Logging und Monitoring -- Version: `[VERSION]` -- Besondere Konfigurationen: - - [Wird ergänzt] - -#### OpenWebUI -- Funktion: KI-gestützte Kommunikation -- Version: `[VERSION]` -- Integrationen: - - [Wird ergänzt] - -#### Kimai -- Funktion: Zeiterfassung -- Version: `[VERSION]` -- Besondere Konfigurationen: - - [Wird ergänzt] - -## Entwicklungsumgebung - -### Systemvoraussetzungen -- Windows mit WSL (Windows Subsystem for Linux) -- Visual Studio Code -- Docker Desktop -- NGINX Proxy Manager (läuft in WSL) - -#### Domain-Konfiguration -Die Entwicklungsumgebung nutzt die Domain `mrx8086.com` mit verschiedenen Subdomains für die einzelnen Services. Diese werden lokal über die Windows-Hosts-Datei (`C:\Windows\System32\drivers\etc\hosts`) aufgelöst. - -```plaintext -# Development Environment Host Entries -127.0.0.1 mrx8086.com -127.0.0.1 proxy.mrx8086.com # NGINX Proxy Manager -172.23.171.133 auth.mrx8086.com # Keycloak -127.0.0.1 cloud.mrx8086.com # Nextcloud -127.0.0.1 docs.mrx8086.com # Paperless -127.0.0.1 time.mrx8086.com # Kimai -127.0.0.1 automate.mrx8086.com # n8n -``` - -#### Service-Übersicht -| Subdomain | Service | Beschreibung | -|-----------|---------|--------------| -| proxy.mrx8086.com | NGINX Proxy Manager | Reverse Proxy und SSL-Management (lokal in der Development Umgebung) | -| auth.mrx8086.com | Keycloak | Zentrale Authentifizierung | -| cloud.mrx8086.com | Nextcloud | Dokumentenverwaltung | -| docs.mrx8086.com | Paperless | Dokumentenmanagement | -| time.mrx8086.com | Kimai | Zeiterfassung | -| automate.mrx8086.com | n8n | Workflow-Automatisierung | - -#### WSL-Konfiguration -- NGINX Proxy Manager läuft in WSL -- IP-Adresse des WSL-Systems: 172.23.171.133 (Beispiel, kann sich ändern) -- Alle Docker-Container werden innerhalb von WSL betrieben - -#### `setup_realm.js` -Dieses Skript wird verwendet, um den Keycloak-Realm, die zugehörigen Clients und Testbenutzer automatisiert zu erstellen. Es verwendet eine `.env`-Datei zur Konfiguration. - -#### Verwendung von .env -Die Konfigurationen für das setup_realm.js Script werden in einer .env Datei gespeichert. Die benötigten Umgebungsvariablen sind unten aufgelistet: -- `KEYCLOAK_URL`: Die URL zum Keycloak Server (z.B. https://auth.mrx8086.com) -- `KEYCLOAK_ADMIN_USER`: Der Benutzername des Keycloak Administrators (z.B. admin). -- `KEYCLOAK_ADMIN_PASSWORD`: Das Passwort des Keycloak Administrators. -- `NEXTCLOUD_CLIENT_ID`: Die Client ID für Nextcloud. (z.B. nextcloud) -- `PAPERLESS_CLIENT_ID`: Die Client ID für Paperless (z.B. paperless). -- `NODERED_CLIENT_ID`: Die Client ID für Node-RED (z.B. nodered). -- `TESTADMIN_PASSWORD`: Das Passwort für den Testadmin User. -- `TESTUSER_PASSWORD`: Das Passwort für den Testuser User. -- `TESTSERVICEUSER_PASSWORD`: Das Passwort für den Testserviceuser User. -- `KEYCLOAK_NEXTCLOUD_CLIENT_SECRET`: Das Client Secret für Nextcloud. -- `NEXTCLOUD_URL`: Die URL zur Nextcloud Instanz (z.B. https://cloud.mrx8086.com). - -#### NGINX-Konfigurationen -Für jeden Service existiert eine dedizierte NGINX-Konfiguration. In der Development Umgebung wird der **NGINX Proxy Manager** verwendet. Für **Staging** und **Production** werden die entsprechenden NGINX Konfigurationsdateien in `/config/nginx` abgelegt. - -## Konfigurationen - -### Netzwerkkonfiguration -- Interne Netzwerkstruktur (noch zu definieren) -- Reverse Proxy Konfiguration über den Nginx Proxy Manager in der Development Umgebung, und Nginx Server Config in Staging und Production. -- SSL/TLS-Setup: Selbsignierte Zertifikate in der Development Umgebung, Letsencrypt in Staging und Production. -- Konfigurationsdateien für NGINX Server Config sind unter `/config/nginx/sites-available/` zu finden. -- Für die Entwicklungsumgebung werden die Konfigurationen über den Nginx Proxy Manager konfiguriert. -- Die SSL Zertifikate für die Development Umgebung werden als selbsignierte Zertifikate generiert und in `/config/nginx/ssl/mrx8086.com/` abgelegt. -- In der Staging und Production Umgebung werden die Zertifikate über Let's Encrypt oder eine andere Zertifizierungsstelle verwaltet. - -#### Umgebungsvariablen -Es werden zwei `.env`-Dateien verwendet: -Eine im `docker/` Verzeichnis für die Docker-Konfiguration und eine im `scripts/setup/keycloak/` für das `setup_realm.js`-Skript. - -**`docker/.env`:** -```env -# Generated on 2024-12-12_18-12-36 -# Keycloak Admin -KEYCLOAK_ADMIN_PASSWORD=9aD5Fddh457QqmvQqr6Rb8bu - -# Keycloak Database -KC_DB_USERNAME=keycloak -KC_DB_PASSWORD=p47616y763z101f3 -``` - -**`scripts/setup/keycloak/.env`:** -```env -KEYCLOAK_URL=https://auth.mrx8086.com -KEYCLOAK_ADMIN_USER=admin -KEYCLOAK_ADMIN_PASSWORD=9aD5Fddh457QqmvQqr6Rb8bu -NEXTCLOUD_CLIENT_ID=nextcloud -PAPERLESS_CLIENT_ID=paperless -NODERED_CLIENT_ID=nodered -TESTADMIN_PASSWORD=TestAdminPwd -TESTUSER_PASSWORD=TestUserPwd -TESTSERVICEUSER_PASSWORD=TestServiceUserPwd -KEYCLOAK_NEXTCLOUD_CLIENT_SECRET=OSbJ08zyjBWChwBR7S6c1q4sU0d8zvEK -NEXTCLOUD_URL=https://cloud.mrx8086.com -``` - -Die Passwörter in der `.env` Datei im `scripts/setup/keycloak` werden vom `setup_environment.sh` Skript generiert. - -#### Keycloak-Konfiguration - -Keycloak ist als zentrale Authentifizierungsstelle konfiguriert. Die Realm-Konfiguration, Clients und Benutzer werden über das `setup_realm.js` Skript definiert, die Konfiguration wird über die `.env` Datei im `/scripts/setup/keycloak` Verzeichnis angepasst. - -##### Realm-Konfiguration -- **Realm-Name:** `office-automation` -- **Anzeige Name:** `Office Automation` -- **SSL ist erforderlich**: `external` -- **Registrierung ist nicht erlaubt**: `false` -- **Login mit Email ist erlaubt**: `true` -- **Doppelte Email ist nicht erlaubt**: `false` -- **Passwort Reset ist erlaubt**: `true` -- **Username Bearbeitung ist nicht erlaubt**: `false` -- **Brute Force Schutz ist aktiviert**: `true` -- **Permanente Sperrung ist nicht aktiviert**: `false` -- **Standard Signature Algorithm**: `RS256` -- **WebAuthn Policy Signatur Algorithmen**: `ES256` -- **WebAuthn Policy Attestation Conveyance Preference**: `none` -- **WebAuthn Policy Authenticator Attachment**: `cross-platform` -- **WebAuthn Policy Require Resident Key**: `not specified` -- **WebAuthn Policy User Verification Requirement**: `preferred` -- **WebAuthn Policy Create Timeout**: `0` -- **WebAuthn Policy Avoid Same Authenticator Register**: `false` -- **Default Default Client Scopes**: `email`, `profile`, `roles`, `web-origins` -- **Default Optional Client Scopes**: `address`, `phone`, `offline_access`, `microprofile-jwt` - -##### Clients -Die folgenden Clients werden über das Skript konfiguriert: -- **Nextcloud:** - - **Client ID:** `nextcloud` - - **Name:** `Nextcloud` - - **Redirect URIs:** - - `https://cloud.mrx8086.com/apps/sociallogin/custom_oidc/keycloak` - - `https://cloud.mrx8086.com/apps/user_oidc/code` - - **Post Logout Redirect URIs:** `https://cloud.mrx8086.com/*` -- **Paperless:** - - **Client ID:** `paperless` - - **Name:** `Paperless` - - **Redirect URIs:** `https://docs.mrx8086.com/*` -- **Node-RED:** - - **Client ID:** `nodered` - - **Name:** `Node-RED` - - **Redirect URIs:** `https://automate.mrx8086.com/*` - -##### Gruppen -- **nextcloud-admins:** Gruppe für Nextcloud Benutzer mit Admin Rechten. -- **nextcloud-users:** Gruppe für reguläre Nextcloud Benutzer. -- **nextcloud-youpi:** Gruppe für Nextcloud Youpi Benutzer. -- **nextcloud-service:** Gruppe für Nextcloud Service Benutzer. - -##### Benutzer -- **testadmin:** - - Benutzername: `testadmin` - - Passwort: wird entweder aus der Umgebungsvariable `TESTADMIN_PASSWORD` gelesen oder standardmäßig `initial123!` gesetzt. - - Gruppen: `nextcloud-admins`,`nextcloud-users` -- **testuser:** - - Benutzername: `testuser` - - Passwort: wird entweder aus der Umgebungsvariable `TESTUSER_PASSWORD` gelesen oder standardmäßig `initial123!` gesetzt. - - Gruppen: `nextcloud-users`,`nextcloud-youpi` -- **testserviceuser:** - - Benutzername: `testserviceuser` - - Passwort: wird entweder aus der Umgebungsvariable `TESTSERVICEUSER_PASSWORD` gelesen oder standardmäßig `initial123!` gesetzt. - - Gruppen: `nextcloud-service` - -#### SSL/TLS-Setup -- **Entwicklungsumgebung (`dev`):** Für lokale Entwicklung werden selbsignierte SSL-Zertifikate verwendet. -- **Staging/Produktionsumgebung (`staging`, `production`):** Hier werden SSL-Zertifikate über Let's Encrypt oder eine ähnliche Zertifizierungsstelle verwaltet. - -## Installationsanleitung -#### Voraussetzungen -- Docker Version: `[VERSION]` -- Minimal Systemanforderungen: - - CPU: `[ANFORDERUNG]` - - RAM: `[ANFORDERUNG]` - - Speicher: `[ANFORDERUNG]` -- Für die Ausführung des `setup_realm.js` Skriptes wird `Node.js` benötigt -- Die genaue Version von `Node.js` wird zu einem späteren Zeitpunkt dokumentiert. -- Vor dem starten müssen die Passwörter generiert und die `.env` Dateien erstellt werden. Hierzu wird das `setup_environment.sh` verwendet. Dieses Skript sollte **nicht in der Produktionsumgebung** verwendet werden. -- Das Skript erstellt die benötigten Verzeichnisse, generiert zufällige Passwörter, speichert diese verschlüsselt ab, und erstellt die benötigten `.env` Dateien. -- Für die Ausführung des `setup_realm.js` Skriptes wird `Node.js` und `npm` benötigt -- Die benötigten Node Module `dotenv` und `axios` können mit `npm install dotenv axios` installiert werden. -- Die `.env` Dateien werden im `/docker` und im `/scripts/setup/keycloak` Verzeichnis abgelegt. - -#### Keycloak-Installation -1. Führe das `setup_environment.sh` Skript aus, um die .env Dateien, die Passwörter zu generieren und die Credentials zu verschlüsseln. -2. Kopiere die `docker-compose.yml` Datei in das `docker/` Verzeichnis. -3. Kopiere die `.env` Datei in das `docker/` Verzeichnis. -4. Führe `docker-compose up -d` im `docker/` Verzeichnis aus um Keycloak zu starten. - -#### Ausführen von `setup_realm.js` -1. Stelle sicher, dass Node.js und npm installiert sind. -2. Wechsle in das `/scripts/setup/keycloak` Verzeichnis. -3. Installiere die benötigten npm Pakete mit `npm install dotenv axios`. -4. Führe das Skript mit `node setup_realm.js` aus. Dies erstellt den Keycloak-Realm, die Clients und die Testbenutzer. - * Das Script befindet sich im `/scripts/setup/keycloak` Verzeichnis - -## Workflows -#### Dokumentenverarbeitung -- Eingangsverarbeitung -- OCR-Prozess -- Kategorisierung -- Archivierung - -#### Geschäftsprozesse -- Rechnungsstellung -- Zahlungsabwicklung -- Kundenmanagement -- Zeiterfassung - -#### Authentifizierungsflow -Die Authentifizierung der Benutzer für alle Dienste wird über Keycloak abgewickelt. Details zu den Authentifizierungsabläufen werden in einem späteren Schritt dokumentiert. - -## Sicherheitskonzept -#### Zugriffsmanagement -- Rollenkonzept (wird in späteren schritten dokumentiert) -- Berechtigungsmatrix (wird in späteren schritten dokumentiert) -- Authentifizierungsflows (siehe Workflows) -- Keycloak wird als zentrale Authentifizierungsstelle verwendet, Passwortrichtlinien werden in Keycloak definiert. - -#### Datensicherheit -- Verschlüsselung (wird in späteren schritten dokumentiert) -- Backup-Strategie (wird in späteren schritten dokumentiert) -- Notfallwiederherstellung (wird in späteren schritten dokumentiert) - -## Wartung und Monitoring -#### Regelmäßige Wartungsaufgaben -- Backup-Überprüfung -- Updates -- Performance-Monitoring - -Details zur Wartung und dem Monitoring werden in späteren Schritten dokumentiert. - -## Troubleshooting -#### Bekannte Probleme -- [Wird ergänzt mit auftretenden Problemen] - -#### Debugging -- Log-Analyse -- Fehlerbehandlung -- Support-Prozesse -Details zu bekannten Problemen und zur Fehlerbehandlung werden in späteren Schritten dokumentiert. -``` -```markdown -# Automated Office 2.0 - Current Project State - -## Overview -Project to automate all administrative and commercial processes within the company, using open-source solutions. - -## Current Implementation Status - -### 1. Project Structure -- Basic directory structure created -- Ansible roles established (common, docker, nginx, services) -- Configuration directories set up for all services -- Documentation structure established - -### 2. Environment Setup -- Development environment using WSL -- NGINX running in WSL for development using NGINX Proxy Manager -- Docker environment being set up -- SSL certificates in place for development (self-signed) -- Staging and Production environment will use NGINX Server Configs and letsencrypt SSL certificates - -### 3. Service Status - -#### Keycloak (auth.mrx8086.com) -- NGINX configuration complete -- Docker setup complete -- Keycloak is running behind a reverse proxy -- Implemented setup_realm.js script for automated realm, client and user setup -- SSL certificates configured (self-signed) -- `setup_realm.js` configures the `office-automation` realm, `nextcloud`, `paperless`, and `nodered` clients. -- Test users `testadmin`, `testuser` and `testserviceuser` are also created. -- Client Scopes for `openid`, `profile` and `groups-nextcloud` are added to the nextcloud client. -- Groups `nextcloud-admins`, `nextcloud-users`, `nextcloud-youpi` and `nextcloud-service` are created. - -#### Nextcloud (cloud.mrx8086.com) -- NGINX configuration complete -- Docker setup complete -- SSL certificates configured -- Nextcloud is configured to use Keycloak for authentication - -#### Paperless (docs.mrx8086.com) -- NGINX configuration complete -- Docker setup pending -- SSL certificates configured - -#### Node-RED (automate.mrx8086.com) -- NGINX configuration complete -- Docker setup pending -- SSL certificates configured -- Chosen over n8n for better open-source compatibility - -### 4. Security -- Automated password generation implemented -- Encrypted credentials storage system in place -- SSL certificates managed and deployed - -### 5. Development Decisions -- Using WSL for development environment -- NGINX running directly in WSL for development -- Docker containers for all services -- Focusing on completely open-source solutions -- Development environment uses Nginx Proxy Manager -- Staging and Production will use Nginx Server Config files - -## Next Steps -1. Complete Paperless and Node-RED docker setup -2. Test Paperless and Node-RED authentication against Keycloak -3. Proceed with remaining service deployments -4. Setup Letsencrypt SSL Certificates in the Staging Environment - -## Important Files Location -- NGINX configs: /config/nginx/sites-available/ -- SSL certificates: /config/nginx/ssl/mrx8086.com/ -- Docker compose: /docker/docker-compose.yml -- Environment variables: /config/.env -- Encrypted credentials: /config/credentials/ -- Keycloak setup script: /scripts/install/setup_realm.js - -## Development Environment -- Domain: mrx8086.com -- SSL certificates in place (self-signed) -- NGINX running in WSL -- Docker running in WSL -``` -```markdown -# Ansible Setup Documentation - -## Overview -Ansible wird für das automatisierte Deployment des Automated Office Systems verwendet. - -## Roles Structure - -### Common Role -- Basis-Systemkonfiguration -- Sicherheitseinstellungen (fail2ban, UFW) -- Grundlegende Systempakete - -```yaml -# Standardvariablen -timezone: "Europe/Berlin" -fail2ban_bantime: 600 -fail2ban_findtime: 600 -fail2ban_maxretry: 3 -``` - -### Docker Role -- Docker Installation und Konfiguration -- Docker Compose Setup -- Docker Netzwerk-Konfiguration - -```yaml -# Docker Standardvariablen -docker_version: "latest" -docker_compose_version: "2.21.0" -docker_users: ["{{ ansible_user }}"] -``` - -### NGINX Role -- NGINX Installation -- SSL/TLS Setup -- Virtual Host Konfiguration - -```yaml -# NGINX Standardvariablen -nginx_worker_processes: auto -nginx_worker_connections: 1024 -nginx_client_max_body_size: "100M" -``` - -### Services Role -- Deployment der Docker-Container -- Service-spezifische Konfigurationen -- Datenpersistenz-Setup - -## Inventory Structure -```plaintext -inventory/ -├── production/ -└── staging/ - └── hosts -``` - -## Variables -```yaml -# vars/defaults/main.yml -base_domain: "example.com" -ssl_email: "admin@example.com" - -services: - keycloak: true - nextcloud: true - paperless: true - nodered: true -``` -```yaml -# ansible/roles/common/defaults/main.yml ---- -# System -timezone: "Europe/Berlin" - -# Security -fail2ban_bantime: 600 -fail2ban_findtime: 600 -fail2ban_maxretry: 3 - -# Firewall ports to open -ufw_allowed_ports: - - { port: 22, proto: tcp } # SSH - - { port: 80, proto: tcp } # HTTP - - { port: 443, proto: tcp } # HTTPS -``` -```yaml -# ansible/roles/docker/defaults/main.yml ---- -# Docker Standardvariablen -docker_version: "latest" -docker_compose_version: "2.21.0" -docker_users: ["{{ ansible_user }}"] -``` -```yaml -# ansible/roles/nginx/defaults/main.yml ---- -# NGINX Standardvariablen -nginx_worker_processes: auto -nginx_worker_connections: 1024 -nginx_client_max_body_size: "100M" -``` -```yaml -# ansible/vars/defaults/main.yml ---- -# Domain-Konfiguration -base_domain: "example.com" -ssl_email: "admin@example.com" - -# Aktivierte Services -services: - keycloak: true - nextcloud: true - paperless: true - nodered: true - -# Ports -keycloak_port: 8080 -nextcloud_port: 8081 -paperless_port: 8000 -nodered_port: 1880 - -# Docker-Konfiguration -docker_compose_version: "2.21.0" -``` -## Deployment Flow -1. Common Role: Systemvorbereitung -2. Docker Role: Container-Runtime -3. NGINX Role: Reverse Proxy -4. Services Role: Anwendungen - -## Wichtige Befehle -```bash -# Staging Deployment -ansible-playbook -i inventory/staging site.yml - -# Production Deployment -ansible-playbook -i inventory/production site.yml -``` - -## Sicherheitsaspekte -- Automatische Passwortverwaltung -- SSL/TLS-Konfiguration -- Firewall-Einstellungen -- Fail2ban-Integration - -## Entwicklungshinweise -- Lokales Testing über WSL -- Staging-Umgebung für Tests -- Produktionsumgebung für finale Deployments - -## Updates und Wartung -- Regelmäßige Updates über Ansible -- Backup-Integration -- Monitoring-Setup -``` -```bash -#!/bin/bash -set -e - -# Ensure we're in the project root directory -PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" - -# Define directories relative to project root -CREDENTIALS_DIR="${PROJECT_ROOT}/config/credentials" -DOCKER_DIR="${PROJECT_ROOT}/docker" -KEYCLOAK_SETUP_DIR="${PROJECT_ROOT}/scripts/setup/keycloak" -ANSIBLE_PLAYBOOK="${PROJECT_ROOT}/ansible/site.yml" -ANSIBLE_INVENTORY="${PROJECT_ROOT}/ansible/inventory/staging/hosts" -NEXTCLOUD_DATA_DIR="${PROJECT_ROOT}/data/nextcloud/data" -TEMP_FILE=$(mktemp) -KEYCLOAK_DB_DIR="${PROJECT_ROOT}/data/keycloak-db" - -# Create necessary directories -sudo mkdir -p "${CREDENTIALS_DIR}" -sudo mkdir -p "${DOCKER_DIR}" -sudo mkdir -p "${KEYCLOAK_SETUP_DIR}" - -# Initialize password variables -KEYCLOAK_ADMIN_PASSWORD="" -KC_DB_PASSWORD="" -TESTADMIN_PASSWORD="" -TESTUSER_PASSWORD="" -TESTSERVICEUSER_PASSWORD="" -KEYCLOAK_NEXTCLOUD_CLIENT_SECRET="" - -# Function to read a password from a .env file -read_password_from_env() { - local env_file="$1" - local variable_name="$2" - if [ -f "$env_file" ]; then - grep "^${variable_name}=" "$env_file" | cut -d '=' -f2 - fi -} - -# Function to generate secure passwords -generate_password() { - openssl rand -base64 32 -} - -# Function to generate password if empty -generate_password_if_empty() { - local variable_name="$1" - eval "local value=\$$variable_name" - if [ -z "$value" ]; then - eval "$variable_name=\"$(generate_password)\"" - echo ">>> Generiertes Passwort für: $variable_name" - fi -} - -# Function to create .env file -create_env_file() { - local env_file="$1" - local content="$2" - if [ ! -f "$env_file" ]; then - echo "$content" > "$env_file" - echo ">>> .env file created: $env_file" - else - echo ">>> .env file already exists: $env_file" - fi -} - -echo ">>> Überprüfe bestehende .env Dateien und lese Passwörter..." - -# Try reading passwords from existing .env files -if [ -f "$DOCKER_DIR/.env" ]; then - KC_DB_PASSWORD=$(read_password_from_env "$DOCKER_DIR/.env" "KC_DB_PASSWORD") - KEYCLOAK_ADMIN_PASSWORD=$(read_password_from_env "$DOCKER_DIR/.env" "KEYCLOAK_ADMIN_PASSWORD") -fi - -if [ -f "$KEYCLOAK_SETUP_DIR/.env" ]; then - KEYCLOAK_ADMIN_PASSWORD=$(read_password_from_env "$KEYCLOAK_SETUP_DIR/.env" "KEYCLOAK_ADMIN_PASSWORD") # Überschreibt ggf. den Wert aus docker/.env - TESTADMIN_PASSWORD=$(read_password_from_env "$KEYCLOAK_SETUP_DIR/.env" "TESTADMIN_PASSWORD") - TESTUSER_PASSWORD=$(read_password_from_env "$KEYCLOAK_SETUP_DIR/.env" "TESTUSER_PASSWORD") - TESTSERVICEUSER_PASSWORD=$(read_password_from_env "$KEYCLOAK_SETUP_DIR/.env" "TESTSERVICEUSER_PASSWORD") - KEYCLOAK_NEXTCLOUD_CLIENT_SECRET=$(read_password_from_env "$KEYCLOAK_SETUP_DIR/.env" "KEYCLOAK_NEXTCLOUD_CLIENT_SECRET") -fi - -echo ">>> Generiere neue Passwörter für fehlende Werte..." - -# Generate passwords if they are still empty -generate_password_if_empty KEYCLOAK_ADMIN_PASSWORD -generate_password_if_empty KC_DB_PASSWORD -generate_password_if_empty TESTADMIN_PASSWORD -generate_password_if_empty TESTUSER_PASSWORD -generate_password_if_empty TESTSERVICEUSER_PASSWORD -generate_password_if_empty KEYCLOAK_NEXTCLOUD_CLIENT_SECRET - -# Date for documentation -SETUP_DATE=$(date '+%Y-%m-%d_%H-%M-%S') - -# Create credentials content -CREDENTIALS_CONTENT=$(cat < "${CREDENTIALS_DIR}/credentials_hash.txt" -echo ">>> Credentials hash stored in: ${CREDENTIALS_DIR}/credentials_hash.txt" - -# Set GPG PASSPHRASE -export GPG_PASSPHRASE=$(generate_password) -# Set GPG agent environment variable -export GPG_TTY=$(tty) - -echo ">>> Trying openssl encryption first" -# Alternative Verschlüsselung mit Openssl -echo "$CREDENTIALS_CONTENT" > "$TEMP_FILE" - if openssl enc -aes-256-cbc -pbkdf2 -salt -in "$TEMP_FILE" -out "${CREDENTIALS_DIR}/credentials_${SETUP_DATE}.txt.enc" -k "$GPG_PASSPHRASE" ; then - echo ">>> Credentials encrypted successfully using openssl" - mv "${CREDENTIALS_DIR}/credentials_${SETUP_DATE}.txt.enc" "${CREDENTIALS_DIR}/credentials_${SETUP_DATE}.txt.gpg" - else - echo ">>> Openssl encryption failed, trying gpg" - - # Attempt to kill existing gpg agent - gpgconf --kill gpg-agent 2>/dev/null - echo ">>> Attempting to manually start gpg-agent with pinentry-curses" - gpg-agent --daemon --pinentry-program /usr/bin/pinentry-curses - gpg-connect-agent /bye 2>/dev/null - eval $(gpg-agent --daemon) - gpg-connect-agent updatestartuptty /bye 2>/dev/null - - # Attempt to encrypt credentials using GPG with error handling - if echo "$CREDENTIALS_CONTENT" | gpg --symmetric --cipher-algo AES256 -vvv -o "${CREDENTIALS_DIR}/credentials_${SETUP_DATE}.txt.gpg" ; then - echo ">>> Credentials encrypted successfully using gpg." - else - echo - - - - - - - ``` \ No newline at end of file