diff --git a/.vscode/launch.json b/.vscode/launch.json index 98b4803..8cbc156 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,7 +11,10 @@ "FLASK_APP": "backend/main.py", "FLASK_DEBUG": "1", "SECRET_KEY": "dev-secret-key-change-in-production", - "REFRESH_TOKEN_EXPIRY_DAYS": "90" + "REFRESH_TOKEN_EXPIRY_DAYS": "90", + "DIGEST_TOKEN_SECRET": "dev-digest-token", + "VAPID_PUBLIC_KEY": "BNKkHdq45uLigohSG7c1TwlAo7ETncoRVLQK02LxHgu2P1DgSJD9njRMfbbzUsaTQGllvLBz7An1WiWsNYQhvKE", + "VAPID_PRIVATE_KEY": "jNiZJT0UO4H861KmnCt874Fg6p5jDAyYKS4V2MZf8bQ" }, "args": [ "run", diff --git a/frontend/vue-app/192.168.1.102+1-key.pem b/frontend/vue-app/192.168.1.102+1-key.pem index 17ebd0e..597b441 100644 --- a/frontend/vue-app/192.168.1.102+1-key.pem +++ b/frontend/vue-app/192.168.1.102+1-key.pem @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCu4wdLkE3sTDd9 -Mea+AJFpnsk2nR0CBm0MqopJvr0E7X+iOpVRdfHOqxQ5vS6a5sjMjDDLjpO6Qb6Z -o0zrm6N+djhfPlITdwXXoNW4TURrWaBFyQXDzHt+eaVBMXpRhLYFcpHvFam+EfM7 -5XB5UmNe400eKhAC5IMIOxuAWhMMN1TfMGVkt+pQAhTFYbeWMvEfCxY0IY3wfzMf -7+ZMKc1YQ0R8hhwqF2KP5BswwTFAIANhopkqGkszOz5ZRQIVlZCSYehbfGEklpPo -LjPeF0qZJWwPzZy0fT9SJH1sLl8SA/+KTo6n3GeJpPdG+MlxMgi7a9hDXM8MlwCV -us34apVbAgMBAAECggEAWfQCM5a0zd7iB64cHgySvr3ihwnG+tytSH+Lg6Ts+lTi -emIhnXXJ+2A5lf09tIUSMUvGaV0blQjt7X52ORWjwY8zLaITe1mUErXyV8q+b2z5 -KAvewDg0KPiOzHqTjMxzB1hHwa7l0RLQhjVcZbq/y/WkG+jMtYAt+ZTVb25lL7mI -JAkBTmATcPrsnYxqk1kwZsTcgrnXZwXKWBKtKy6i728V1bLxYF/KyizGnaClt0+I -H0qi5jnF5ispXmdBlJa2kFOzDNRa4iO7m328nqFSikdYT/xaPfGwNtTplgSxQ2kE -WkbKq6Tjx1K4XR4en5sT7NXst89Vl53UwWT85AZxuQKBgQDeyAOu1H81/SDhtvOt -mdbb6WvRFrzHSRQEX5vBasD1cgKz3uTQeAUKlTGcKZz796pDnluNoAOBx9bnXeYp -6PMfif5tJmykmBPik9CtKlsZEwGexjrfvsGM+tISCRDMfF1FAk16BBlQePUWUyEi -kqdw8pk8HGkA82Blhu3N8dJbFQKBgQDI9sp99Za7cHUHGKjF8wFS7feFwvbeYzY5 -WLXcCTac75Xoqr9O59a74Fz2QdBZGT5eCg06NUbxJ2YTJuWbfRR0jHYEMPUY9iTj -cYCiYYS67NMjHe4/wZU430S/Egz4FUXyf/XswhURjM5pHxyWmLh7XejjRKs8x6GE -WUva37GKrwKBgBj0VJ1HxjwY7474/FCs08lsWxxfrKOyBuD6iKrgt16G99CIHh9P -4liuH5F7g88hjdvnKCA0FVB7PxJJjVeSdXFJ9srpK/A/7LJLlmtfPDcRzvOnBr87 -Udjl25QTmeMd5yCswlrxjJhcBDAM/cAupzzan9mA4S4vFNQqigawmLyFAoGACreW -jucU9cQGia1X+s59yJVmONzv22ZBEwfXEvfu0Km6PeE1OJkGi5hofL1/xfChsdQp -ZmxG7z9hoy3U2tjtyVVgSdLujzk5OGPqLz6yHGHa1KmY9g91zMWjXekxhd1kkI0g -aVLkWr4+l76QALv+Qp38eHpGA4TF6U/1yqNZTYMCgYB12cwRZkihD60MfXaq/vqY -zu2AC49k3h+QKKtYMJ7i5i1nwH9EyrycBLtE9xFm40GYrqUJZ/55BwjaskMI8x5h -X7r4lK1XqOGRIX7nwSWS1UOucj2CAqAYrXal8FzOo+aazBcRCcUiC0vt49ICVKss -+wapUQ7517R2w2tUnAOidg== +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDKVW6l8o9I6Wt1 +QY2kEBPm4AZpp7P67HPJ+xqjOjnXjUrxIOOxqcQkS+LkR/ZxEqGTIkqHAvX+1Q1K +5/b5PABm3kM+J9mdMbN6Mo9d0Y2qzqk383l41yDfZUNx0iyv6Viu5OZXPDNTSFwg +CIXxzGsIZJPIO0javKFD+kIeeNdElCpmLF6SDw7NuJgzM7zupBpuwc16dVe/p/fH +/iAkELoiFNS/W+awOf8X3UckRSKO1PH5z9xONl3bkLK8zqolNamPMaAYlAvwGilk +4V78s+0+J3AioCQdpeDjYLwOTS52ffvLs6kw5jZa/u3dgFqBZOwqGM9HmSPJJG7R +ACAtDp55AgMBAAECggEAF0M4BeCTyH1cx1YOeb/G9/8HAbgALX/oxp7GBuEDhDS4 +mm1OfG9RL56hcx9Sdlje5oaVZL0qiP5YCUYO60QSpEEW4FMu1f/AO7MLMG1OwUYC +Jt6Jd2Mdgo23EcOpM17r3SzQTlSLrp41yFGOi9i1sBj3NDjbtRllnaYM2snILzg4 +5p0o20H4t4vnhLTCgfymjThF3FQHNZXlIbylNNDjbR+spNTwmn2ISbfFjNa7fecm +ZvdukETrl1Jrp91iwX66VaY9bDM4irEU5Z62G+IZXmzLDeJQU75gQPwHRndPLQqZ +ltXqMEFHOYNyiIkQFL2zq5AZELSIuvmdi81J+LyooQKBgQDdVJIDyvVpPUoks5Mr +szmkyFEQ+kY1dJV1k03jYXPHZqRzw5U5yfmDM1BCJztmvA2chXW0XhqxNUSd2JMv +00xxckPPUHG8AenyREGq8WSciqzf8Se0UBFhoiN/T1nSeDWbFKJeWuigXaDZ9qBq +jfeCkFunIvzje4Y++KSzAkwxIQKBgQDqBxb7PwFJipVkqQm3zpVMA3ZcWwTUQaqD +83jJidMGQlSXNTvp7P7hfvzvBQVoV2EuSRPUjA41OxMpMeGvc/WIVT2WVEgeWtiG +tTUEZZv2q3sFyvrUyMlxiaxuBejVvH0T3orikXr8P/Y5670Lf7KfkM2B4OtqeqHK +tA5LCJ5KWQKBgC4Cvrf7ITlXfGpUymtzPrB61B9rZ90E920RykdSovb454cJSaRR +0ITtzelyrm6U+V9ofyeXyIS+Rh1qQG7YxjNvRZl7Z6ll3HR4rA4VUI0aZwXG5DIf +0v0w76AvpsSSKNKsX3SuAV4VGLM3CfIcwS9rQyJjq56+txGwLszn1V8BAoGAJThB +cG4Bz2dqARtdP01ssy0tytxy9SsIannzcOIpnKo5995wi/C0TLq8kWsUBBc5jnny +3G/15oNhtcCIKzZfC3K7G8iFu8Yo/6ucJfnfBykYpMA2ilbwqs0BjnIEKNIUdm+D +WStYCvxFNcsHQufpSbVm6cwSxNmCF9HxH//b5OkCgYEAqmrJxwf46yv6w+BiX061 +xOnNvcupZ2hAQ5krY7rIA2ZAR+SmfG6kptfPAW9Jrr5HKLq7rO8u7PGGLahH+Q9T +OaBRalWKpOvK6/yfnJdEpQFvPTTM2HRwFOG3lW0ti9j6eJ9tn6CiL73jEyurtCk9 +1Jroja8Cq6ZE3XsBwW+ge28= -----END PRIVATE KEY----- diff --git a/frontend/vue-app/192.168.1.102+1.pem b/frontend/vue-app/192.168.1.102+1.pem index 550ab5e..3245bf7 100644 --- a/frontend/vue-app/192.168.1.102+1.pem +++ b/frontend/vue-app/192.168.1.102+1.pem @@ -1,25 +1,26 @@ -----BEGIN CERTIFICATE----- -MIIETDCCArSgAwIBAgIQDRI/2ndt0jHqQgdHokXM3jANBgkqhkiG9w0BAQsFADCB -hTEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMS0wKwYDVQQLDCRERVNL -VE9QLUFVOTBHNkpcUnlhbkBERVNLVE9QLUFVOTBHNkoxNDAyBgNVBAMMK21rY2Vy -dCBERVNLVE9QLUFVOTBHNkpcUnlhbkBERVNLVE9QLUFVOTBHNkowHhcNMjUxMTE4 -MTU1MjA1WhcNMjgwMjE4MTU1MjA1WjBYMScwJQYDVQQKEx5ta2NlcnQgZGV2ZWxv -cG1lbnQgY2VydGlmaWNhdGUxLTArBgNVBAsMJERFU0tUT1AtQVU5MEc2SlxSeWFu -QERFU0tUT1AtQVU5MEc2SjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -AK7jB0uQTexMN30x5r4AkWmeyTadHQIGbQyqikm+vQTtf6I6lVF18c6rFDm9Lprm -yMyMMMuOk7pBvpmjTOubo352OF8+UhN3Bdeg1bhNRGtZoEXJBcPMe355pUExelGE -tgVyke8Vqb4R8zvlcHlSY17jTR4qEALkgwg7G4BaEww3VN8wZWS36lACFMVht5Yy -8R8LFjQhjfB/Mx/v5kwpzVhDRHyGHCoXYo/kGzDBMUAgA2GimSoaSzM7PllFAhWV -kJJh6Ft8YSSWk+guM94XSpklbA/NnLR9P1IkfWwuXxID/4pOjqfcZ4mk90b4yXEy -CLtr2ENczwyXAJW6zfhqlVsCAwEAAaNkMGIwDgYDVR0PAQH/BAQDAgWgMBMGA1Ud -JQQMMAoGCCsGAQUFBwMBMB8GA1UdIwQYMBaAFMdcsDJbHnPC2tztDztuvlALzXcJ -MBoGA1UdEQQTMBGCCWxvY2FsaG9zdIcEwKgBZjANBgkqhkiG9w0BAQsFAAOCAYEA -nhDUKSW8Ti6h39cth+JeX3isU/cBO1l3y3Ptflb3i02na3x2b39hVstm1xCuxF43 -KNLF+Mfe1OegifDHCxkEQGM6HvppBjbUchZlTcr0q1xusU6v/moGxYnEP1BewvRv -B5eNHSADROdRNSbtuK8DeVPWG3uXzyqmQPTlSmtNYAXuigsmPEodiFLBxIoE1qWd -Y4EGWK9b7Vka7IjIH6KnegJe5n9aI102Hu2rZwP8WIlDhqPzpDprrpj0n8t38Q5z -FK+Qae3E1i5vSAZoX0buUngnpXAbGDQl/Sq/PIIFeljlOWtI8JDhUb2nZHWnPoyA -NuiGgYsOFfU6eH6gFw/sTphjrABIQ9JbQoSjeUA3vcol1De7mqCPJ6oC4lbeMdr1 -xt1bD6UiIhjx219ikAlnNSfm9eZsqBepPLi029wBDP/De1RdGRcLRwtNBxNWkYcc -t/7BWjjDd0/67meIEK85kYatfK1uUrVOjeU097LjwHjvsfsqKZr3Kok+kAzFalvF +MIIEYjCCAsqgAwIBAgIRAKMCeivvVrGdMDcAcGb3ArYwDQYJKoZIhvcNAQELBQAw +gZMxHjAcBgNVBAoTFW1rY2VydCBkZXZlbG9wbWVudCBDQTE0MDIGA1UECwwrcnlh +bkBtYWNib29rLnRhaWxhMTQ2YjMudHMubmV0IChSeWFuIEtlZ2VsKTE7MDkGA1UE +AwwybWtjZXJ0IHJ5YW5AbWFjYm9vay50YWlsYTE0NmIzLnRzLm5ldCAoUnlhbiBL +ZWdlbCkwHhcNMjYwNDE2MjAyNzE0WhcNMjgwNzE2MjAyNzE0WjBfMScwJQYDVQQK +Ex5ta2NlcnQgZGV2ZWxvcG1lbnQgY2VydGlmaWNhdGUxNDAyBgNVBAsMK3J5YW5A +bWFjYm9vay50YWlsYTE0NmIzLnRzLm5ldCAoUnlhbiBLZWdlbCkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDKVW6l8o9I6Wt1QY2kEBPm4AZpp7P67HPJ ++xqjOjnXjUrxIOOxqcQkS+LkR/ZxEqGTIkqHAvX+1Q1K5/b5PABm3kM+J9mdMbN6 +Mo9d0Y2qzqk383l41yDfZUNx0iyv6Viu5OZXPDNTSFwgCIXxzGsIZJPIO0javKFD ++kIeeNdElCpmLF6SDw7NuJgzM7zupBpuwc16dVe/p/fH/iAkELoiFNS/W+awOf8X +3UckRSKO1PH5z9xONl3bkLK8zqolNamPMaAYlAvwGilk4V78s+0+J3AioCQdpeDj +YLwOTS52ffvLs6kw5jZa/u3dgFqBZOwqGM9HmSPJJG7RACAtDp55AgMBAAGjZDBi +MA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAfBgNVHSMEGDAW +gBSzPmpBCA7e+Z8h2a25FLP+CEFnrDAaBgNVHREEEzARgglsb2NhbGhvc3SHBMCo +AWYwDQYJKoZIhvcNAQELBQADggGBAHjDyJQaET4fuLp/PGlyOqeRqr2YWFGho9/r +sPdJ8bw785vkSmvMFBl3qK9kj0X/GkRqJ1tXit7pMVetoXRBSbVe07kX0G+jm5bT +En+TEzp0cSc0NqyRJAR7PuLQtcZA4XQWductqwszcggrIUdozzWNQ0gjuQ0fWD6A +kkH1uyqWb4zVWnwwuoi6Z0Gmbim3ldW/EilhtYd7DzA4ztYaDmt4D8WKZo5LjH5y +OgoiHuWAqP85R7wsscNWUgei1ltERsGLlvz5f/WGqkeVYzC3EwKnubh4fo2NKqc0 +UmHRnUrX1o5ZUPemnp0vnE4NPYFDZf9iyn8WkG9qC+/IbPudsia3I8aZQ5RqAttj +rWJkzqsJE6UAb3L1XCbYzxUz1vtzDZpH9dq/UG+iDckxJvlSl+DMa60bd2qH2ui3 +VusOFBKS5uUam6JFsV2/fLzHJUo9CdVl/bscK8byN5IxWOpOc4SiDpKybVpNmHwD +WuBkDmpNzU0HOUSxZNRIIVb5/dA7YA== -----END CERTIFICATE----- diff --git a/frontend/vue-app/public/icons/icon-192x192.png b/frontend/vue-app/public/icons/icon-192x192.png new file mode 100644 index 0000000..35c1989 Binary files /dev/null and b/frontend/vue-app/public/icons/icon-192x192.png differ diff --git a/frontend/vue-app/public/icons/icon-512x512.png b/frontend/vue-app/public/icons/icon-512x512.png new file mode 100644 index 0000000..ed932fd Binary files /dev/null and b/frontend/vue-app/public/icons/icon-512x512.png differ diff --git a/frontend/vue-app/public/manifest.json b/frontend/vue-app/public/manifest.json index 2b13ab4..c60cfe5 100644 --- a/frontend/vue-app/public/manifest.json +++ b/frontend/vue-app/public/manifest.json @@ -1,4 +1,5 @@ { + "id": "/", "name": "Reward App", "short_name": "Rewards", "start_url": "/", @@ -9,8 +10,20 @@ "icons": [ { "src": "/favicon.ico", - "sizes": "48x48", + "sizes": "32x32", "type": "image/x-icon" + }, + { + "src": "/icons/icon-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/icons/icon-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "any" } ] } diff --git a/frontend/vue-app/public/sw.js b/frontend/vue-app/public/sw.js index 3a2b0bf..98c6937 100644 --- a/frontend/vue-app/public/sw.js +++ b/frontend/vue-app/public/sw.js @@ -1,5 +1,14 @@ /* Service Worker for Reward App push notifications */ +/* Activate immediately — no waiting for old tabs to close */ +self.addEventListener('install', function (event) { + event.waitUntil(self.skipWaiting()) +}) + +self.addEventListener('activate', function (event) { + event.waitUntil(self.clients.claim()) +}) + self.addEventListener('push', function (event) { if (!event.data) return @@ -13,6 +22,7 @@ self.addEventListener('push', function (event) { const title = payload.title || 'Reward App' const options = { body: payload.body || '', + icon: '/icons/icon-192x192.png', data: payload, actions: [ { action: 'approve', title: 'Approve' },