From bf4043004b1c82cca27f112788a0fb58d6f4042f Mon Sep 17 00:00:00 2001 From: hans Date: Wed, 12 Mar 2025 15:01:18 +0100 Subject: [PATCH] in development funktionieren Steckdosen, Prod: baseURL fehler --- angular.json | 3 + apacheconfs/cors.conf | 30 ++++ apacheconfs/httpd24.conf | 143 ++++++++++++++++++ apacheconfs/virtual-host.conf | 35 +++++ proxy.conf.json | 18 +++ .../tasmota-control.component.ts | 8 +- src/app/tasmota.service.ts | 45 +++--- src/environments/environment.prod.ts | 5 + src/environments/environment.ts | 6 + 9 files changed, 272 insertions(+), 21 deletions(-) create mode 100644 apacheconfs/cors.conf create mode 100644 apacheconfs/httpd24.conf create mode 100644 apacheconfs/virtual-host.conf create mode 100644 proxy.conf.json create mode 100644 src/environments/environment.prod.ts create mode 100644 src/environments/environment.ts diff --git a/angular.json b/angular.json index 697df9c..dd7ecca 100644 --- a/angular.json +++ b/angular.json @@ -67,6 +67,9 @@ "defaultConfiguration": "production" }, "serve": { + "options": { + "proxyConfig": "proxy.conf.json" + }, "builder": "@angular-devkit/build-angular:dev-server", "configurations": { "production": { diff --git a/apacheconfs/cors.conf b/apacheconfs/cors.conf new file mode 100644 index 0000000..7336ba4 --- /dev/null +++ b/apacheconfs/cors.conf @@ -0,0 +1,30 @@ + + # Globale CORS-Einstellungen + Header always set Access-Control-Allow-Origin "*" + Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS" + Header always set Access-Control-Allow-Headers "Origin, Content-Type, Accept, Authorization" + + # OPTIONS Requests behandeln + RewriteEngine On + RewriteCond %{REQUEST_METHOD} OPTIONS + RewriteRule ^(.*)$ $1 [R=200,L] + + +# Spezifische Konfiguration für Tasmota-Endpoints + + ProxyPass "http://10.0.0.31" + ProxyPassReverse "http://10.0.0.31" + + Header always set Access-Control-Allow-Origin "*" + Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS" + Header always set Access-Control-Allow-Headers "Origin, Content-Type, Accept, Authorization" + + + + ProxyPass "http://10.0.0.32" + ProxyPassReverse "http://10.0.0.32" + + Header always set Access-Control-Allow-Origin "*" + Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS" + Header always set Access-Control-Allow-Headers "Origin, Content-Type, Accept, Authorization" + diff --git a/apacheconfs/httpd24.conf b/apacheconfs/httpd24.conf new file mode 100644 index 0000000..8d124c7 --- /dev/null +++ b/apacheconfs/httpd24.conf @@ -0,0 +1,143 @@ +ServerRoot "/usr/local/etc/apache24" + +Listen 127.0.0.1:915 + +LoadModule authn_core_module modules/mod_authn_core.so +LoadModule authn_file_module modules/mod_authn_file.so +LoadModule authz_core_module modules/mod_authz_core.so +LoadModule authz_host_module modules/mod_authz_host.so +LoadModule authz_groupfile_module modules/mod_authz_groupfile.so +LoadModule authz_user_module modules/mod_authz_user.so +LoadModule authz_owner_module modules/mod_authz_owner.so +LoadModule auth_basic_module modules/mod_auth_basic.so +LoadModule auth_digest_module modules/mod_auth_digest.so +LoadModule include_module modules/mod_include.so +LoadModule filter_module modules/mod_filter.so +LoadModule deflate_module modules/mod_deflate.so +LoadModule log_config_module modules/mod_log_config.so +#LoadModule logio_module modules/mod_logio.so +LoadModule env_module modules/mod_env.so +LoadModule mime_magic_module modules/mod_mime_magic.so +LoadModule headers_module modules/mod_headers.so +LoadModule setenvif_module modules/mod_setenvif.so +LoadModule mime_module modules/mod_mime.so +LoadModule status_module modules/mod_status.so +LoadModule autoindex_module modules/mod_autoindex.so +LoadModule asis_module modules/mod_asis.so +LoadModule cgid_module modules/mod_cgid.so +LoadModule negotiation_module modules/mod_negotiation.so +LoadModule dir_module modules/mod_dir.so +LoadModule actions_module modules/mod_actions.so +LoadModule alias_module modules/mod_alias.so +LoadModule rewrite_module modules/mod_rewrite.so +LoadModule proxy_module modules/mod_proxy.so +LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so +LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so +LoadModule unixd_module modules/mod_unixd.so + + + User http + Group http + + +ErrorLog /run/apache24-error_log +TraceEnable off +LogLevel error + + + LogFormat "%{X-Real-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined + LogFormat "%{X-Real-IP}i %l %u %t \"%r\" %>s %b" common + + + LogFormat "%{X-Real-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio + + + CustomLog /dev/null combined + #CustomLog /run/apache24-access_log combined + + + + ScriptSock /run/httpd/user-cgisock + + + + TypesConfig conf/mime.types + AddEncoding x-compress Z + AddEncoding x-gzip gz tgz + AddType application/x-compress .Z + AddType application/x-gzip .gz .tgz + AddType image/x-icon .ico + AddHandler cgi-script .cgi + + +MIMEMagicFile conf/magic +EnableMMAP off + +# TODO: AllowOverride of root directory to All ?? + + Options FollowSymLinks + AllowOverride All + + +# TODO: should apache handle this or nginx? + + DeflateCompressionLevel 2 + AddOutputFilterByType DEFLATE text/html text/plain text/xml + AddOutputFilter DEFLATE js css + BrowserMatch ^Mozilla/4 gzip-only-text/html + BrowserMatch ^Mozilla/4\.[0678] no-gzip + BrowserMatch \bMSIE\s7 !no-gzip !gzip-only-text/html + + +# TODO: should apache handle this or nginx + + + Require all denied + + + + + DocumentRoot "/var/services/web" + Header always set Access-Control-Allow-Origin "*" + Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS" + Header always set Access-Control-Allow-Headers "Origin, Content-Type, Accept, Authorization" + + # Tasmota Proxy Konfiguration + ProxyRequests Off + ProxyPreserveHost On + + + ProxyPass "http://10.0.0.31" + ProxyPassReverse "http://10.0.0.31" + + Header always set Access-Control-Allow-Origin "*" + Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS" + Header always set Access-Control-Allow-Headers "Origin, Content-Type, Accept, Authorization" + + + + ProxyPass "http://10.0.0.32" + ProxyPassReverse "http://10.0.0.32" + + Header always set Access-Control-Allow-Origin "*" + Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS" + Header always set Access-Control-Allow-Headers "Origin, Content-Type, Accept, Authorization" + + + # Logging + ErrorLog /var/log/apache2/error.log + CustomLog /var/log/apache2/access.log combined + IncludeOptional conf-enabled/alias.*.conf + + +# TODO: Should apapche handle FileETag +# For CVE-2003-1418 +FileETag MTime Size + +Include conf/extra/httpd-mpm.conf +Include conf/extra/httpd-autoindex.conf +Include conf/extra/httpd-languages.conf +Include conf/extra/mod_xsendfile.conf +Include conf/extra/mod_rpaf.conf + +IncludeOptional sites-enabled/*.conf diff --git a/apacheconfs/virtual-host.conf b/apacheconfs/virtual-host.conf new file mode 100644 index 0000000..74ef711 --- /dev/null +++ b/apacheconfs/virtual-host.conf @@ -0,0 +1,35 @@ + + ServerName your-nas-domain.com + DocumentRoot "/var/services/web/" + + # CORS Headers + Header always set Access-Control-Allow-Origin "*" + Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS" + Header always set Access-Control-Allow-Headers "Origin, Content-Type, Accept, Authorization" + + # Tasmota Proxy Konfiguration + ProxyRequests Off + ProxyPreserveHost On + + + ProxyPass "http://10.0.0.31" + ProxyPassReverse "http://10.0.0.31" + + Header always set Access-Control-Allow-Origin "*" + Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS" + Header always set Access-Control-Allow-Headers "Origin, Content-Type, Accept, Authorization" + + + + ProxyPass "http://10.0.0.32" + ProxyPassReverse "http://10.0.0.32" + + Header always set Access-Control-Allow-Origin "*" + Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS" + Header always set Access-Control-Allow-Headers "Origin, Content-Type, Accept, Authorization" + + + # Logging + ErrorLog /var/log/apache2/error.log + CustomLog /var/log/apache2/access.log combined + diff --git a/proxy.conf.json b/proxy.conf.json new file mode 100644 index 0000000..9efe69e --- /dev/null +++ b/proxy.conf.json @@ -0,0 +1,18 @@ +{ + "/tasmota1": { + "target": "http://10.0.0.31", + "secure": false, + "changeOrigin": true, + "pathRewrite": { + "^/tasmota1": "" + } + }, + "/tasmota2": { + "target": "http://10.0.0.32", + "secure": false, + "changeOrigin": true, + "pathRewrite": { + "^/tasmota2": "" + } + } +} diff --git a/src/app/tasmota-control/tasmota-control.component.ts b/src/app/tasmota-control/tasmota-control.component.ts index 0e731fd..37f4802 100644 --- a/src/app/tasmota-control/tasmota-control.component.ts +++ b/src/app/tasmota-control/tasmota-control.component.ts @@ -18,13 +18,13 @@ export class TasmotaControlComponent implements OnInit { } updateSocketStatuses(): void { - this.tasmotaService.getSocketStatus(this.tasmotaService.socket1IP) + this.tasmotaService.getSocketStatus(this.tasmotaService.socket1Path) .subscribe({ next: (status) => this.socket1Status = status, error: (error) => console.error('Fehler beim Abrufen des Status von Steckdose 1:', error) }); - this.tasmotaService.getSocketStatus(this.tasmotaService.socket2IP) + this.tasmotaService.getSocketStatus(this.tasmotaService.socket2Path) .subscribe({ next: (status) => this.socket2Status = status, error: (error) => console.error('Fehler beim Abrufen des Status von Steckdose 2:', error) @@ -32,7 +32,7 @@ export class TasmotaControlComponent implements OnInit { } toggleSocket1(): void { - this.tasmotaService.toggleSocket(this.tasmotaService.socket1IP, this.socket1Status) + this.tasmotaService.toggleSocket(this.tasmotaService.socket1Path, this.socket1Status) .subscribe({ next: (status) => this.socket1Status = status, error: (error) => console.error('Fehler beim Schalten von Steckdose 1:', error) @@ -40,7 +40,7 @@ export class TasmotaControlComponent implements OnInit { } toggleSocket2(): void { - this.tasmotaService.toggleSocket(this.tasmotaService.socket2IP, this.socket2Status) + this.tasmotaService.toggleSocket(this.tasmotaService.socket2Path, this.socket2Status) .subscribe({ next: (status) => this.socket2Status = status, error: (error) => console.error('Fehler beim Schalten von Steckdose 2:', error) diff --git a/src/app/tasmota.service.ts b/src/app/tasmota.service.ts index c12223e..1fedd34 100644 --- a/src/app/tasmota.service.ts +++ b/src/app/tasmota.service.ts @@ -1,39 +1,50 @@ // tasmota.service.ts import { Injectable } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; +import { environment } from '../environments/environment'; @Injectable({ providedIn: 'root' }) export class TasmotaService { - private SOCKET1_IP = '10.0.0.31'; // Ändere zu deiner ersten Tasmota IP - private SOCKET2_IP = '10.0.0.32'; // Ändere zu deiner zweiten Tasmota IP + private baseUrl = environment.production + ? '' + : ''; + + private SOCKET1_PATH = this.baseUrl + '/tasmota1'; + private SOCKET2_PATH = this.baseUrl + '/tasmota2'; + + private httpOptions = { + headers: new HttpHeaders({ + 'Content-Type': 'application/json', + // Weitere Header falls nötig + }) + }; constructor(private http: HttpClient) { } - toggleSocket(socketIP: string, currentStatus: boolean): Observable { + getSocketStatus(socketPath: string): Observable { + return this.http.get(`${socketPath}/cm?cmnd=Power`, this.httpOptions) + .pipe( + map(response => response.POWER === 'ON') + ); + } + + toggleSocket(socketPath: string, currentStatus: boolean): Observable { const command = currentStatus ? 'Power%20Off' : 'Power%20On'; - return this.http.get(`http://${socketIP}/cm?cmnd=${command}`) + return this.http.get(`${socketPath}/cm?cmnd=${command}`, this.httpOptions) .pipe( map(response => response.POWER === 'ON') ); } - getSocketStatus(socketIP: string): Observable { - return this.http.get(`http://${socketIP}/cm?cmnd=Power`) - .pipe( - map(response => response.POWER === 'ON') - ); + get socket1Path(): string { + return this.SOCKET1_PATH; } - get socket1IP(): string { - return this.SOCKET1_IP; - } - - get socket2IP(): string { - return this.SOCKET2_IP; + get socket2Path(): string { + return this.SOCKET2_PATH; } } - diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts new file mode 100644 index 0000000..b5d3278 --- /dev/null +++ b/src/environments/environment.prod.ts @@ -0,0 +1,5 @@ +// environments/environment.prod.ts +export const environment = { + production: true, + apiUrl: '' // Produktions-URL (leer wenn gleicher Server) +}; diff --git a/src/environments/environment.ts b/src/environments/environment.ts new file mode 100644 index 0000000..1d19dd4 --- /dev/null +++ b/src/environments/environment.ts @@ -0,0 +1,6 @@ +// environments/environment.ts +export const environment = { + production: false, + apiUrl: 'http://localhost:4200' // Entwicklungs-URL +}; +