From 0deddeca5162f2f9bd0fb838c9fafe36b1599a93 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Thu, 8 Jan 2026 11:24:38 +0100 Subject: [PATCH] Enhance deployment script with PM2 process checks and error handling Update deploy-production.sh to include checks for PM2 installation and process existence before restarting. Implement error messages for failed starts and restarts, improving robustness and user guidance during deployment. Additionally, add useful commands for managing the PM2 process post-deployment. --- deploy-production.sh | 43 ++++++++++++++++++- .../auth/register-passkey-options.options.js | 32 ++++++++++++++ .../api/auth/register-passkey-options.post.js | 13 ++---- server/api/auth/register-passkey.options.js | 32 ++++++++++++++ server/api/auth/register-passkey.post.js | 13 +++--- 5 files changed, 115 insertions(+), 18 deletions(-) create mode 100644 server/api/auth/register-passkey-options.options.js create mode 100644 server/api/auth/register-passkey.options.js diff --git a/deploy-production.sh b/deploy-production.sh index a191235..ca8913d 100755 --- a/deploy-production.sh +++ b/deploy-production.sh @@ -311,9 +311,50 @@ echo "7. Keeping backups in $BACKUP_ROOT (no git stash used)." # 8. Restart PM2 echo "" echo "8. Restarting PM2..." -pm2 restart harheimertc + +# Prüfe, ob PM2 installiert ist +if ! command -v pm2 &> /dev/null; then + echo "ERROR: PM2 ist nicht installiert oder nicht im PATH!" + echo "Bitte installieren Sie PM2: npm install -g pm2" + exit 1 +fi + +# Prüfe, ob der Prozess existiert +if ! pm2 describe harheimertc &> /dev/null; then + echo "WARNING: PM2-Prozess 'harheimertc' existiert nicht." + echo "Versuche, den Prozess zu starten..." + pm2 start harheimertc.config.cjs || pm2 start harheimertc.simple.cjs || { + echo "ERROR: Konnte PM2-Prozess nicht starten." + echo "Bitte manuell starten: pm2 start harheimertc.config.cjs" + exit 1 + } + echo " ✓ PM2-Prozess gestartet" +else + # Restart mit --update-env, um Umgebungsvariablen zu aktualisieren + echo " Restarting harheimertc with --update-env..." + if pm2 restart harheimertc --update-env; then + echo " ✓ PM2-Prozess neu gestartet" + else + echo "ERROR: PM2-Restart fehlgeschlagen!" + echo "Bitte manuell prüfen: pm2 logs harheimertc" + exit 1 + fi +fi + +# Prüfe, ob der Prozess läuft +sleep 2 +if pm2 describe harheimertc | grep -q "online"; then + echo " ✓ PM2-Prozess läuft (online)" +else + echo "WARNING: PM2-Prozess ist nicht online. Prüfe Logs: pm2 logs harheimertc" +fi echo "" echo "=== Deployment completed successfully! ===" echo "The application is now running with the latest code and your production data preserved." +echo "" +echo "Useful commands:" +echo " pm2 logs harheimertc # View logs" +echo " pm2 status # View status" +echo " pm2 restart harheimertc # Restart manually" diff --git a/server/api/auth/register-passkey-options.options.js b/server/api/auth/register-passkey-options.options.js new file mode 100644 index 0000000..8f7615a --- /dev/null +++ b/server/api/auth/register-passkey-options.options.js @@ -0,0 +1,32 @@ +import { getWebAuthnConfig } from '../../utils/webauthn-config.js' + +export default defineEventHandler(async (event) => { + const requestOrigin = getHeader(event, 'origin') + const { origin: webauthnOrigin } = getWebAuthnConfig() + + console.log('[DEBUG] OPTIONS preflight request received', { + origin: requestOrigin, + webauthnOrigin, + timestamp: new Date().toISOString() + }) + + // CORS-Header für Cross-Device Authentication + const allowedOrigin = requestOrigin || webauthnOrigin + + if (allowedOrigin) { + setHeader(event, 'Access-Control-Allow-Origin', allowedOrigin) + setHeader(event, 'Access-Control-Allow-Credentials', 'true') + setHeader(event, 'Access-Control-Allow-Methods', 'GET, POST, OPTIONS') + setHeader(event, 'Access-Control-Allow-Headers', 'Content-Type, Authorization, Origin, X-Requested-With') + setHeader(event, 'Access-Control-Max-Age', '86400') // 24 Stunden Cache für Preflight + console.log('[DEBUG] CORS headers set for OPTIONS', { + origin: allowedOrigin, + requestOrigin, + webauthnOrigin + }) + } + + // OPTIONS Preflight-Request: 204 No Content + setResponseStatus(event, 204) + return null +}) diff --git a/server/api/auth/register-passkey-options.post.js b/server/api/auth/register-passkey-options.post.js index d160f75..92a8ed6 100644 --- a/server/api/auth/register-passkey-options.post.js +++ b/server/api/auth/register-passkey-options.post.js @@ -126,6 +126,7 @@ export default defineEventHandler(async (event) => { // CORS-Header für Cross-Device Authentication // WICHTIG: Für Cross-Device muss CORS korrekt konfiguriert sein + // OPTIONS-Requests werden von .options.js behandelt const allowedOrigin = requestOrigin || webauthnOrigin if (allowedOrigin) { @@ -134,21 +135,13 @@ export default defineEventHandler(async (event) => { setHeader(event, 'Access-Control-Allow-Methods', 'GET, POST, OPTIONS') setHeader(event, 'Access-Control-Allow-Headers', 'Content-Type, Authorization, Origin, X-Requested-With') setHeader(event, 'Access-Control-Max-Age', '86400') // 24 Stunden Cache für Preflight - console.log('[DEBUG] CORS headers set', { + console.log('[DEBUG] CORS headers set for POST', { origin: allowedOrigin, requestOrigin, - webauthnOrigin, - method: getMethod(event) + webauthnOrigin }) } - // OPTIONS Preflight-Request für Cross-Device - if (getMethod(event) === 'OPTIONS') { - console.log('[DEBUG] OPTIONS preflight request, returning 204') - setResponseStatus(event, 204) - return null - } - // Stelle sicher, dass die Options korrekt serialisiert werden const serializedOptions = { ...options, diff --git a/server/api/auth/register-passkey.options.js b/server/api/auth/register-passkey.options.js new file mode 100644 index 0000000..b394186 --- /dev/null +++ b/server/api/auth/register-passkey.options.js @@ -0,0 +1,32 @@ +import { getWebAuthnConfig } from '../../utils/webauthn-config.js' + +export default defineEventHandler(async (event) => { + const requestOrigin = getHeader(event, 'origin') + const { origin: webauthnOrigin } = getWebAuthnConfig() + + console.log('[DEBUG] OPTIONS preflight request received (register-passkey)', { + origin: requestOrigin, + webauthnOrigin, + timestamp: new Date().toISOString() + }) + + // CORS-Header für Cross-Device Authentication + const allowedOrigin = requestOrigin || webauthnOrigin + + if (allowedOrigin) { + setHeader(event, 'Access-Control-Allow-Origin', allowedOrigin) + setHeader(event, 'Access-Control-Allow-Credentials', 'true') + setHeader(event, 'Access-Control-Allow-Methods', 'POST, OPTIONS') + setHeader(event, 'Access-Control-Allow-Headers', 'Content-Type, Authorization, Origin, X-Requested-With') + setHeader(event, 'Access-Control-Max-Age', '86400') // 24 Stunden Cache für Preflight + console.log('[DEBUG] CORS headers set for OPTIONS', { + origin: allowedOrigin, + requestOrigin, + webauthnOrigin + }) + } + + // OPTIONS Preflight-Request: 204 No Content + setResponseStatus(event, 204) + return null +}) diff --git a/server/api/auth/register-passkey.post.js b/server/api/auth/register-passkey.post.js index c8e67a4..d3f75d5 100644 --- a/server/api/auth/register-passkey.post.js +++ b/server/api/auth/register-passkey.post.js @@ -20,19 +20,18 @@ export default defineEventHandler(async (event) => { }) // CORS-Header für Cross-Device Authentication + // OPTIONS-Requests werden von .options.js behandelt const allowedOrigin = requestOrigin || webauthnOrigin if (allowedOrigin) { setHeader(event, 'Access-Control-Allow-Origin', allowedOrigin) setHeader(event, 'Access-Control-Allow-Credentials', 'true') setHeader(event, 'Access-Control-Allow-Methods', 'POST, OPTIONS') setHeader(event, 'Access-Control-Allow-Headers', 'Content-Type, Authorization, Origin, X-Requested-With') - } - - // OPTIONS Preflight-Request - if (getMethod(event) === 'OPTIONS') { - console.log('[DEBUG] OPTIONS preflight request, returning 204') - setResponseStatus(event, 204) - return null + console.log('[DEBUG] CORS headers set for POST', { + origin: allowedOrigin, + requestOrigin, + webauthnOrigin + }) } const body = await readBody(event)