From 6a045133591fa51454cb4964c0208dfcde534357 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Tue, 16 Apr 2024 22:34:24 +0300 Subject: [PATCH 1/9] proper env name --- .env | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.env b/.env index c2ef068..df77abf 100644 --- a/.env +++ b/.env @@ -20,11 +20,11 @@ AZURE_AD_TENANT_ID=f69d1a93-bfba-498a-9b60-e87c1bc26276 # First APPLE_SECRET=eyJhbGciOiJFUzI1NiIsImtpZCI6IlRCM1YzNTVHNVkifQ.eyJhdWQiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiaXNzIjoiWEM1N1A5U1hESyIsImlhdCI6MTcxMjE3ODM0MiwiZXhwIjoxNzI3NzMwMzQzLCJzdWIiOiJjb20ubXdoaXRuZXNzaW5nLnNvZmlhIn0.XceA0qUQi0tXg0GM_LkJkpNU5AqXLiSB2JlEVbHCB_nINbQTWkjtoWxfqmvdOkIzwKtvdQ8FFb-crK9no9Bbbw -APPLE_ID=com.mwhitnessing.sofia +APPLE_APP_ID=com.mwhitnessing.sofia APPLE_SECRET=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IiJ9.eyJpYXQiOjE3MTMyMDI1MzAsImV4cCI6MTcyODc1NDUzMCwiYXVkIjoiaHR0cHM6Ly9hcHBsZWlkLmFwcGxlLmNvbSIsImlzcyI6IiIsInN1YiI6IiJ9.C18A_ZBGcaHoGf8JPeQtdkLdWQqAqzCygWd6eD_S-X3OXw8ZWNXGtGAk5xEB9sui84OW60dNnH6ZGQMAtP5-hA # with team in the ID? -#APPLE_ID=XC57P9SXDK.com.mwhitnessing.sofia +#APPLE_APP_ID=XC57P9SXDK.com.mwhitnessing.sofia #APPLE_SECRET=eyJhbGciOiJFUzI1NiIsImtpZCI6IlRCM1YzNTVHNVkifQ.eyJhdWQiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiaXNzIjoiWEM1N1A5U1hESyIsImlhdCI6MTcxMjE3ODM0MiwiZXhwIjoxNzI3NzMwMzQzLCJzdWIiOiJjb20ubXdoaXRuZXNzaW5nLnNvZmlhIn0.XceA0qUQi0tXg0GM_LkJkpNU5AqXLiSB2JlEVbHCB_nINbQTWkjtoWxfqmvdOkIzwKtvdQ8FFb-crK9no9Bbbw # to generate APPLE_TEAM_ID=XC57P9SXDK From d81b64b34d509b9708159e87130033600be2b12b Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Wed, 17 Apr 2024 00:57:34 +0300 Subject: [PATCH 2/9] try new generated appleID secret --- .env | 2 +- .env.production | 2 +- _deploy/setupAppleId.mjs | 68 +++++++++++++++++------------------ package-lock.json | 20 +++++++++-- pages/api/auth/apple-token.ts | 10 +++--- server.js | 2 +- 6 files changed, 60 insertions(+), 44 deletions(-) diff --git a/.env b/.env index df77abf..8ae60da 100644 --- a/.env +++ b/.env @@ -21,7 +21,7 @@ AZURE_AD_TENANT_ID=f69d1a93-bfba-498a-9b60-e87c1bc26276 # First APPLE_SECRET=eyJhbGciOiJFUzI1NiIsImtpZCI6IlRCM1YzNTVHNVkifQ.eyJhdWQiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiaXNzIjoiWEM1N1A5U1hESyIsImlhdCI6MTcxMjE3ODM0MiwiZXhwIjoxNzI3NzMwMzQzLCJzdWIiOiJjb20ubXdoaXRuZXNzaW5nLnNvZmlhIn0.XceA0qUQi0tXg0GM_LkJkpNU5AqXLiSB2JlEVbHCB_nINbQTWkjtoWxfqmvdOkIzwKtvdQ8FFb-crK9no9Bbbw APPLE_APP_ID=com.mwhitnessing.sofia -APPLE_SECRET=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IiJ9.eyJpYXQiOjE3MTMyMDI1MzAsImV4cCI6MTcyODc1NDUzMCwiYXVkIjoiaHR0cHM6Ly9hcHBsZWlkLmFwcGxlLmNvbSIsImlzcyI6IiIsInN1YiI6IiJ9.C18A_ZBGcaHoGf8JPeQtdkLdWQqAqzCygWd6eD_S-X3OXw8ZWNXGtGAk5xEB9sui84OW60dNnH6ZGQMAtP5-hA +APPLE_SECRET=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlRCM1YzNTVHNVkifQ.eyJpYXQiOjE3MTMzMDQ1OTMsImV4cCI6MTcyODg1NjU5MywiYXVkIjoiaHR0cHM6Ly9hcHBsZWlkLmFwcGxlLmNvbSIsImlzcyI6IlhDNTdQOVNYREsiLCJzdWIiOiJjb20ubXdoaXRuZXNzaW5nLnNvZmlhIn0.iO2prjQ_4P7F17R7LTJfG9zHluj59uUtm8DA1LbK49jVBMeGHQP_Az7s_yU5D-GeMHSwU7VnVHcaVKiGWT_Yjg # with team in the ID? #APPLE_APP_ID=XC57P9SXDK.com.mwhitnessing.sofia diff --git a/.env.production b/.env.production index 112901f..8e9e8f4 100644 --- a/.env.production +++ b/.env.production @@ -7,7 +7,7 @@ NEXT_PUBLIC_PUBLIC_URL= https://sofia.mwitnessing.com NEXTAUTH_SECRET=1dd8a5457970d1dda50600be28e935ecc4513ff27c49c431849e6746f158d638 # ? do we need to duplicate this? already defined in the deoployment yml file DATABASE=mysql://jwpwsofia:dwxhns9p9vp248V39xJyRthUsZ2gR9@mariadb:3306/jwpwsofia - +# DATABASE=mysql://cart:cartpw@localhost:3306/cart EMAIL_BYPASS_TO= MAILTRAP_HOST_BULK=bulk.smtp.mailtrap.io diff --git a/_deploy/setupAppleId.mjs b/_deploy/setupAppleId.mjs index ef22074..7ff3383 100644 --- a/_deploy/setupAppleId.mjs +++ b/_deploy/setupAppleId.mjs @@ -4,14 +4,14 @@ import { SignJWT } from "jose" import { createPrivateKey } from "crypto" if (process.argv.includes("--help") || process.argv.includes("-h")) { - console.log(` + console.log(` Creates a JWT from the components found at Apple. By default, the JWT has a 6 months expiry date. Read more: https://developer.apple.com/documentation/sign_in_with_apple/generate_and_validate_tokens#3262048 Usage: node apple.mjs [--kid] [--iss] [--private_key] [--sub] [--expires_in] [--exp] - APPLE_ID=com.mwhitnessing.sofia + APPLE_APP_ID=com.mwhitnessing.sofia APPLE_TEAM_ID=XC57P9SXDK APPLE_KEY_ID=TB3V355G5Y APPLE_KEY @@ -37,45 +37,45 @@ eyJhbGciOiJFUzI1NiIsImtpZCI6IlRCM1YzNTVHNVkifQ.eyJhdWQiOiJodHRwczovL2FwcGxlaWQuY --exp Future date in seconds when the JWT expires `) } else { - const args = process.argv.slice(2).reduce((acc, arg, i) => { - if (arg.match(/^--\w/)) { - const key = arg.replace(/^--/, "").toLowerCase() - acc[key] = process.argv[i + 3] - } - return acc - }, {}) + const args = process.argv.slice(2).reduce((acc, arg, i) => { + if (arg.match(/^--\w/)) { + const key = arg.replace(/^--/, "").toLowerCase() + acc[key] = process.argv[i + 3] + } + return acc + }, {}) - const { - team_id, - iss = team_id, + const { + team_id, + iss = team_id, - private_key, + private_key, - client_id, - sub = client_id, + client_id, + sub = client_id, - key_id, - kid = key_id, + key_id, + kid = key_id, - expires_in = 86400 * 180, - exp = Math.ceil(Date.now() / 1000) + expires_in, - } = args + expires_in = 86400 * 180, + exp = Math.ceil(Date.now() / 1000) + expires_in, + } = args - /** - * How long is the secret valid in seconds. - * @default 15780000 - */ - const expiresAt = Math.ceil(Date.now() / 1000) + expires_in - const expirationTime = exp ?? expiresAt - console.log(` + /** + * How long is the secret valid in seconds. + * @default 15780000 + */ + const expiresAt = Math.ceil(Date.now() / 1000) + expires_in + const expirationTime = exp ?? expiresAt + console.log(` Apple client secret generated. Valid until: ${new Date(expirationTime * 1000)} ${await new SignJWT({}) - .setAudience("https://appleid.apple.com") - .setIssuer(iss) - .setIssuedAt() - .setExpirationTime(expirationTime) - .setSubject(sub) - .setProtectedHeader({ alg: "ES256", kid }) - .sign(createPrivateKey(private_key.replace(/\\n/g, "\n")))}`) + .setAudience("https://appleid.apple.com") + .setIssuer(iss) + .setIssuedAt() + .setExpirationTime(expirationTime) + .setSubject(sub) + .setProtectedHeader({ alg: "ES256", kid }) + .sign(createPrivateKey(private_key.replace(/\\n/g, "\n")))}`) } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 9acc5d5..a8be91d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4802,6 +4802,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "optional": true, "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -5771,6 +5772,7 @@ "url": "https://github.com/sponsors/sibiraj-s" } ], + "optional": true, "engines": { "node": ">=8" } @@ -5784,6 +5786,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "optional": true, "engines": { "node": ">=6" } @@ -8546,7 +8549,8 @@ "node_modules/hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "optional": true }, "node_modules/hsl-to-hex": { "version": "1.0.0", @@ -8888,6 +8892,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "optional": true, "engines": { "node": ">=8" } @@ -8915,6 +8920,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "optional": true, "engines": { "node": ">=10" } @@ -10943,6 +10949,7 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "optional": true, "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", @@ -10954,6 +10961,7 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "optional": true, "bin": { "semver": "bin/semver" } @@ -13870,6 +13878,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "optional": true, "dependencies": { "aggregate-error": "^3.0.0" }, @@ -15871,6 +15880,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "optional": true, "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -15879,12 +15889,14 @@ "node_modules/spdx-exceptions": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==" + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "optional": true }, "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "optional": true, "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" @@ -15893,7 +15905,8 @@ "node_modules/spdx-license-ids": { "version": "3.0.17", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", - "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==" + "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", + "optional": true }, "node_modules/ssf": { "version": "0.8.2", @@ -17442,6 +17455,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "optional": true, "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" diff --git a/pages/api/auth/apple-token.ts b/pages/api/auth/apple-token.ts index 128c34a..dd44751 100644 --- a/pages/api/auth/apple-token.ts +++ b/pages/api/auth/apple-token.ts @@ -9,17 +9,19 @@ export default async function handler(req, res) { if (req.method === 'GET') { try { const appleKey = fs.readFileSync(path.resolve('./_deploy/appleKey.p8'), 'utf8'); - + const teamID = process.env.APPLE_TEAM_ID || "XC57P9SXDK"; + const keyID = process.env.APPLE_KEY_ID || "TB3V355G5Y"; + const appleAppID = process.env.APPLE_APP_ID || "com.mwitnessing.mwitnessing"; const token = jwt.sign({}, appleKey, { algorithm: 'ES256', expiresIn: '180d', - issuer: process.env.APPLE_TEAM_ID, + issuer: teamID, header: { alg: 'ES256', - kid: process.env.APPLE_KEY_ID, + kid: keyID, }, audience: 'https://appleid.apple.com', - subject: process.env.APPLE_ID, + subject: appleAppID, }); // Redirect to Apple's authentication page, or send the token to the client to do so diff --git a/server.js b/server.js index 2c41621..88c5b7b 100644 --- a/server.js +++ b/server.js @@ -40,7 +40,7 @@ console.log("process.env.PORT = ", process.env.PORT); console.log("process.env.TELEGRAM_BOT = ", process.env.TELEGRAM_BOT); console.log("process.env.DATABASE_URL = ", process.env.DATABASE_URL); console.log("process.env.DATABASE = ", process.env.DATABASE); -console.log("process.env.APPLE_ID = ", process.env.APPLE_ID); +console.log("process.env.APPLE_APP_ID = ", process.env.APPLE_APP_ID); //require('module-alias/register'); From 6e08ea21d425253552f4bb06b6626ef909ee5b94 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Wed, 17 Apr 2024 01:29:20 +0300 Subject: [PATCH 3/9] notify and debug apple-signin api --- components/PwaManager.tsx | 3 ++- components/sidebar.tsx | 2 +- pages/api/auth/apple-signin.ts | 40 ++++++++++++++++++++++++++++++++++ pages/api/notify.ts | 37 +++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 pages/api/auth/apple-signin.ts create mode 100644 pages/api/notify.ts diff --git a/components/PwaManager.tsx b/components/PwaManager.tsx index 1eae6ce..ceb6577 100644 --- a/components/PwaManager.tsx +++ b/components/PwaManager.tsx @@ -151,7 +151,7 @@ function PwaManager() { return; } - await fetch('/api/notification', { + await fetch('/api/notify', { method: 'POST', headers: { 'Content-Type': 'application/json' @@ -219,6 +219,7 @@ function PwaManager() { Телеграм + < ); diff --git a/components/sidebar.tsx b/components/sidebar.tsx index 01533b8..3f2d4c2 100644 --- a/components/sidebar.tsx +++ b/components/sidebar.tsx @@ -163,7 +163,7 @@ function UserSection({ session }) { function SignInButton() { return ( -
signIn()}> +
signIn()}>
); diff --git a/pages/api/auth/apple-signin.ts b/pages/api/auth/apple-signin.ts new file mode 100644 index 0000000..8b152a7 --- /dev/null +++ b/pages/api/auth/apple-signin.ts @@ -0,0 +1,40 @@ +// pages/api/auth/apple.js +import jwt from 'jsonwebtoken'; +import axios from 'axios'; +import fs from 'fs'; +import path from 'path'; + +export default async function handler(req, res) { + if (req.method === 'GET') { + // Generate the client secret + const clientSecret = generateClientSecret(); + const redirectUri = `${req.headers.origin}/api/auth/apple/callback`; + + // Redirect to Apple's authorization page + res.redirect(`https://appleid.apple.com/auth/authorize?response_type=code&client_id=${process.env.APPLE_CLIENT_ID}&redirect_uri=${encodeURIComponent(redirectUri)}&scope=name+email&response_mode=form_post&state=STATE&client_secret=${encodeURIComponent(clientSecret)}`); + } else { + res.status(405).json({ error: 'Method not allowed' }); + } +} + +function generateClientSecret() { + const appleKey = fs.readFileSync(path.resolve('./_deploy/appleKey.p8'), 'utf8'); + const teamID = process.env.APPLE_TEAM_ID || "XC57P9SXDK"; + const keyID = process.env.APPLE_KEY_ID || "TB3V355G5Y"; + const appleAppID = process.env.APPLE_APP_ID || "com.mwitnessing.mwitnessing"; + + // Token expiration + const now = Math.floor(Date.now() / 1000); + const exp = now + 86400 * 180; // 6 months + + const claims = { + iss: teamID, + iat: now, + exp: exp, + aud: 'https://appleid.apple.com', + sub: appleAppID, + }; + + const token = jwt.sign(claims, privateKey, { algorithm: 'ES256', header: { alg: 'ES256', kid: keyId } }); + return token; +} diff --git a/pages/api/notify.ts b/pages/api/notify.ts new file mode 100644 index 0000000..34ebd93 --- /dev/null +++ b/pages/api/notify.ts @@ -0,0 +1,37 @@ + +const webPush = require('web-push') + +webPush.setVapidDetails( + `mailto:${process.env.WEB_PUSH_EMAIL}`, + process.env.NEXT_PUBLIC_WEB_PUSH_PUBLIC_KEY, + process.env.WEB_PUSH_PRIVATE_KEY +) + +const Notification = (req, res) => { + if (req.method == 'POST') { + const { subscription } = req.body + + webPush + .sendNotification( + subscription, + JSON.stringify({ title: 'Hello Web Push', message: 'Your web push notification is here!' }) + ) + .then(response => { + res.writeHead(response.statusCode, response.headers).end(response.body) + }) + .catch(err => { + if ('statusCode' in err) { + res.writeHead(err.statusCode, err.headers).end(err.body) + } else { + console.error(err) + res.statusCode = 500 + res.end() + } + }) + } else { + res.statusCode = 405 + res.end() + } +} + +export default Notification From 348e404565df9ec11da32cacaff0b954f4486795 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Wed, 17 Apr 2024 01:37:00 +0300 Subject: [PATCH 4/9] fix typo --- components/PwaManager.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/components/PwaManager.tsx b/components/PwaManager.tsx index ceb6577..3bce4fc 100644 --- a/components/PwaManager.tsx +++ b/components/PwaManager.tsx @@ -219,7 +219,11 @@ function PwaManager() { Телеграм
- < +
+ + Apple sign-in + +
); From c0a2a5f17128b0af0a233349731535f957977c28 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Wed, 17 Apr 2024 01:38:08 +0300 Subject: [PATCH 5/9] more typo --- pages/api/auth/apple-signin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/api/auth/apple-signin.ts b/pages/api/auth/apple-signin.ts index 8b152a7..d8f2503 100644 --- a/pages/api/auth/apple-signin.ts +++ b/pages/api/auth/apple-signin.ts @@ -35,6 +35,6 @@ function generateClientSecret() { sub: appleAppID, }; - const token = jwt.sign(claims, privateKey, { algorithm: 'ES256', header: { alg: 'ES256', kid: keyId } }); + const token = jwt.sign(claims, appleKey, { algorithm: 'ES256', header: { alg: 'ES256', kid: keyID } }); return token; } From 08f6af1a7ae5096675878be464a2cd5726a18ca8 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Wed, 17 Apr 2024 01:58:57 +0300 Subject: [PATCH 6/9] config tweaks --- .env | 5 +++-- pages/api/auth/apple-signin.ts | 9 ++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.env b/.env index 8ae60da..854bba3 100644 --- a/.env +++ b/.env @@ -20,6 +20,9 @@ AZURE_AD_TENANT_ID=f69d1a93-bfba-498a-9b60-e87c1bc26276 # First APPLE_SECRET=eyJhbGciOiJFUzI1NiIsImtpZCI6IlRCM1YzNTVHNVkifQ.eyJhdWQiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiaXNzIjoiWEM1N1A5U1hESyIsImlhdCI6MTcxMjE3ODM0MiwiZXhwIjoxNzI3NzMwMzQzLCJzdWIiOiJjb20ubXdoaXRuZXNzaW5nLnNvZmlhIn0.XceA0qUQi0tXg0GM_LkJkpNU5AqXLiSB2JlEVbHCB_nINbQTWkjtoWxfqmvdOkIzwKtvdQ8FFb-crK9no9Bbbw +APPLE_TEAM_ID=XC57P9SXDK +APPLE_KEY_ID=TB3V355G5Y + APPLE_APP_ID=com.mwhitnessing.sofia APPLE_SECRET=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlRCM1YzNTVHNVkifQ.eyJpYXQiOjE3MTMzMDQ1OTMsImV4cCI6MTcyODg1NjU5MywiYXVkIjoiaHR0cHM6Ly9hcHBsZWlkLmFwcGxlLmNvbSIsImlzcyI6IlhDNTdQOVNYREsiLCJzdWIiOiJjb20ubXdoaXRuZXNzaW5nLnNvZmlhIn0.iO2prjQ_4P7F17R7LTJfG9zHluj59uUtm8DA1LbK49jVBMeGHQP_Az7s_yU5D-GeMHSwU7VnVHcaVKiGWT_Yjg @@ -27,8 +30,6 @@ APPLE_SECRET=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlRCM1YzNTVHNVkifQ.eyJp #APPLE_APP_ID=XC57P9SXDK.com.mwhitnessing.sofia #APPLE_SECRET=eyJhbGciOiJFUzI1NiIsImtpZCI6IlRCM1YzNTVHNVkifQ.eyJhdWQiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiaXNzIjoiWEM1N1A5U1hESyIsImlhdCI6MTcxMjE3ODM0MiwiZXhwIjoxNzI3NzMwMzQzLCJzdWIiOiJjb20ubXdoaXRuZXNzaW5nLnNvZmlhIn0.XceA0qUQi0tXg0GM_LkJkpNU5AqXLiSB2JlEVbHCB_nINbQTWkjtoWxfqmvdOkIzwKtvdQ8FFb-crK9no9Bbbw # to generate -APPLE_TEAM_ID=XC57P9SXDK -APPLE_KEY_ID=TB3V355G5Y AUTH0_ID=Aa9f3HJowauUrmBVY4iQzQJ7fYsaZDbK diff --git a/pages/api/auth/apple-signin.ts b/pages/api/auth/apple-signin.ts index d8f2503..62c2dc5 100644 --- a/pages/api/auth/apple-signin.ts +++ b/pages/api/auth/apple-signin.ts @@ -4,14 +4,17 @@ import axios from 'axios'; import fs from 'fs'; import path from 'path'; +const dotenv = require("dotenv"); + export default async function handler(req, res) { if (req.method === 'GET') { // Generate the client secret const clientSecret = generateClientSecret(); - const redirectUri = `${req.headers.origin}/api/auth/apple/callback`; + // const redirectUri = `${req.headers.origin}/api/auth/apple/callback`; + const redirectUri = `https://sofia.mwitnessing.com/api/auth/callback/apple`; // Redirect to Apple's authorization page - res.redirect(`https://appleid.apple.com/auth/authorize?response_type=code&client_id=${process.env.APPLE_CLIENT_ID}&redirect_uri=${encodeURIComponent(redirectUri)}&scope=name+email&response_mode=form_post&state=STATE&client_secret=${encodeURIComponent(clientSecret)}`); + res.redirect(`https://appleid.apple.com/auth/authorize?response_type=code&client_id=${process.env.APPLE_APP_ID}&redirect_uri=${encodeURIComponent(redirectUri)}&scope=name+email&response_mode=form_post&state=STATE&client_secret=${encodeURIComponent(clientSecret)}`); } else { res.status(405).json({ error: 'Method not allowed' }); } @@ -21,7 +24,7 @@ function generateClientSecret() { const appleKey = fs.readFileSync(path.resolve('./_deploy/appleKey.p8'), 'utf8'); const teamID = process.env.APPLE_TEAM_ID || "XC57P9SXDK"; const keyID = process.env.APPLE_KEY_ID || "TB3V355G5Y"; - const appleAppID = process.env.APPLE_APP_ID || "com.mwitnessing.mwitnessing"; + const appleAppID = process.env.APPLE_APP_ID; // Token expiration const now = Math.floor(Date.now() / 1000); From 5b80366ffcd409db906a664f8d5c5623cb7a6d30 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Wed, 17 Apr 2024 02:13:47 +0300 Subject: [PATCH 7/9] try to edit url params --- pages/api/auth/apple-signin.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pages/api/auth/apple-signin.ts b/pages/api/auth/apple-signin.ts index 62c2dc5..7fd9bf1 100644 --- a/pages/api/auth/apple-signin.ts +++ b/pages/api/auth/apple-signin.ts @@ -14,7 +14,8 @@ export default async function handler(req, res) { const redirectUri = `https://sofia.mwitnessing.com/api/auth/callback/apple`; // Redirect to Apple's authorization page - res.redirect(`https://appleid.apple.com/auth/authorize?response_type=code&client_id=${process.env.APPLE_APP_ID}&redirect_uri=${encodeURIComponent(redirectUri)}&scope=name+email&response_mode=form_post&state=STATE&client_secret=${encodeURIComponent(clientSecret)}`); + const url = `https://appleid.apple.com/auth/authorize?response_type=code&client_id=${process.env.APPLE_APP_ID}&redirect_uri=${encodeURIComponent(redirectUri)}&scope=email&response_mode=form_post&state=initial&usePopup=true&client_secret=${encodeURIComponent(clientSecret)}`; + res.redirect(url); } else { res.status(405).json({ error: 'Method not allowed' }); } @@ -39,5 +40,6 @@ function generateClientSecret() { }; const token = jwt.sign(claims, appleKey, { algorithm: 'ES256', header: { alg: 'ES256', kid: keyID } }); + console.log("generated new token:" + token); return token; } From 0dd5d717147c131882e145ed6b517096f141d8ff Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Wed, 17 Apr 2024 02:28:37 +0300 Subject: [PATCH 8/9] fix edge case --- components/availability/AvailabilityForm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/availability/AvailabilityForm.js b/components/availability/AvailabilityForm.js index 66262ee..3da3063 100644 --- a/components/availability/AvailabilityForm.js +++ b/components/availability/AvailabilityForm.js @@ -298,7 +298,7 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o return itemStart && itemEnd && (slotStart.getTime() < itemEnd.getTime()) && - (slotEnd.getTime() >= itemStart.getTime()); + (slotEnd.getTime() > itemStart.getTime()); }); slots.push({ From 52aecf741e43d90af1e59c2a25fa0422644d33a2 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Wed, 17 Apr 2024 02:59:54 +0300 Subject: [PATCH 9/9] fix copy availabilities button functionality. when editing manually, the flag is set back to false; --- components/availability/AvailabilityForm.js | 2 +- components/calendar/avcalendar.tsx | 4 ++++ pages/api/index.ts | 17 +++++++++-------- pages/dash.tsx | 1 + 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/components/availability/AvailabilityForm.js b/components/availability/AvailabilityForm.js index 3da3063..cd73c80 100644 --- a/components/availability/AvailabilityForm.js +++ b/components/availability/AvailabilityForm.js @@ -212,7 +212,7 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o availability.dayOfMonth = startTime.getDate(); availability.endDate = null; } - + availability.isFromPreviousMonth = false; availability.dateOfEntry = new Date(); } diff --git a/components/calendar/avcalendar.tsx b/components/calendar/avcalendar.tsx index 4bc8225..644dd49 100644 --- a/components/calendar/avcalendar.tsx +++ b/components/calendar/avcalendar.tsx @@ -402,6 +402,10 @@ const AvCalendar = ({ publisherId, events, selectedDate }) => { // orange-500 from Tailwind CSS backgroundColor = '#f56565'; } + if (event.isFromPreviousMonth) { + //gray + backgroundColor = '#a0aec0'; + } if (event.isActive) { switch (event.type) { case 'assignment': diff --git a/pages/api/index.ts b/pages/api/index.ts index f01dfa3..3349dad 100644 --- a/pages/api/index.ts +++ b/pages/api/index.ts @@ -30,7 +30,7 @@ export default async function handler(req, res) { var action = req.query.action; var filter = req.query.filter; - let day: Date, monthInfo: any; + let day: Date; let isExactTime; if (req.query.date) { day = new Date(req.query.date); @@ -42,6 +42,7 @@ export default async function handler(req, res) { isExactTime = true; } + let monthInfo = common.getMonthDatesInfo(day); const searchText = req.query.searchText?.normalize('NFC'); try { @@ -220,6 +221,7 @@ export default async function handler(req, res) { res.status(200).json(shiftsForDate); break; + case "copyOldAvailabilities": //get all publishers that don't have availabilities for the current month monthInfo = common.getMonthDatesInfo(day); @@ -283,12 +285,12 @@ export default async function handler(req, res) { type: AvailabilityType.Monthly, isFromPreviousMonth: true, name: avail.name || "старо предпочитание", - // parentAvailabilityId: avail.id - parentAvailability: { - connect: { - id: avail.id - } - } + parentAvailabilityId: avail.id, + // parentAvailability: { + // connect: { + // id: avail.id + // } + // }, } await prisma.availability.create({ data: data }); @@ -331,7 +333,6 @@ export default async function handler(req, res) { case "updateShifts": //get all shifts for the month and publish them (we pass date ) - let monthInfo = common.getMonthDatesInfo(day); let isPublished = common.parseBool(req.query.isPublished); let updated = await prisma.shift.updateMany({ where: { diff --git a/pages/dash.tsx b/pages/dash.tsx index 71718db..fb3a2f7 100644 --- a/pages/dash.tsx +++ b/pages/dash.tsx @@ -88,6 +88,7 @@ async function getAvailabilities(userId) { name: true, isActive: true, isFromPreviousAssignment: true, + isFromPreviousMonth: true, dayofweek: true, dayOfMonth: true, startTime: true,