From 451a61d357d4310921e62dd889d30c9e169f4894 Mon Sep 17 00:00:00 2001 From: cpu Date: Fri, 28 Mar 2025 15:06:02 +0100 Subject: [PATCH] added auth so subscribe request --- labels.example | 19 +++++++++--- package.json | 28 ++++++++++++++++++ pushFlicIntegration.js | 65 +++++++++++++++++++++++++++++++++++++---- virt-game-timer.service | 30 +++++++++++++++++++ 4 files changed, 133 insertions(+), 9 deletions(-) create mode 100644 package.json create mode 100644 virt-game-timer.service diff --git a/labels.example b/labels.example index 33d3b67..22af919 100644 --- a/labels.example +++ b/labels.example @@ -1,13 +1,21 @@ +# Enable Traefik for this container traefik.enable=true + +# Docker Network traefik.docker.network=traefik + +# Route requests based on Host traefik.http.routers.game-timer.rule=Host(`game-timer.virtonline.eu`) -traefik.http.routers.game-timer.service=game-timer +# Specify the entrypoint ('websecure' for HTTPS) +traefik.http.routers.game-timer.entrypoints=web-secure traefik.http.routers.game-timer.tls=true traefik.http.routers.game-timer.tls.certResolver=default -traefik.http.routers.game-timer.entrypoints=web-secure +# Link the router to the service defined below +traefik.http.routers.game-timer.service=game-timer + +# Point the service to the container's port traefik.http.services.game-timer.loadbalancer.server.port=80 -traefik.http.routers.game-timer.middlewares=game-timer-auth # Declaring the user list # # Note: when used in docker-compose.yml all dollar signs in the hash need to be doubled for escaping. @@ -17,4 +25,7 @@ traefik.http.routers.game-timer.middlewares=game-timer-auth # Also note that dollar signs should NOT be doubled when they are not evaluated (e.g. Ansible docker_container module). # for docker lables use # `htpasswd -nb user password` -traefik.http.middlewares.game-timer-auth.basicauth.users=user:$apr1$rFge2lVe$DpoqxMsxSVJubFLXu4OMr1 \ No newline at end of file +traefik.http.middlewares.game-timer-auth.basicauth.users=user:$apr1$rFge2lVe$DpoqxMsxSVJubFLXu4OMr1 + +# Apply the middleware to the router +traefik.http.routers.game-timer.middlewares=game-timer-auth diff --git a/package.json b/package.json new file mode 100644 index 0000000..9c50cda --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "countdown", + "version": "1.0.0", + "description": "Multi-player chess timer with carousel navigation", + "main": "app.js", + "scripts": { + "start": "docker run -d -p 8080:80 --name game-timer-container game-timer:latest", + "stop": "docker stop game-timer-container && docker rm game-timer-container", + "build": "docker build -t 'game-timer:latest' .", + "rebuild": "npm run stop || true && npm run build && npm run start", + "logs": "docker logs game-timer-container", + "status": "docker ps | grep game-timer-container", + "dev": "cd /usr/share/nginx/html && python -m http.server 8000", + "clean": "docker system prune -f" + }, + "keywords": [ + "timer", + "game", + "chess", + "pwa" + ], + "author": "", + "license": "SEE LICENSE IN LICENSE", + "repository": { + "type": "git", + "url": "https://gitea.virtonline.eu/2HoursProject/game-timer.git" + } +} \ No newline at end of file diff --git a/pushFlicIntegration.js b/pushFlicIntegration.js index 93e786d..b0c330c 100644 --- a/pushFlicIntegration.js +++ b/pushFlicIntegration.js @@ -10,12 +10,32 @@ let actionHandlers = {}; // Store handlers for different Flic actions function getBasicAuthCredentials() { const storedAuth = localStorage.getItem('basicAuthCredentials'); if (storedAuth) { - try { return JSON.parse(storedAuth); } catch (error) { console.error('Failed to parse stored credentials:', error); } + try { + const credentials = JSON.parse(storedAuth); + // Check if the credentials are valid + if (credentials.username && credentials.password) { + console.log('Using stored basic auth credentials.'); + return credentials; + } + } catch (error) { + console.error('Failed to parse stored credentials:', error); + } } + + // No valid stored credentials found + // The function will return null and the caller should handle prompting if needed + console.log('No valid stored credentials found.'); + return null; +} + +// Prompt the user for credentials after permissions are granted +function promptForCredentials() { + console.log('Prompting user for auth credentials.'); const username = prompt('Please enter your username for backend authentication:'); if (!username) return null; const password = prompt('Please enter your password:'); if (!password) return null; + const credentials = { username, password }; localStorage.setItem('basicAuthCredentials', JSON.stringify(credentials)); return credentials; @@ -59,12 +79,33 @@ async function subscribeToPush() { } try { + // First request notification permission + console.log('Requesting notification permission...'); const permission = await Notification.requestPermission(); if (permission !== 'granted') { console.warn('Notification permission denied.'); alert('Please enable notifications to link the Flic button.'); return; } + + console.log('Notification permission granted.'); + + // After permission is granted, check for stored credentials or prompt user + let credentials = getBasicAuthCredentials(); + if (!credentials) { + const confirmAuth = confirm('Do you want to set up credentials for push notifications now?'); + if (!confirmAuth) { + console.log('User declined to provide auth credentials.'); + return; + } + + credentials = promptForCredentials(); + if (!credentials) { + console.log('User canceled credential input.'); + alert('Authentication required to set up push notifications.'); + return; + } + } const registration = await navigator.serviceWorker.ready; let existingSubscription = await registration.pushManager.getSubscription(); @@ -113,8 +154,20 @@ async function sendSubscriptionToServer(subscription, buttonId) { console.log(`Sending subscription for button "${buttonId}" to backend...`); const credentials = getBasicAuthCredentials(); if (!credentials) { - alert('Authentication required to save button link.'); - return; + // One more chance to enter credentials if needed + const confirmAuth = confirm('Authentication required to complete setup. Provide credentials now?'); + if (!confirmAuth) { + alert('Authentication required to save button link.'); + return; + } + + const newCredentials = promptForCredentials(); + if (!newCredentials) { + alert('Authentication required to save button link.'); + return; + } + + credentials = newCredentials; } const headers = { 'Content-Type': 'application/json' }; @@ -122,16 +175,18 @@ async function sendSubscriptionToServer(subscription, buttonId) { if (authHeader) headers['Authorization'] = authHeader; try { + // Add support for handling CORS preflight with credentials const response = await fetch(`${BACKEND_URL}/subscribe`, { method: 'POST', body: JSON.stringify({ button_id: buttonId, subscription: subscription }), - headers: headers + headers: headers, + credentials: 'include' // This ensures credentials are sent with OPTIONS requests too }); if (response.ok) { const result = await response.json(); console.log('Subscription sent successfully:', result.message); - // Maybe show a success message to the user + alert('Push notification setup completed successfully!'); } else { let errorMsg = `Server error: ${response.status}`; if (response.status === 401 || response.status === 403) { diff --git a/virt-game-timer.service b/virt-game-timer.service new file mode 100644 index 0000000..0016371 --- /dev/null +++ b/virt-game-timer.service @@ -0,0 +1,30 @@ +[Unit] +Description=virt-game-timer (virt-game-timer) +Requires=docker.service +After=docker.service +DefaultDependencies=no + +[Service] +Type=simple +Environment="HOME=/root" +ExecStartPre=-/usr/bin/env sh -c '/usr/bin/env docker kill virt-game-timer 2>/dev/null || true' +ExecStartPre=-/usr/bin/env sh -c '/usr/bin/env docker rm virt-game-timer 2>/dev/null || true' + +ExecStart=/usr/bin/env docker run \ + --rm \ + --name=virt-game-timer \ + --log-driver=none \ + --network=traefik \ + --label-file=/virt/game-timer/labels \ + --mount type=bind,src=/etc/localtime,dst=/etc/localtime,ro \ + game-timer:latest + +ExecStop=-/usr/bin/env sh -c '/usr/bin/env docker kill virt-game-timer 2>/dev/null || true' +ExecStop=-/usr/bin/env sh -c '/usr/bin/env docker rm virt-game-timer 2>/dev/null || true' + +Restart=always +RestartSec=30 +SyslogIdentifier=virt-game-timer + +[Install] +WantedBy=multi-user.target \ No newline at end of file