From 40e1136e902bf920ab500dca6a2b911e918b9005 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Sun, 31 Mar 2024 18:39:21 +0300 Subject: [PATCH 1/8] auto copying old availabilities leaves dateOfEntry null --- _doc/ToDo.md | 9 +++++++++ pages/api/index.ts | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/_doc/ToDo.md b/_doc/ToDo.md index ae6c5fd..bd32c11 100644 --- a/_doc/ToDo.md +++ b/_doc/ToDo.md @@ -187,3 +187,12 @@ fix availability repeat checks sometimes delete from mycalendar fails saturday shifts start at 12:00 / dymamic +------------------------------- +Add availability type UNAVAILABLE/ AWAY (like Estelle, Rick, Me) + +why "Александра Чернъшова" seems available every shift thursdays? +fix Time ZONE (currently Z, but it leads to shift when the DST changes ( winter entries are shifter in summer)) +защо Марсел Клайнер е червен четв 11 април? - има предпочитания и е в номата +fix repeating availabilities - Tanq kolcjanova only blue first thursday +add assignment in calendar planner +fix database diff --git a/pages/api/index.ts b/pages/api/index.ts index 4aa8313..624d363 100644 --- a/pages/api/index.ts +++ b/pages/api/index.ts @@ -266,7 +266,8 @@ export default async function handler(req, res) { dayOfMonth: null, dayofweek: avail.dayofweek || common.getDayOfWeekNameEnEnum(avail.startTime), weekOfMonth: avail.weekofMonth || common.getWeekOfMonth(avail.startTime), - dateOfEntry: new Date(), //avail.dateOfEntry || avail.startTime, + // null for auto generated availabilities + //dateOfEntry: new Date(), //avail.dateOfEntry || avail.startTime, startTime: newStart, endTime: newEnd, type: AvailabilityType.Monthly, From e5ba7a33a13036ca359007bfe8220fc7f74441aa Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Sun, 31 Mar 2024 20:17:06 +0300 Subject: [PATCH 2/8] refactor .env usage due to unexpexted env values --- .env | 10 ++++---- .env.demo | 4 ++-- .env.development | 9 +++---- .env.homelab | 37 ----------------------------- .env.production | 4 ++-- .env.test | 17 +++++++------ .vscode/launch.json | 4 ++-- package.json | 4 ++-- pages/api/auth/[...nextauth].ts | 2 +- pages/api/shiftgenerate.ts | 2 +- pages/cart/availabilities/index.tsx | 4 ++-- pages/cart/availabilities/new.tsx | 2 +- pages/cart/calendar/index.tsx | 2 +- pages/cart/cartevents/edit/[id].tsx | 4 ++-- pages/cart/cartevents/new.tsx | 4 ++-- pages/cart/locations/[id].tsx | 4 ++-- pages/cart/locations/edit/[id].tsx | 2 +- pages/cart/locations/new.tsx | 2 +- pages/cart/publishers/edit/[id].tsx | 2 +- pages/cart/publishers/new.tsx | 2 +- pages/cart/reports/experience.tsx | 2 +- pages/cart/reports/report.tsx | 2 +- process.d.ts | 2 +- server.js | 12 ++++++---- src/helpers/common.js | 6 +++-- 25 files changed, 53 insertions(+), 92 deletions(-) delete mode 100644 .env.homelab diff --git a/.env b/.env index 5b30dbb..827cefb 100644 --- a/.env +++ b/.env @@ -1,11 +1,9 @@ #NODE_TLS_REJECT_UNAUTHORIZED='0' -SSL_ENABLED=false -NEXT_PUBLIC_PROTOCOL=https -NEXT_PUBLIC_HOST=localhost -NEXT_PUBLIC_PORT=3003 -NEXTAUTH_URL=https://localhost:3003 -# NEXTAUTH_URL_INTERNAL=http://127.0.0.1:3003 +# SSL_ENABLED=false +# NEXT_PUBLIC_HOST=localhost +# NEXT_PUBLIC_PORT=3003 +# PUBLIC_URL=http://localhost:3003 # Linux: `openssl rand -hex 32` or go to https://generate-secret.now.sh/32 NEXTAUTH_SECRET=ed8a9681efc414df89dfd03cd188ed58 diff --git a/.env.demo b/.env.demo index 17f98ce..02a1a51 100644 --- a/.env.demo +++ b/.env.demo @@ -1,7 +1,7 @@ -NEXT_PUBLIC_PROTOCOL=https +SSL_ENABLED=false NEXT_PUBLIC_PORT= NEXT_PUBLIC_HOST=staging.mwhitnessing.com -NEXTAUTH_URL= https://staging.mwhitnessing.com +PUBLIC_URL=https://staging.mwhitnessing.com # Linux: `openssl rand -hex 32` or go to https://generate-secret.now.sh/32 NEXTAUTH_SECRET=1dd8a5457970d1dda50600be28e935ecc4513ff27c49c431849e6746f158d638 diff --git a/.env.development b/.env.development index afec269..4167c2c 100644 --- a/.env.development +++ b/.env.development @@ -1,15 +1,12 @@ NODE_TLS_REJECT_UNAUTHORIZED=0 # NODE_EXTRA_CA_CERTS=C:\\Users\\popov\\AppData\\Local\\mkcert - -NEXT_PUBLIC_PROTOCOL=https +PROTOCOL=https NEXT_PUBLIC_HOST=localhost NEXT_PUBLIC_PORT=3003 -NEXTAUTH_URL=https://localhost:3003 +PUBLIC_URL=https://localhost:3003 -SSL_ENABLED=true -TELEGRAM_BOT=true SSL_KEY=./certificates/localhost-key.pem SSL_CERT=./certificates/localhost.pem DATABASE_URL=mysql://root:Zelen0ku4e@192.168.0.10:3306/cart_dev -# DATABASE_URL=mysql://cart:cartpw@localhost:3306/cart +# DATABASE_URL=mysql://cart:cartpw@localhost:3306/cart \ No newline at end of file diff --git a/.env.homelab b/.env.homelab deleted file mode 100644 index 2a2aa9a..0000000 --- a/.env.homelab +++ /dev/null @@ -1,37 +0,0 @@ -NODE_TLS_REJECT_UNAUTHORIZED='0' -# DATABASE_URL="file:./src/data/dev.db" -# DATABASE_URL="mysql://root:Zelen0ku4e@192.168.0.10:3306/cart" - -NEXT_PUBLIC_PORT= -# NEXT_PUBLIC_NEXTAUTH_URL=https://cart.d-popov.com -NEXT_PUBLIC_PROTOCOL=https -NEXT_PUBLIC_HOST=cart.d-popov.com -NEXTAUTH_URL=https://cart.d-popov.com -# NEXTAUTH_URL= https://demo.mwhitnessing.com - -# Linux: `openssl rand -hex 32` or go to https://generate-secret.now.sh/32 -NEXTAUTH_SECRET=ed8a9681efc414df89dfd03cd188ed58 -DATABASE_URL=mysql://cart:cart2023@192.168.0.10:3306/cart_demo - -APPLE_ID= -APPLE_TEAM_ID= -APPLE_PRIVATE_KEY= -APPLE_KEY_ID= - -AUTH0_ID=Aa9f3HJowauUrmBVY4iQzQJ7fYsaZDbK -AUTH0_SECRET=_c0O9GkyRXkoWMQW7jNExnl6UoXN6O4oD3mg7NZ_uHVeAinCUtcTAkeQmcKXpZ4x -AUTH0_ISSUER=https://dev-wkzi658ckibr1amv.us.auth0.com - -FACEBOOK_ID= -FACEBOOK_SECRET= - -GITHUB_ID= -GITHUB_SECRET= -# GOOGLE_ID=926212607479-d3m8hm8f8esp3rf1639prskn445sa01v.apps.googleusercontent.com -# GOOGLE_SECRET=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 - -TWITTER_ID= -TWITTER_SECRET= - -EMAIL_SERVER=smtp://8ec69527ff2104:c7bc05f171c96c@smtp.mailtrap.io:2525 -EMAIL_FROM=noreply@example.com diff --git a/.env.production b/.env.production index a3438f2..3f4db06 100644 --- a/.env.production +++ b/.env.production @@ -1,7 +1,7 @@ -NEXT_PUBLIC_PROTOCOL=https NEXT_PUBLIC_PORT= NEXT_PUBLIC_HOST=sofia.mwhitnessing.com -NEXTAUTH_URL= https://sofia.mwhitnessing.com +SSL_ENABLED=false # we're behind a reverse proxy. SSL is handled by the proxy +PUBLIC_URL= https://sofia.mwhitnessing.com # Linux: `openssl rand -hex 32` or go to https://generate-secret.now.sh/32 NEXTAUTH_SECRET=1dd8a5457970d1dda50600be28e935ecc4513ff27c49c431849e6746f158d638 diff --git a/.env.test b/.env.test index 1b9eef8..44c7087 100644 --- a/.env.test +++ b/.env.test @@ -1,13 +1,15 @@ NODE_TLS_REJECT_UNAUTHORIZED='0' +# DATABASE_URL="file:./src/data/dev.db" +# DATABASE_URL="mysql://root:Zelen0ku4e@192.168.0.10:3306/cart" -NEXT_PUBLIC_PORT=5001 -NEXT_PUBLIC_PROTOCOL=https +SSL_ENABLED=true +NEXT_PUBLIC_PORT= NEXT_PUBLIC_HOST=cart.d-popov.com -NEXTAUTH_URL=https://cart.d-popov.com +PUBLIC_URL=https://cart.d-popov.com # Linux: `openssl rand -hex 32` or go to https://generate-secret.now.sh/32 NEXTAUTH_SECRET=ed8a9681efc414df89dfd03cd188ed58 -DATABASE_URL=mysql://cart:cartpw@192.168.0.10:3306/cart_dev +DATABASE_URL=mysql://cart:cart2023@192.168.0.10:3306/cart_demo APPLE_ID= APPLE_TEAM_ID= @@ -23,14 +25,11 @@ FACEBOOK_SECRET= GITHUB_ID= GITHUB_SECRET= -GOOGLE_ID=926212607479-d3m8hm8f8esp3rf1639prskn445sa01v.apps.googleusercontent.com -GOOGLE_SECRET=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 +# GOOGLE_ID=926212607479-d3m8hm8f8esp3rf1639prskn445sa01v.apps.googleusercontent.com +# GOOGLE_SECRET=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 TWITTER_ID= TWITTER_SECRET= EMAIL_SERVER=smtp://8ec69527ff2104:c7bc05f171c96c@smtp.mailtrap.io:2525 EMAIL_FROM=noreply@example.com - -GMAIL_EMAIL_USERNAME= -GMAIL_EMAIL_APP_PASS= diff --git a/.vscode/launch.json b/.vscode/launch.json index b11332d..963bb15 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,7 +6,7 @@ "configurations": [ { "name": "Run npm nodemon (DEV)", - "command": "npm run debug-env", + "command": "npm run debug", "request": "launch", "type": "node-terminal", "preLaunchTask": "killInspector", @@ -35,7 +35,7 @@ "request": "launch", "type": "node-terminal", "cwd": "${workspaceFolder}", - "command": "conda activate node && npm run debug-env", + "command": "conda activate node && npm run debug", }, { "name": "Run conda npm TEST", diff --git a/package.json b/package.json index 296bcf9..ce05476 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "homepage": "https://git.d-popov.com/popov/next-cart-app", "scripts": { "debug": "nodemon --inspect server.js", - "debug-env": "cross-env NODE_ENV=development dotenv -e .env.development -- nodemon --inspect server.js", + "debug-env-dev": "dotenv -e .env.development -- nodemon --inspect server.js", "build": "next build", "buildWin": "npm run build", "start": "next start", @@ -109,4 +109,4 @@ "depcheck": "^1.4.7", "prisma": "^5.11.0" } -} +} \ No newline at end of file diff --git a/pages/api/auth/[...nextauth].ts b/pages/api/auth/[...nextauth].ts index 764362a..e0acd8a 100644 --- a/pages/api/auth/[...nextauth].ts +++ b/pages/api/auth/[...nextauth].ts @@ -24,7 +24,7 @@ import { isLoggedIn, setAuthTokens, clearAuthTokens, getAccessToken, getRefreshT export const authOptions: NextAuthOptions = { // https://next-auth.js.org/configuration/providers/oauth - site: process.env.NEXTAUTH_URL, + site: process.env.PUBLIC_URL, secret: process.env.NEXTAUTH_SECRET, // Ensure you have this set in your .env file //adapter: PrismaAdapter(prisma), providers: [ diff --git a/pages/api/shiftgenerate.ts b/pages/api/shiftgenerate.ts index 4d44052..409d580 100644 --- a/pages/api/shiftgenerate.ts +++ b/pages/api/shiftgenerate.ts @@ -444,7 +444,7 @@ async function GenerateSchedule(axios: Axios, date: string, copyFromPreviousMont } //create shifts using API - // const { data: createdShifts } = await axios.post(`${process.env.NEXTAUTH_URL}/api/data/shifts`, shiftsToCreate); + // const { data: createdShifts } = await axios.post(`${process.env.PUBLIC_URL}/api/data/shifts`, shiftsToCreate); //const { data: allshifts } = await axios.get(`/api/data/shifts`); return {}; //allshifts; diff --git a/pages/cart/availabilities/index.tsx b/pages/cart/availabilities/index.tsx index 0cd158a..23a14c1 100644 --- a/pages/cart/availabilities/index.tsx +++ b/pages/cart/availabilities/index.tsx @@ -133,7 +133,7 @@ export const getServerSideProps = async (context) => { const role = session?.user.role; console.log("server role: " + role); - var queryUrl = process.env.NEXTAUTH_URL + "/api/data/availabilities?select=id,name,isActive,dayofweek,dayOfMonth,startTime,endTime,publisher.firstName,publisher.lastName,publisher.id"; + var queryUrl = process.env.PUBLIC_URL + "/api/data/availabilities?select=id,name,isActive,dayofweek,dayOfMonth,startTime,endTime,publisher.firstName,publisher.lastName,publisher.id"; if (role === UserRole.USER || context.query.my) { queryUrl += `&where={"publisherId":"${session?.user.id}"}`; } else if (role == UserRole.ADMIN) { @@ -145,7 +145,7 @@ export const getServerSideProps = async (context) => { } var resp = await axios.get( queryUrl - // process.env.NEXTAUTH_URL + "/api/data/availabilities?include=publisher", + // process.env.PUBLIC_URL + "/api/data/availabilities?include=publisher", , { decompress: true }); var items = resp.data; console.log("got " + items.length + " availabilities"); diff --git a/pages/cart/availabilities/new.tsx b/pages/cart/availabilities/new.tsx index f281459..e10fd2b 100644 --- a/pages/cart/availabilities/new.tsx +++ b/pages/cart/availabilities/new.tsx @@ -31,7 +31,7 @@ export const getServerSideProps = async (context) => { }; } const { data: item } = await axios.get( - process.env.NEXTAUTH_URL + "/api/data/availabilities/" + context.params.id + process.env.PUBLIC_URL + "/api/data/availabilities/" + context.params.id ); return { diff --git a/pages/cart/calendar/index.tsx b/pages/cart/calendar/index.tsx index 7a77aec..594c22e 100644 --- a/pages/cart/calendar/index.tsx +++ b/pages/cart/calendar/index.tsx @@ -893,7 +893,7 @@ export const getServerSideProps = async (context) => { const axios = await axiosServer(context); const baseUrl = common.getBaseUrl(); console.log('runtime BaseUrl: ' + baseUrl); - console.log('runtime NEXTAUTH_URL: ' + process.env.NEXTAUTH_URL); + console.log('runtime PUBLIC_URL: ' + process.env.PUBLIC_URL); console.log('Runtime Axios Base URL:', axios.defaults.baseURL); const currentDate = new Date(); diff --git a/pages/cart/cartevents/edit/[id].tsx b/pages/cart/cartevents/edit/[id].tsx index 81fca35..08b8428 100644 --- a/pages/cart/cartevents/edit/[id].tsx +++ b/pages/cart/cartevents/edit/[id].tsx @@ -7,9 +7,9 @@ export const getServerSideProps = async (context) => { console.log("edit page getServerSideProps"); const axios = await axiosServer(context); const { id } = context.query; - const { data } = await axios.get(`${process.env.NEXTAUTH_URL}/api/data/cartevents/` + id); + const { data } = await axios.get(`${process.env.PUBLIC_URL}/api/data/cartevents/` + id); const locations = await axios - .get(`${process.env.NEXTAUTH_URL}/api/data/locations?select=id,name`) + .get(`${process.env.PUBLIC_URL}/api/data/locations?select=id,name`) .then((res) => { console.log("locations: " + JSON.stringify(res.data)); return res.data; diff --git a/pages/cart/cartevents/new.tsx b/pages/cart/cartevents/new.tsx index 0503430..522f489 100644 --- a/pages/cart/cartevents/new.tsx +++ b/pages/cart/cartevents/new.tsx @@ -26,7 +26,7 @@ export const getServerSideProps = async (context) => { const axios = await axiosServer(context); const locations = await axios - .get(`${process.env.NEXTAUTH_URL}/api/data/locations?select=id,name`) + .get(`${process.env.PUBLIC_URL}/api/data/locations?select=id,name`) .then((res) => { console.log("locations: " + JSON.stringify(res.data)); return res.data; @@ -41,7 +41,7 @@ export const getServerSideProps = async (context) => { const { id } = context.query.id; const { data: item } = await axiosInstance.get( - process.env.NEXTAUTH_URL + "/api/data/cartevents/" + context.params.id + process.env.PUBLIC_URL + "/api/data/cartevents/" + context.params.id ); return { diff --git a/pages/cart/locations/[id].tsx b/pages/cart/locations/[id].tsx index f66a6bc..523478b 100644 --- a/pages/cart/locations/[id].tsx +++ b/pages/cart/locations/[id].tsx @@ -99,11 +99,11 @@ export const getServerSideProps: GetServerSideProps = async (context) => { const axios = await axiosServer(context); const { data: location } = await axios.get( - `${process.env.NEXTAUTH_URL}/api/data/locations/${context.params.id}` + `${process.env.PUBLIC_URL}/api/data/locations/${context.params.id}` ); if (location.backupLocationId !== null) { const { data: backupLocation } = await axios.get( - process.env.NEXTAUTH_URL + "/api/data/locations/" + location.backupLocationId + process.env.PUBLIC_URL + "/api/data/locations/" + location.backupLocationId ); location.backupLocationName = backupLocation.name; location.backupLocationContent = backupLocation ? backupLocation.content : ""; diff --git a/pages/cart/locations/edit/[id].tsx b/pages/cart/locations/edit/[id].tsx index ef1b7b8..90ba81f 100644 --- a/pages/cart/locations/edit/[id].tsx +++ b/pages/cart/locations/edit/[id].tsx @@ -29,7 +29,7 @@ export const getServerSideProps = async (context) => { }; } const { data: item } = await axios.get( - process.env.NEXTAUTH_URL + "/api/data/locations/" + context.params.id + process.env.PUBLIC_URL + "/api/data/locations/" + context.params.id ); console.log(item) //this is the location object context.res.setHeader("Cache-Control", "s-maxage=1, stale-while-revalidate"); diff --git a/pages/cart/locations/new.tsx b/pages/cart/locations/new.tsx index be77ea0..e1c7137 100644 --- a/pages/cart/locations/new.tsx +++ b/pages/cart/locations/new.tsx @@ -32,7 +32,7 @@ export const getServerSideProps = async (context) => { } const { data: loc } = await axios.get( - `${process.env.NEXTAUTH_URL}api/data/locations/` + context.params.id + `${process.env.PUBLIC_URL}api/data/locations/` + context.params.id ); console.log(location) //this is the location object context.res.setHeader("Cache-Control", "s-maxage=1, stale-while-revalidate"); diff --git a/pages/cart/publishers/edit/[id].tsx b/pages/cart/publishers/edit/[id].tsx index 680fb41..484910f 100644 --- a/pages/cart/publishers/edit/[id].tsx +++ b/pages/cart/publishers/edit/[id].tsx @@ -44,7 +44,7 @@ export const getServerSideProps = async (context) => { props: {} }; } - var url = process.env.NEXTAUTH_URL + "/api/data/publishers/" + context.query.id + "?include=availabilities,assignments,assignments.shift"; + var url = process.env.PUBLIC_URL + "/api/data/publishers/" + context.query.id + "?include=availabilities,assignments,assignments.shift"; console.log("GET PUBLISHER FROM:" + url) const { data: item } = await axios.get(url); diff --git a/pages/cart/publishers/new.tsx b/pages/cart/publishers/new.tsx index fb99ae4..f9f62fb 100644 --- a/pages/cart/publishers/new.tsx +++ b/pages/cart/publishers/new.tsx @@ -47,7 +47,7 @@ export const getServerSideProps = async (context) => { props: {} }; } - var url = process.env.NEXTAUTH_URL + "/api/data/publishers/" + context.query.id + "?include=availabilities,shifts"; + var url = process.env.PUBLIC_URL + "/api/data/publishers/" + context.query.id + "?include=availabilities,shifts"; console.log("GET PUBLISHER FROM:" + url) const { data } = await axios.get(url); diff --git a/pages/cart/reports/experience.tsx b/pages/cart/reports/experience.tsx index 5cb4db8..c41079a 100644 --- a/pages/cart/reports/experience.tsx +++ b/pages/cart/reports/experience.tsx @@ -32,7 +32,7 @@ export const getServerSideProps = async (context) => { // }; // } // const { data: loc } = await axiosInstance.get( - // `${process.env.NEXTAUTH_URL}api/data/locations/` + context.params.id + // `${process.env.PUBLIC_URL}api/data/locations/` + context.params.id // ); // console.log(location) //this is the location object diff --git a/pages/cart/reports/report.tsx b/pages/cart/reports/report.tsx index ef3b971..b416704 100644 --- a/pages/cart/reports/report.tsx +++ b/pages/cart/reports/report.tsx @@ -33,7 +33,7 @@ export const getServerSideProps = async (context) => { // } // const { data: loc } = await axiosInstance.get( - // `${process.env.NEXTAUTH_URL}api/data/locations/` + context.params.id + // `${process.env.PUBLIC_URL}api/data/locations/` + context.params.id // ); // console.log(location) //this is the location object // context.res.setHeader("Cache-Control", "s-maxage=1, stale-while-revalidate"); diff --git a/process.d.ts b/process.d.ts index b140ecb..b31f4de 100644 --- a/process.d.ts +++ b/process.d.ts @@ -1,6 +1,6 @@ declare namespace NodeJS { export interface ProcessEnv { - NEXTAUTH_URL: string + PUBLIC_URL: string NEXTAUTH_SECRET: string GITHUB_ID: string GITHUB_SECRET: string diff --git a/server.js b/server.js index 82128dd..61eb531 100644 --- a/server.js +++ b/server.js @@ -28,21 +28,23 @@ let baseUrlGlobal; // require('dotenv').config(); // } -console.log("initial process.env.NODE_ENV = ", process.env.NODE_ENV); +console.log("initial process.env.NODE_ENV = ", process.env.NODE_ENV); //NODE_ENV can be passed as docker param require('dotenv').config({ path: `.env.${process.env.NODE_ENV}` }); console.log("process.env.NODE_ENV = ", process.env.NODE_ENV); +const PROTOCOL = process.env.PROTOCOL; const PORT = process.env.NEXT_PUBLIC_PORT || 3000; const HOST = process.env.NEXT_PUBLIC_HOST; +const LOAD_CERTS = process.env.PROTOCOL === 'https'; + const dev = process.env.NODE_ENV !== "production"; -const PROTOCOL = process.env.NEXT_PUBLIC_PROTOCOL; const nextApp = next({ dev }); const nextHandler = nextApp.getRequestHandler(); -console.log("process.env.SSL_ENABLED = ", process.env.SSL_ENABLED); -console.log("process.env.NEXTAUTH_URL = ", process.env.NEXTAUTH_URL); +console.log("process.env.PROTOCOL = ", process.env.PROTOCOL); +console.log("process.env.PUBLIC_URL = ", process.env.PUBLIC_URL); console.log("process.env.NEXT_PUBLIC_PORT = ", process.env.NEXT_PUBLIC_PORT); console.log("process.env.TELEGRAM_BOT = ", process.env.TELEGRAM_BOT); @@ -559,7 +561,7 @@ nextApp }); //check if ssl is enabled - if (process.env.SSL_ENABLED === "true") { + if (LOAD_CERTS) { console.log("SSL_ENABLED = true"); // Redirect from http to https // server.use((req, res, next) => { diff --git a/src/helpers/common.js b/src/helpers/common.js index a72ab2f..288f906 100644 --- a/src/helpers/common.js +++ b/src/helpers/common.js @@ -78,8 +78,8 @@ exports.setBaseUrl = function (req) { exports.getBaseUrl = function (relative = "", req = null) { if (typeof window === 'undefined') { // Server-side logic - // Read the base URL from env (NEXTAUTH_URL): - return process.env.NEXTAUTH_URL + relative; + // Read the base URL from env (PUBLIC_URL): + return process.env.PUBLIC_URL + relative; // const filePath = path.join(__dirname, 'baseUrl.txt'); @@ -122,6 +122,8 @@ exports.getPrismaClient = function getPrismaClient() { datasources: { db: { url: process.env.DATABASE_URL } }, }); } + logger.debug("getPrismaClient: process.env.DATABASE_URL = ", process.env.DATABASE_URL); + return prisma; } From d47297e2f7d998788f2f18ec6a89b5dbc2fb6fe7 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Mon, 1 Apr 2024 09:50:28 +0300 Subject: [PATCH 3/8] more ENV refactoring --- .env.development | 2 +- next.config.js | 2 +- server.js | 57 ++++++++++++++++++++++++------------------------ 3 files changed, 30 insertions(+), 31 deletions(-) diff --git a/.env.development b/.env.development index 4167c2c..9204bc9 100644 --- a/.env.development +++ b/.env.development @@ -1,6 +1,6 @@ NODE_TLS_REJECT_UNAUTHORIZED=0 # NODE_EXTRA_CA_CERTS=C:\\Users\\popov\\AppData\\Local\\mkcert -PROTOCOL=https +NEXT_PUBLIC_PROTOCOL=https NEXT_PUBLIC_HOST=localhost NEXT_PUBLIC_PORT=3003 PUBLIC_URL=https://localhost:3003 diff --git a/next.config.js b/next.config.js index 2bc690b..865380e 100644 --- a/next.config.js +++ b/next.config.js @@ -12,7 +12,7 @@ module.exports = { pageExtensions: ['ts', 'tsx', 'md', 'mdx'], // Replace `jsx?` with `tsx?` env: { env: process.env.NODE_ENV, - server: 'http://' + process.env.NEXT_PUBLIC_HOST + ':' + process.env.NEXT_PUBLIC_PORT + '', + server: process.env.NEXT_PUBLIC_PROTOCOL + '://' + process.env.NEXT_PUBLIC_HOST + ':' + process.env.NEXT_PUBLIC_PORT + '', }, webpack(config, { isServer }) { diff --git a/server.js b/server.js index 61eb531..21637f2 100644 --- a/server.js +++ b/server.js @@ -35,15 +35,14 @@ require('dotenv').config({ console.log("process.env.NODE_ENV = ", process.env.NODE_ENV); -const PROTOCOL = process.env.PROTOCOL; +const PROTOCOL = process.env.NEXT_PUBLIC_PROTOCOL; const PORT = process.env.NEXT_PUBLIC_PORT || 3000; const HOST = process.env.NEXT_PUBLIC_HOST; -const LOAD_CERTS = process.env.PROTOCOL === 'https'; const dev = process.env.NODE_ENV !== "production"; const nextApp = next({ dev }); const nextHandler = nextApp.getRequestHandler(); -console.log("process.env.PROTOCOL = ", process.env.PROTOCOL); +console.log("process.env.NEXT_PUBLIC_PROTOCOL = ", process.env.NEXT_PUBLIC_PROTOCOL); console.log("process.env.PUBLIC_URL = ", process.env.PUBLIC_URL); console.log("process.env.NEXT_PUBLIC_PORT = ", process.env.NEXT_PUBLIC_PORT); console.log("process.env.TELEGRAM_BOT = ", process.env.TELEGRAM_BOT); @@ -64,12 +63,37 @@ const uploadTmp = multer({ storage: storageMem }); const prisma = common.getPrismaClient(); +const server = express(); +//check if ssl is enabled +if (process.env.NEXT_PUBLIC_PROTOCOL === 'https') { + console.log("SSL_ENABLED = true"); + // Redirect from http to https + // server.use((req, res, next) => { + // if (req.headers['x-forwarded-proto'] !== 'https') { + // return res.redirect(`https://${req.headers.host}${req.url}`); + // } + // next(); + // }); + if (process.env.SSL_KEY && process.env.SSL_CERT) { + const options = { + key: fs.readFileSync(process.env.SSL_KEY), + cert: fs.readFileSync(process.env.SSL_CERT), + secureProtocol: 'TLSv1_2_method', // Example: Force TLS 1.2 + }; + https.createServer(options, server).listen(PORT); + } +} +else { + server.listen(PORT, (err) => { + if (err) throw err; + console.log(`> Ready on ${PROTOCOL}://${HOST}:${PORT}`); + }); +} // handlers nextApp .prepare() .then(() => { - const server = express(); // Add the middleware to set 'x-forwarded-host' header server.use((req, res, next) => { @@ -560,31 +584,6 @@ nextApp return nextHandler(req, res); }); - //check if ssl is enabled - if (LOAD_CERTS) { - console.log("SSL_ENABLED = true"); - // Redirect from http to https - // server.use((req, res, next) => { - // if (req.headers['x-forwarded-proto'] !== 'https') { - // return res.redirect(`https://${req.headers.host}${req.url}`); - // } - // next(); - // }); - if (process.env.SSL_KEY && process.env.SSL_CERT) { - const options = { - key: fs.readFileSync(process.env.SSL_KEY), - cert: fs.readFileSync(process.env.SSL_CERT), - secureProtocol: 'TLSv1_2_method', // Example: Force TLS 1.2 - }; - https.createServer(options, server).listen(PORT); - } - } - else { - server.listen(PORT, (err) => { - if (err) throw err; - console.log(`> Ready on ${PROTOCOL}://${HOST}:${PORT}`); - }); - } }) .catch((ex) => { console.warn(`Error starting server on ${HOST}:${PORT}`) From f83a3e9bd918572a1ee4f380b5c51752b5387556 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Mon, 1 Apr 2024 11:11:23 +0300 Subject: [PATCH 4/8] staging has standard test environment now --- .env.development | 2 +- .env.test | 15 ++++++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/.env.development b/.env.development index 9204bc9..8029d98 100644 --- a/.env.development +++ b/.env.development @@ -1,8 +1,8 @@ NODE_TLS_REJECT_UNAUTHORIZED=0 # NODE_EXTRA_CA_CERTS=C:\\Users\\popov\\AppData\\Local\\mkcert NEXT_PUBLIC_PROTOCOL=https -NEXT_PUBLIC_HOST=localhost NEXT_PUBLIC_PORT=3003 +NEXT_PUBLIC_HOST=localhost PUBLIC_URL=https://localhost:3003 SSL_KEY=./certificates/localhost-key.pem diff --git a/.env.test b/.env.test index 44c7087..78ba247 100644 --- a/.env.test +++ b/.env.test @@ -1,15 +1,12 @@ -NODE_TLS_REJECT_UNAUTHORIZED='0' -# DATABASE_URL="file:./src/data/dev.db" -# DATABASE_URL="mysql://root:Zelen0ku4e@192.168.0.10:3306/cart" - -SSL_ENABLED=true +NEXT_PUBLIC_PROTOCOL=http NEXT_PUBLIC_PORT= -NEXT_PUBLIC_HOST=cart.d-popov.com -PUBLIC_URL=https://cart.d-popov.com +NEXT_PUBLIC_HOST=staging.mwhitnessing.com +PUBLIC_URL=https://staging.mwhitnessing.com # Linux: `openssl rand -hex 32` or go to https://generate-secret.now.sh/32 -NEXTAUTH_SECRET=ed8a9681efc414df89dfd03cd188ed58 -DATABASE_URL=mysql://cart:cart2023@192.168.0.10:3306/cart_demo +NEXTAUTH_SECRET=1dd8a5457970d1dda50600be28e935ecc4513ff27c49c431849e6746f158d638 +# ? do we need to duplicate this? already defined in the deoployment yml file +DATABASE_URL=mysql://jwpwsofia_demo:dwxhns9p9vp248@mariadb:3306/jwpwsofia_demo APPLE_ID= APPLE_TEAM_ID= From f488fa971a2e360959fa28aa7236a16b6efdba37 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Mon, 1 Apr 2024 11:12:00 +0300 Subject: [PATCH 5/8] fix and simplify baseurl --- .env | 8 +++----- .env.demo | 9 --------- .env.development | 8 ++++---- .env.production | 8 ++++---- .env.test | 8 ++++---- next.config.js | 2 +- server.js | 14 +++++++------- src/helpers/common.js | 34 +--------------------------------- 8 files changed, 24 insertions(+), 67 deletions(-) delete mode 100644 .env.demo diff --git a/.env b/.env index 827cefb..eec3b83 100644 --- a/.env +++ b/.env @@ -1,9 +1,7 @@ - #NODE_TLS_REJECT_UNAUTHORIZED='0' -# SSL_ENABLED=false -# NEXT_PUBLIC_HOST=localhost -# NEXT_PUBLIC_PORT=3003 -# PUBLIC_URL=http://localhost:3003 +# HOST=localhost +# PORT=3003 +# NEXT_PUBLIC_PUBLIC_URL=http://localhost:3003 # Linux: `openssl rand -hex 32` or go to https://generate-secret.now.sh/32 NEXTAUTH_SECRET=ed8a9681efc414df89dfd03cd188ed58 diff --git a/.env.demo b/.env.demo deleted file mode 100644 index 02a1a51..0000000 --- a/.env.demo +++ /dev/null @@ -1,9 +0,0 @@ -SSL_ENABLED=false -NEXT_PUBLIC_PORT= -NEXT_PUBLIC_HOST=staging.mwhitnessing.com -PUBLIC_URL=https://staging.mwhitnessing.com - -# Linux: `openssl rand -hex 32` or go to https://generate-secret.now.sh/32 -NEXTAUTH_SECRET=1dd8a5457970d1dda50600be28e935ecc4513ff27c49c431849e6746f158d638 -# ? do we need to duplicate this? already defined in the deoployment yml file -DATABASE_URL=mysql://jwpwsofia_demo:dwxhns9p9vp248@mariadb:3306/jwpwsofia_demo \ No newline at end of file diff --git a/.env.development b/.env.development index 8029d98..21fcc42 100644 --- a/.env.development +++ b/.env.development @@ -1,9 +1,9 @@ NODE_TLS_REJECT_UNAUTHORIZED=0 # NODE_EXTRA_CA_CERTS=C:\\Users\\popov\\AppData\\Local\\mkcert -NEXT_PUBLIC_PROTOCOL=https -NEXT_PUBLIC_PORT=3003 -NEXT_PUBLIC_HOST=localhost -PUBLIC_URL=https://localhost:3003 +PROTOCOL=https +PORT=3003 +HOST=localhost +NEXT_PUBLIC_PUBLIC_URL=https://localhost:3003 SSL_KEY=./certificates/localhost-key.pem SSL_CERT=./certificates/localhost.pem diff --git a/.env.production b/.env.production index 3f4db06..8f9c4eb 100644 --- a/.env.production +++ b/.env.production @@ -1,7 +1,7 @@ -NEXT_PUBLIC_PORT= -NEXT_PUBLIC_HOST=sofia.mwhitnessing.com -SSL_ENABLED=false # we're behind a reverse proxy. SSL is handled by the proxy -PUBLIC_URL= https://sofia.mwhitnessing.com +PORT= +HOST=sofia.mwhitnessing.com +PROTOCOL=http # we're behind a reverse proxy. SSL is handled by the proxy +NEXT_PUBLIC_PUBLIC_URL= https://sofia.mwhitnessing.com # Linux: `openssl rand -hex 32` or go to https://generate-secret.now.sh/32 NEXTAUTH_SECRET=1dd8a5457970d1dda50600be28e935ecc4513ff27c49c431849e6746f158d638 diff --git a/.env.test b/.env.test index 78ba247..0fbca9e 100644 --- a/.env.test +++ b/.env.test @@ -1,7 +1,7 @@ -NEXT_PUBLIC_PROTOCOL=http -NEXT_PUBLIC_PORT= -NEXT_PUBLIC_HOST=staging.mwhitnessing.com -PUBLIC_URL=https://staging.mwhitnessing.com +PROTOCOL=http +HOST=staging.mwhitnessing.com +PORT= +NEXT_PUBLIC_PUBLIC_URL=https://staging.mwhitnessing.com # Linux: `openssl rand -hex 32` or go to https://generate-secret.now.sh/32 NEXTAUTH_SECRET=1dd8a5457970d1dda50600be28e935ecc4513ff27c49c431849e6746f158d638 diff --git a/next.config.js b/next.config.js index 865380e..32d4f12 100644 --- a/next.config.js +++ b/next.config.js @@ -12,7 +12,7 @@ module.exports = { pageExtensions: ['ts', 'tsx', 'md', 'mdx'], // Replace `jsx?` with `tsx?` env: { env: process.env.NODE_ENV, - server: process.env.NEXT_PUBLIC_PROTOCOL + '://' + process.env.NEXT_PUBLIC_HOST + ':' + process.env.NEXT_PUBLIC_PORT + '', + server: process.env.NEXT_PUBLIC_PUBLIC_URL }, webpack(config, { isServer }) { diff --git a/server.js b/server.js index 21637f2..c48323b 100644 --- a/server.js +++ b/server.js @@ -35,16 +35,16 @@ require('dotenv').config({ console.log("process.env.NODE_ENV = ", process.env.NODE_ENV); -const PROTOCOL = process.env.NEXT_PUBLIC_PROTOCOL; -const PORT = process.env.NEXT_PUBLIC_PORT || 3000; -const HOST = process.env.NEXT_PUBLIC_HOST; +const PROTOCOL = process.env.PROTOCOL; +const PORT = process.env.PORT || 3000; +const HOST = process.env.HOST; const dev = process.env.NODE_ENV !== "production"; const nextApp = next({ dev }); const nextHandler = nextApp.getRequestHandler(); -console.log("process.env.NEXT_PUBLIC_PROTOCOL = ", process.env.NEXT_PUBLIC_PROTOCOL); -console.log("process.env.PUBLIC_URL = ", process.env.PUBLIC_URL); -console.log("process.env.NEXT_PUBLIC_PORT = ", process.env.NEXT_PUBLIC_PORT); +console.log("process.env.PROTOCOL = ", process.env.PROTOCOL); +console.log("process.env.PUBLIC_URL = ", process.env.NEXT_PUBLIC_PUBLIC_URL); +console.log("process.env.PORT = ", process.env.PORT); console.log("process.env.TELEGRAM_BOT = ", process.env.TELEGRAM_BOT); //require('module-alias/register'); @@ -66,7 +66,7 @@ const prisma = common.getPrismaClient(); const server = express(); //check if ssl is enabled -if (process.env.NEXT_PUBLIC_PROTOCOL === 'https') { +if (process.env.PROTOCOL === 'https') { console.log("SSL_ENABLED = true"); // Redirect from http to https // server.use((req, res, next) => { diff --git a/src/helpers/common.js b/src/helpers/common.js index 288f906..e580a4b 100644 --- a/src/helpers/common.js +++ b/src/helpers/common.js @@ -76,39 +76,7 @@ exports.setBaseUrl = function (req) { }; exports.getBaseUrl = function (relative = "", req = null) { - if (typeof window === 'undefined') { - // Server-side logic - // Read the base URL from env (PUBLIC_URL): - return process.env.PUBLIC_URL + relative; - - // const filePath = path.join(__dirname, 'baseUrl.txt'); - - // try { - // if (fs.existsSync(filePath)) { - // const baseUrl = fs.readFileSync(filePath, 'utf8').trim(); - // const fullUrl = relative ? new URL(relative, baseUrl).toString() : baseUrl; - // return fullUrl; - // } else { - // if (req) { - // // Assuming setBaseUrl is defined somewhere in this file - // const baseUrl = exports.setBaseUrl(req); - // return `${baseUrl}/${relative.replace(/^\/|\/$/g, '')}`; - // } - // console.log('Base URL file does not exist.'); - // return null; - // } - // } catch (error) { - // console.error('Error reading the base URL file:', error); - // return null; - // } - } else { - // Client-side logic - // Fetch the base URL from the server endpoint you've set up - const baseUrl = window.location.origin; - const fullUrl = relative ? `${baseUrl}/${relative.replace(/^\/|\/$/g, '')}` : baseUrl; - //console.log("getBaseUrl()=", fullUrl); - return fullUrl.toString(); - } + return process.env.NEXT_PUBLIC_PUBLIC_URL + relative; }; From 5a658d4e19c615aff33a22953e26331f69cb8d50 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Mon, 1 Apr 2024 13:05:35 +0300 Subject: [PATCH 6/8] fix availability ui bug --- components/availability/AvailabilityForm.js | 58 ++++++++++++------- .../AvailabilityFormDatePicker.js | 4 +- pages/api/index.ts | 10 +++- 3 files changed, 49 insertions(+), 23 deletions(-) diff --git a/components/availability/AvailabilityForm.js b/components/availability/AvailabilityForm.js index 19d09a4..868ccc1 100644 --- a/components/availability/AvailabilityForm.js +++ b/components/availability/AvailabilityForm.js @@ -1,5 +1,5 @@ import axiosInstance from '../../src/axiosSecure'; -import { useEffect, useState, useCallback } from "react"; +import { useEffect, useState, useCallback, use } from "react"; import toast from "react-hot-toast"; import { useRouter } from "next/router"; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; @@ -26,9 +26,6 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o const [editMode, setEditMode] = useState(existingItems.length > 0); const [publisher, setPublisher] = useState({ id: publisherId }); const [day, setDay] = useState(new Date(date)); - const [doRepeat, setDoRepeat] = useState(false); - const [repeatFrequency, setRepeatFrequency] = useState(1); - const [repeatUntil, setRepeatUntil] = useState(null); const [canUpdate, setCanUpdate] = useState(true); const [timeSlots, setTimeSlots] = useState([]); @@ -46,6 +43,10 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o isLast: false, }]); + const [doRepeat, setDoRepeat] = useState(existingItems && existingItems.length > 0 ? existingItems[0].repeatWeekly : false); + const [repeatFrequency, setRepeatFrequency] = useState(1); + const [repeatUntil, setRepeatUntil] = useState(null); + const [isInline, setInline] = useState(inline || false); const [config, setConfig] = useState(null); useEffect(() => { @@ -69,6 +70,7 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o const response = await axiosInstance.get(`/api/data/availabilities/${id}`); setAvailabilities([response.data]); setEditMode(true); + setDoRepeat(response.data.repeatWeekly); } catch (error) { console.error(error); toast.error("Error fetching availability data."); @@ -202,10 +204,24 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o availability.isWithTransportIn = group[0].isFirst && timeSlots[0].isWithTransport; availability.isWithTransportOut = group[group.length - 1].isLast && timeSlots[timeSlots.length - 1].isWithTransport; - availability.repeatWeekly = doRepeat; - availability.dayOfMonth = doRepeat ? null : availability.startTime.getDate(); - availability.endDate = doRepeat ? repeatUntil : null; + delete availability.weekOfMonth; + if (doRepeat) { + availability.repeatWeekly = true; + availability.dayOfMonth = null; + availability.weekOfMonth = 0; + availability.endDate = repeatUntil; + } else { + availability.repeatWeekly = false; + availability.dayOfMonth = availability.startTime.getDate(); + availability.endDate = null; + } + availability.dateOfEntry = new Date(); + if (availability.parentAvailabilityId) { + availability.parentAvailability = { connect: { id: parentAvailabilityId } }; + } + delete availability.parentAvailabilityId; + return availability; } @@ -288,8 +304,7 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o const TimeSlotCheckboxes = ({ slots, setSlots, items: [] }) => { - const [allDay, setAllDay] = useState(false); - + const [allDay, setAllDay] = useState(slots.every(slot => slot.isChecked)); const handleAllDayChange = (e) => { const updatedSlots = slots.map(slot => ({ ...slot, @@ -297,7 +312,9 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o })); setSlots(updatedSlots); setAllDay(e.target.checked) - setCanUpdate(true); + // setCanUpdate(slots.some(slot => slot.isChecked)); + const anyChecked = updatedSlots.some(slot => slot.isChecked); + setCanUpdate(anyChecked); console.log("handleAllDayChange: allDay: " + allDay + ", updatedSlots: " + JSON.stringify(updatedSlots)); }; useEffect(() => { @@ -352,9 +369,9 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o return (
-