diff --git a/.env b/.env index 5b30dbb..24dc32d 100644 --- a/.env +++ b/.env @@ -1,22 +1,13 @@ - #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 +# 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 +NODE_ENV=development # mysql -DATABASE_PROVIDER=mysql -# DATABASE_URL=mysql://cart:cart2023@192.168.0.10:3306/cart_dev -DATABASE_URL=mysql://root:Zelen0ku4e@192.168.0.10:3306/cart_dev -# DATABASE_URL=mysql://cart:cartpw@20.101.62.76:3307/cart - -# DATABASE_URL=mysql://cart:cartpw@localhost:3306/cart # npx prisma migrate dev # // owner: dobromir.popov@gmail.com | Специално Свидетелстване София # // https://console.cloud.google.com/apis/credentials/oauthclient/926212607479-d3m8hm8f8esp3rf1639prskn445sa01v.apps.googleusercontent.com?project=grand-forge-108716 @@ -28,10 +19,13 @@ AZURE_AD_CLIENT_SECRET=5ic8Q~GQmW-IUhuxzVGx3BE-i30GXDSpjfMHcb~z #client secret v AZURE_AD_TENANT_ID=f69d1a93-bfba-498a-9b60-e87c1bc26276 -APPLE_ID= -APPLE_TEAM_ID= +APPLE_ID=com.mwhitnessing.sofia +APPLE_SECRET=eyJhbGciOiJFUzI1NiIsImtpZCI6IlRCM1YzNTVHNVkifQ.eyJhdWQiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiaXNzIjoiWEM1N1A5U1hESyIsImlhdCI6MTcxMjE3ODM0MiwiZXhwIjoxNzI3NzMwMzQzLCJzdWIiOiJjb20ubXdoaXRuZXNzaW5nLnNvZmlhIn0.XceA0qUQi0tXg0GM_LkJkpNU5AqXLiSB2JlEVbHCB_nINbQTWkjtoWxfqmvdOkIzwKtvdQ8FFb-crK9no9Bbbw +# to generate +APPLE_TEAM_ID=XC57P9SXDK +APPLE_KEY_ID=TB3V355G5Y APPLE_PRIVATE_KEY= -APPLE_KEY_ID= + AUTH0_ID=Aa9f3HJowauUrmBVY4iQzQJ7fYsaZDbK AUTH0_SECRET=_c0O9GkyRXkoWMQW7jNExnl6UoXN6O4oD3mg7NZ_uHVeAinCUtcTAkeQmcKXpZ4x diff --git a/.env.demo b/.env.demo deleted file mode 100644 index 2a2aa9a..0000000 --- a/.env.demo +++ /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.development b/.env.development index afec269..40806ac 100644 --- a/.env.development +++ b/.env.development @@ -1,15 +1,11 @@ NODE_TLS_REJECT_UNAUTHORIZED=0 # NODE_EXTRA_CA_CERTS=C:\\Users\\popov\\AppData\\Local\\mkcert +PROTOCOL=https +PORT=3003 +HOST=localhost +NEXT_PUBLIC_PUBLIC_URL=https://localhost:3003 +# DATABASE=mysql://cart:cartpw@192.168.0.10:3306/cart_dev +DATABASE=mysql://cart:cartpw@localhost:3306/cart -NEXT_PUBLIC_PROTOCOL=https -NEXT_PUBLIC_HOST=localhost -NEXT_PUBLIC_PORT=3003 -NEXTAUTH_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 diff --git a/.env.development.raph b/.env.development.raph new file mode 100644 index 0000000..52d1a21 --- /dev/null +++ b/.env.development.raph @@ -0,0 +1,10 @@ +NODE_TLS_REJECT_UNAUTHORIZED=0 +# NODE_EXTRA_CA_CERTS=C:\\Users\\popov\\AppData\\Local\\mkcert +PROTOCOL=http +PORT=3003 +HOST=localhost +NEXT_PUBLIC_PUBLIC_URL=http://localhost:3003 +DATABASE="mysql://root:mdp-11000@127.0.0.1:3306/cart?connection_limit=5&charset=utf8mb4&collation=utf8mb4_unicode_ci" + +SSL_KEY=./certificates/localhost-key.pem +SSL_CERT=./certificates/localhost.pem diff --git a/.env.prod_staging b/.env.prod_staging deleted file mode 100644 index 4542e30..0000000 --- a/.env.prod_staging +++ /dev/null @@ -1,9 +0,0 @@ -NEXT_PUBLIC_PROTOCOL=https -NEXT_PUBLIC_PORT= -NEXT_PUBLIC_HOST=staging.mwhitnessing.com -NEXTAUTH_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:dwxhns9p9vp248V39xJyRthUsZ2gR9@mariadb-staging:3306/jwpwsofia \ No newline at end of file diff --git a/.env.production b/.env.production index a3438f2..15d66db 100644 --- a/.env.production +++ b/.env.production @@ -1,9 +1,9 @@ -NEXT_PUBLIC_PROTOCOL=https -NEXT_PUBLIC_PORT= -NEXT_PUBLIC_HOST=sofia.mwhitnessing.com -NEXTAUTH_URL= https://sofia.mwhitnessing.com +PORT= +HOST=sofia.mwitnessing.com +PROTOCOL=http # we're behind a reverse proxy. SSL is handled by the proxy +NEXT_PUBLIC_PUBLIC_URL= https://sofia.mwitnessing.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:dwxhns9p9vp248V39xJyRthUsZ2gR9@mariadb:3306/jwpwsofia \ No newline at end of file +DATABASE=mysql://jwpwsofia:dwxhns9p9vp248V39xJyRthUsZ2gR9@mariadb:3306/jwpwsofia \ No newline at end of file diff --git a/.env.test b/.env.test index 1b9eef8..b99f907 100644 --- a/.env.test +++ b/.env.test @@ -1,13 +1,14 @@ -NODE_TLS_REJECT_UNAUTHORIZED='0' +NODE_ENV=test -NEXT_PUBLIC_PORT=5001 -NEXT_PUBLIC_PROTOCOL=https -NEXT_PUBLIC_HOST=cart.d-popov.com -NEXTAUTH_URL=https://cart.d-popov.com +PROTOCOL=http +HOST=staging.mwitnessing.com +PORT= +NEXT_PUBLIC_PUBLIC_URL=https://staging.mwitnessing.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 +NEXTAUTH_SECRET=1dd8a5457970d1dda50600be28e935ecc4513ff27c49c431849e6746f158d638 +# ? do we need to duplicate this? already defined in the deoployment yml file +DATABASE=mysql://jwpwsofia_demo:dwxhns9p9vp248@mariadb:3306/jwpwsofia_demo APPLE_ID= APPLE_TEAM_ID= @@ -23,14 +24,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..a2cc8ff 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,13 +5,23 @@ "version": "0.2.0", "configurations": [ { - "name": "Run npm nodemon (DEV)", - "command": "npm run debug-env", + "name": "Run npm nodemon (DB)", + "command": "npm run debug", "request": "launch", "type": "node-terminal", "preLaunchTask": "killInspector", "env": { - "NODE_ENV": "development" + "APP_ENV": "development" + } + }, + { + "name": "Run npm nodemon (Raph)", + "command": "npm run debug", + "request": "launch", + "type": "node-terminal", + "preLaunchTask": "killInspector", + "env": { + "APP_ENV": "development.raph" } }, { @@ -35,7 +45,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/DESIGN/readme.md b/DESIGN/readme.md new file mode 100644 index 0000000..e69de29 diff --git a/_deploy/appleKey.p8 b/_deploy/appleKey.p8 new file mode 100644 index 0000000..4c686a8 --- /dev/null +++ b/_deploy/appleKey.p8 @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgL3WoWMr7zzqtZdF/ +wNEJ9+yMP2qNJV305gTdF+++hLOgCgYIKoZIzj0DAQehRANCAATqlUN+GE7/r8UQ +c93hRG9UxCtBcJEcgSGwYVPtZvA5igUBxY/6+RO/Tcnq9xT/6PZD0A82vMNSjoJ6 +/KyhaFLl +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/_deploy/demo.10.yml b/_deploy/demo.10.yml index 307260e..06a3a49 100644 --- a/_deploy/demo.10.yml +++ b/_deploy/demo.10.yml @@ -10,7 +10,7 @@ services: - /mnt/apps/docker_volumes/cart/app/next-cart-app:/app environment: - NODE_ENV=demo - - DATABASE_URL=mysql://cart:cart2023@192.168.0.10:3306/cart + - DATABASE=mysql://cart:cart2023@192.168.0.10:3306/cart #command: sh -c "apk update && apk add git && rm -rf /tmp/clone && git clone https://git.d-popov.com/popov/next-cart-app.git /tmp/clone && rm -rf /app/* && cp -R /tmp/clone/next-cart-app/* /app/ && rm -rf /tmp/clone && npm cache clean --force && rm -rf /app/node_modules /app/package-lock.json && npm --silent --prefix /app install /app && npx --prefix /app prisma generate && npm --prefix /app run test; tail -f /dev/null" #command: sh -c "rm -rf /tmp/clone && git clone https://git.d-popov.com/popov/next-cart-app.git /tmp/clone && rm -rf /app/* && cp -R /tmp/clone/next-cart-app/* /app/ && rm -rf /tmp/clone && npm cache clean --force && rm -rf /app/node_modules /app/package-lock.json && npm --silent --prefix /app install /app && npx --prefix /app prisma generate && npm --prefix /app run test; tail -f /dev/null" command: sh -c "npm cache clean --force && rm -rf /app/node_modules /app/package-lock.json && npm --silent --prefix /app install /app && npx --prefix /app prisma generate && npm --prefix /app run test; tail -f /dev/null" diff --git a/_deploy/demo.11-demo.yml b/_deploy/demo.11-demo.yml index 07a4a7f..3a3a4d9 100644 --- a/_deploy/demo.11-demo.yml +++ b/_deploy/demo.11-demo.yml @@ -8,7 +8,7 @@ services: - /mnt/apps/DEV/cart-demo:/app environment: - NODE_ENV=demo - - DATABASE_URL=mysql://cart:cart2023@192.168.0.10:3306/cart + - DATABASE=mysql://cart:cart2023@192.168.0.10:3306/cart command: sh -c " cd /app && npm run test; tail -f /dev/null" tty: true stdin_open: true diff --git a/_deploy/deoloy.azure.demo.yml b/_deploy/deoloy.azure.demo.yml new file mode 100644 index 0000000..8dac626 --- /dev/null +++ b/_deploy/deoloy.azure.demo.yml @@ -0,0 +1,38 @@ +version: "3" +services: + nextjs-app: # https://sofia.mwhitnessing.com/ + hostname: jwpw-app-staging # jwpw-nextjs-app-1 + image: docker.d-popov.com/jwpw:latest + volumes: + - /mnt/docker_volumes/pw-demo/app/public/content/uploads/:/app/public/content/uploads + environment: + - APP_ENV=test + - NODE_ENV=test + - TZ=Europe/Sofia + - DATABASE=mysql://jwpwsofia_demo:dwxhns9p9vp248@mariadb-demo:3306/jwpwsofia_demo + - UPDATE_CODE_FROM_GIT=true # Set to true to pull latest code from Git + - GIT_BRANCH=main + - GIT_USERNAME=deploy + - GIT_PASSWORD=L3Kr2R438u4F7 + command: sh -c " cd /app && npm install && npx next build && npm run nodeenv; tail -f /dev/null" + tty: true + stdin_open: true + restart: always + networks: + - infrastructure_default + mariadb: + deploy: + replicas: 1 + hostname: mariadb-demo + image: mysql:latest #mariadb:10.4 + volumes: + - /mnt/docker_volumes/pw-demo2/data/mysql:/var/lib/mysql + environment: + MARIADB_ROOT_PASSWORD: i4966cWBtP3xJ7BLsbsgo93 + MYSQL_ROOT_PASSWORD: i4966cWBtP3xJ7BLsbsgo93 + MYSQL_DATABASE: jwpwsofia_demo + MYSQL_USER: jwpwsofia_demo + MYSQL_PASSWORD: dwxhns9p9vp248 +networks: + infrastructure_default: + external: true diff --git a/_deploy/deoloy.azure.prod.stage.yml b/_deploy/deoloy.azure.prod.stage.yml deleted file mode 100644 index 9590d67..0000000 --- a/_deploy/deoloy.azure.prod.stage.yml +++ /dev/null @@ -1,57 +0,0 @@ -version: "3" -services: - nextjs-app: # https://sofia.mwhitnessing.com/ - hostname: jwpw-app-staging # jwpw-nextjs-app-1 - image: docker.d-popov.com/jwpw:latest - volumes: - - /mnt/docker_volumes/pw-staging/app/public/content/uploads/:/app/public/content/uploads - environment: - - NODE_ENV=prod_staging - - TZ=Europe/Sofia - - DATABASE_URL=mysql://jwpwsofia:dwxhns9p9vp248V39xJyRthUsZ2gR9@mariadb-staging:3306/jwpwsofia - - UPDATE_CODE_FROM_GIT=true # Set to true to pull latest code from Git - - GIT_BRANCH=main - - GIT_USERNAME=deploy - - GIT_PASSWORD=L3Kr2R438u4F7 - command: sh -c " cd /app && npm install && npm run nodeenv; tail -f /dev/null" - tty: true - stdin_open: true - restart: always - # ports: - # - "3001:3000" - networks: - - infrastructure_default - mariadb: - hostname: mariadb-staging - image: mariadb:latest #mariadb:10.4 - volumes: - - /mnt/docker_volumes/pw-staging/data/mysql:/var/lib/mysql - environment: - MARIADB_ROOT_PASSWORD: i4966cWBtP3xJ7BLsbsgo93C8Q5262 - MYSQL_ROOT_PASSWORD: i4966cWBtP3xJ7BLsbsgo93C8Q5262 - MYSQL_DATABASE: jwpwsofia - MYSQL_USER: jwpwsofia - MYSQL_PASSWORD: dwxhns9p9vp248V39xJyRthUsZ2gR9 - #command: ["mysqld", "--max-connections=1000", "--sql-mode=ALLOW_INVALID_DATES,ANSI_QUOTES,ERROR_FOR_DIVISION_BY_ZERO,HIGH_NOT_PRECEDENCE,IGNORE_SPACE,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,NO_DIR_IN_CREATE,NO_ENGINE_SUBSTITUTION,NO_FIELD_OPTIONS,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_UNSIGNED_SUBTRACTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,ONLY_FULL_GROUP_BY,PIPES_AS_CONCAT,REAL_AS_FLOAT,STRICT_ALL_TABLES,STRICT_TRANS_TABLES,ANSI,DB2,MAXDB,MSSQL,MYSQL323,MYSQL40,ORACLE,POSTGRESQL,TRADITIONAL", "--wait-timeout=28800"] - networks: - - infrastructure_default - postgres: - hostname: postgres - image: postgres - restart: always - # set shared memory limit when using docker-compose - shm_size: 128mb - # or set shared memory limit when deploy via swarm stack - #volumes: - # - type: tmpfs - # target: /dev/shm - # tmpfs: - # size: 134217728 # 128*2^20 bytes = 128Mb - environment: - POSTGRES_PASSWORD: i4966cWBtP3xJ7BLsbsgo93C8Q5262 - - networks: - - infrastructure_default -networks: - infrastructure_default: - external: true diff --git a/_deploy/deoloy.azure.prod.yml b/_deploy/deoloy.azure.production.yml similarity index 87% rename from _deploy/deoloy.azure.prod.yml rename to _deploy/deoloy.azure.production.yml index 0cb1e8b..7f8bcdb 100644 --- a/_deploy/deoloy.azure.prod.yml +++ b/_deploy/deoloy.azure.production.yml @@ -1,8 +1,10 @@ version: "3" services: - nextjs-app: # https://sofia.mwhitnessing.com/ + nextjs-app: # https://sofia.mwitnessing.com/ hostname: jwpw-app # jwpw-nextjs-app-1 image: docker.d-popov.com/jwpw:latest + deploy: + replicas: 2 #ports: # - "3000:3000" volumes: @@ -10,8 +12,8 @@ services: environment: - NODE_ENV=production - TZ=Europe/Sofia - - DATABASE_URL=mysql://jwpwsofia:dwxhns9p9vp248V39xJyRthUsZ2gR9@mariadb:3306/jwpwsofia - #- DATABASE_URL=postgres://jwpwsofia:dwxhns9p9vp248V39xJyRthUsZ2gR9@mariadb:3306/jwpwsofia + - DATABASE=mysql://jwpwsofia:dwxhns9p9vp248V39xJyRthUsZ2gR9@mariadb:3306/jwpwsofia + #- DATABASE=postgres://jwpwsofia:dwxhns9p9vp248V39xJyRthUsZ2gR9@mariadb:3306/jwpwsofia - UPDATE_CODE_FROM_GIT=true # Set to true to pull latest code from Git - GIT_BRANCH=production - GIT_USERNAME=deploy @@ -30,7 +32,7 @@ services: volumes: - /mnt/docker_volumes/pw/data/mysql:/var/lib/mysql environment: - MARIADB_ROOT_PASSWORD: dwxhns9p9vp248V39xJyRthUsZ2gR9 + # MARIADB_ROOT_PASSWORD: dwxhns9p9vp248V39xJyRthUsZ2gR9 MYSQL_ROOT_PASSWORD: i4966cWBtP3xJ7BLsbsgo93C8Q5262 MYSQL_DATABASE: jwpwsofia MYSQL_USER: jwpwsofia @@ -38,7 +40,6 @@ services: networks: - default - infrastructure_default - mariadb_backup: image: alpine:latest volumes: @@ -51,11 +52,11 @@ services: MYSQL_HOST: mariadb # GOOGLE_DRIVE_FOLDER_ID: your_google_drive_folder_id entrypoint: /bin/sh -c - networks: - infrastructure_default command: | - "apk add --no-cache mysql-client curl && \ + "apk update && \ + apk add --no-cache mariadb-client mariadb-connector-c && \ echo '0 2 * * * mysqldump -h $$MYSQL_HOST -P 3306 -u$$MYSQL_USER -p$$MYSQL_PASSWORD $$MYSQL_DATABASE > /backup/$$(date +\\%Y-\\%m-\\%d-\\%H\\%M\\%S)-$$MYSQL_DATABASE.sql' > /etc/crontabs/root && \ crond -f -d 8" # wget -q https://github.com/prasmussen/gdrive/releases/download/2.1.0/gdrive-linux-x64 -O /usr/bin/gdrive && \ diff --git a/_deploy/entrypoint.sh b/_deploy/entrypoint.sh index 8a7d603..f0ea095 100644 --- a/_deploy/entrypoint.sh +++ b/_deploy/entrypoint.sh @@ -10,7 +10,7 @@ if [ "$UPDATE_CODE_FROM_GIT" = "true" ]; then mkdir /tmp/clone # Clone the repository - git clone -b ${GIT_BRANCH:-main} --depth 1 https://$GIT_USERNAME:${GIT_PASSWORD//@/%40}@git.d-popov.com/popov/mwhitnessing.git /tmp/clone || exit 1 + git clone -b ${GIT_BRANCH:-main} --depth 1 https://$GIT_USERNAME:${GIT_PASSWORD//@/%40}@git.d-popov.com/popov/mwitnessing.git /tmp/clone || exit 1 # Synchronize all files except package.json and package-lock.json to /app rsync -av --delete --exclude 'package.json' --exclude 'package-lock.json' /tmp/clone/ /app/ || echo "Rsync failed: Issue synchronizing files" diff --git a/_deploy/deploy.homelab.production.yml b/_deploy/homelab.deploy.production.yml similarity index 53% rename from _deploy/deploy.homelab.production.yml rename to _deploy/homelab.deploy.production.yml index cf14df8..3c1826a 100644 --- a/_deploy/deploy.homelab.production.yml +++ b/_deploy/homelab.deploy.production.yml @@ -6,7 +6,7 @@ services: - "5001:3000" environment: - NODE_ENV=prod - - DATABASE_URL=mysql://cart:o74x642Rc8@mariadb:3306/cart + - DATABASE=mysql://cart:o74x642Rc8@mariadb:3306/cart - UPDATE_CODE_FROM_GIT=true # Set to true to pull latest code from Git - GIT_USERNAME=deploy - GIT_PASSWORD=%L3Kr2R438u4F7^%40 @@ -15,7 +15,7 @@ services: stdin_open: true mariadb: hostname: mariadb - image: mariadb #bitnami/mariadb:latest #mariadb:10.4 + image: mariadb #bitnami/mariadb:latest #mariadb:10.4 environment: MARIADB_ROOT_PASSWORD: Pw62L$3332JH MYSQL_ROOT_PASSWORD: Pw62L$3332JH @@ -24,4 +24,20 @@ services: MYSQL_PASSWORD: o74x642Rc8 networks: - default - - mysql_default \ No newline at end of file + - mysql_default + postgres: + deploy: + replicas: 0 + hostname: postgres + image: postgres + restart: always + # set shared memory limit when using docker-compose + shm_size: 128mb + # or set shared memory limit when deploy via swarm stack + #volumes: + # - type: tmpfs + # target: /dev/shm + # tmpfs: + # size: 134217728 # 128*2^20 bytes = 128Mb + environment: + POSTGRES_PASSWORD: i4966cWBtP3xJ7BLsbsgo93C8Q5262 diff --git a/_deploy/prod.Dockerfile b/_deploy/prod.Dockerfile index f894520..14d7092 100644 --- a/_deploy/prod.Dockerfile +++ b/_deploy/prod.Dockerfile @@ -4,6 +4,8 @@ FROM node:current-alpine # Set environment variables for Node.js ENV NODE_ENV=production +# ENV MYSQL_ROOT_PASSWORD=pass +ENV MYSQL_DATABASE=cart # Create and set the working directory WORKDIR /app diff --git a/_deploy/sample.docker-compose.yml b/_deploy/sample.docker-compose.yml index 06a9ae4..32347a9 100644 --- a/_deploy/sample.docker-compose.yml +++ b/_deploy/sample.docker-compose.yml @@ -40,7 +40,7 @@ services: - /mnt/data/apps/docker_volumes/cart/app:/app environment: - NODE_ENV=demo - - DATABASE_URL=mysql://cart:cartpw2024@mariadb:3306/cart + - DATABASE=mysql://cart:cartpw2024@mariadb:3306/cart #! entrypoint: ["/bin/sh", "/entrypoint.sh"] #run: npm install && npx prisma generate && npm run test; # command: "npx prisma migrate deploy && npx prisma migrate deploy && npm run build && npm run start" diff --git a/_deploy/setupAppleId.mjs b/_deploy/setupAppleId.mjs new file mode 100644 index 0000000..51f9682 --- /dev/null +++ b/_deploy/setupAppleId.mjs @@ -0,0 +1,78 @@ +#!/bin/node + +import { SignJWT } from "jose" +import { createPrivateKey } from "crypto" + +if (process.argv.includes("--help") || process.argv.includes("-h")) { + 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_TEAM_ID=XC57P9SXDK +APPLE_KEY_ID=TB3V355G5Y +APPLE_KEY + +node setupAppleId.mjs --kid YOUR_KEY_ID --iss YOUR_TEAM_ID --private_key "$(cat key.p8)" --sub YOUR_CLIENT_ID --expires_in 15778800 +node setupAppleId.mjs --kid TB3V355G5Y --iss XC57P9SXDK --sub com.mwhitnessing.sofia --private_key "$(cat appleKey.p8)" + +>>Apple client secret generated. Valid until: Tue Oct 01 2024 00:05:43 GMT+0300 (Eastern European Summer Time) + +eyJhbGciOiJFUzI1NiIsImtpZCI6IlRCM1YzNTVHNVkifQ.eyJhdWQiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiaXNzIjoiWEM1N1A5U1hESyIsImlhdCI6MTcxMjE3ODM0MiwiZXhwIjoxNzI3NzMwMzQzLCJzdWIiOiJjb20ubXdoaXRuZXNzaW5nLnNvZmlhIn0.XceA0qUQi0tXg0GM_LkJkpNU5AqXLiSB2JlEVbHCB_nINbQTWkjtoWxfqmvdOkIzwKtvdQ8FFb-crK9no9Bbbw + + + Options: + --help Print this help message + --kid, --key_id The key id of the private key + --iss, --team_id The Apple team ID + --private_key The private key to use to sign the JWT. (Starts with -----BEGIN PRIVATE KEY-----) + --sub, --client_id The client id to use in the JWT. + --expires_in Number of seconds from now when the JWT should expire. Defaults to 6 months. + --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 { + team_id, + iss = team_id, + + private_key, + + client_id, + sub = client_id, + + key_id, + kid = key_id, + + 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(` +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")))}`) +} \ No newline at end of file diff --git a/_doc/ToDo.md b/_doc/ToDo.md index ae6c5fd..b8801e8 100644 --- a/_doc/ToDo.md +++ b/_doc/ToDo.md @@ -187,3 +187,18 @@ 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 + +-- +emails +mobile apps +apple login +разрешителни - upload diff --git a/_doc/apple-gen-secret.mjs b/_doc/apple-gen-secret.mjs new file mode 100644 index 0000000..4a6600c --- /dev/null +++ b/_doc/apple-gen-secret.mjs @@ -0,0 +1,67 @@ +#!/bin/node +# https://gist.githubusercontent.com/balazsorban44/09613175e7b37ec03f676dcefb7be5eb/raw/b0d31aa0c7f58e0088fdf59ec30cad1415a3475b/apple-gen-secret.mjs + +import { SignJWT } from "jose" +import { createPrivateKey } from "crypto" + +if (process.argv.includes("--help") || process.argv.includes("-h")) { + 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] + + Options: + --help Print this help message + --kid, --key_id The key id of the private key + --iss, --team_id The Apple team ID + --private_key The private key to use to sign the JWT. (Starts with -----BEGIN PRIVATE KEY-----) + --sub, --client_id The client id to use in the JWT. + --expires_in Number of seconds from now when the JWT should expire. Defaults to 6 months. + --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 { + team_id, + iss = team_id, + + private_key, + + client_id, + sub = client_id, + + key_id, + kid = key_id, + + 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(` +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")))}`) +} \ No newline at end of file diff --git a/_doc/notes.mb b/_doc/notes.mb index 4862741..a94440c 100644 --- a/_doc/notes.mb +++ b/_doc/notes.mb @@ -111,6 +111,11 @@ export OPENAI_API_KEY=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 # dev- # ----------------------------------------------update PRISMA schema/sync database ----------------------------------------------- # # prisma migrate dev --create-only +NODE_ENV=production npx prisma migrate deploy +#windows +$env:DATABASE="mysql://cart:cartpw@localhost:3306/cart"; npx prisma migrate deploy +$env:DATABASE="mysql://cart:cartpw@192.168.0.10:3306/cart_dev"; npx prisma migrate deploy + npx prisma generate npx prisma migrate dev --name fix_nextauth_schema --create-only >Prisma Migrate created the following migration without applying it 20231214163235_fix_nextauth_schema @@ -153,8 +158,13 @@ Remove-Item package-lock.json npm install -# -- mysql -# fix +# ---------------------------------- mysql ----------------------------------- # +#backup: (--no-data to skip data) +mysqldump -h mariadb -P 3306 -ujwpwsofia -p"dwxhns9p9vp248V39xJyRthUsZ2gR9" jwpwsofia --skip-add-locks > /backup/manual-$(date +\%Y-\%m-\%d-\%H\%M\%S)-$MYSQL_DATABASE.sql + + + +# fix++ mysql -u root -pi4966cWBtP3xJ7BLsbsgo93C8Q5262 -- mysqld_safe --skip-grant-tables & @@ -164,8 +174,15 @@ SET PASSWORD FOR 'root'@'localhost' = PASSWORD('i4966cWBtP3xJ7BLsbsgo93C8Q5262') GRANT ALL PRIVILEGES ON jwpwsofia.* TO 'jwpwsofia'@'%' IDENTIFIED BY 'dwxhns9p9vp248V39xJyRthUsZ2gR9' WITH GRANT OPTION; GRANT ALL PRIVILEGES ON jwpwsofia.* TO 'jwpwsofia'@'172.22.0.3' IDENTIFIED BY 'dwxhns9p9vp248V39xJyRthUsZ2gR9' WITH GRANT OPTION; +GRANT ALL PRIVILEGES ON jwpwsofia.* TO 'jwpwsofia'@'172.22.0.%' IDENTIFIED BY 'dwxhns9p9vp248V39xJyRthUsZ2gR9' WITH GRANT OPTION; FLUSH PRIVILEGES; exit; +ALTER USER 'jwpwsofia'@'172.22.0.%' IDENTIFIED BY 'dwxhns9p9vp248V39xJyRthUsZ2gR9'; +--if error (does not exist) +CREATE USER 'jwpwsofia'@'172.22.0.%' IDENTIFIED BY 'dwxhns9p9vp248V39xJyRthUsZ2gR9'; +GRANT ALL PRIVILEGES ON jwpwsofia.* TO 'jwpwsofia'@'172.22.0.%' WITH GRANT OPTION; + + #Install depcheck: @@ -184,3 +201,8 @@ ncu -u enable apple ID: curl https://gist.githubusercontent.com/balazsorban44/09613175e7b37ec03f676dcefb7be5eb/raw/b0d31aa0c7f58e0088fdf59ec30cad1415a3475b/apple-gen-secret.mjs -o apple-gen-secret.mjs + + + + +Project setup: diff --git a/components/ExampleForm.js b/components/ExampleForm.js index 45f49f8..bf9050f 100644 --- a/components/ExampleForm.js +++ b/components/ExampleForm.js @@ -40,7 +40,7 @@ class ExampleForm extends React.Component { } const [item, set] = useState({ - isactive: true, + isActive: true, }); const router = useRouter(); @@ -63,7 +63,7 @@ class ExampleForm extends React.Component { handleChange = ({ target }) => { - if (target.name === "isactive") { + if (target.name === "isActive") { set({ ...item, [target.name]: target.checked }); } else if (target.name === "age") { set({ ...item, [target.name]: parseInt(target.value) }); @@ -100,8 +100,8 @@ class ExampleForm extends React.Component {
{location.address} diff --git a/components/location/LocationForm.js b/components/location/LocationForm.js index 098186a..4f58fdb 100644 --- a/components/location/LocationForm.js +++ b/components/location/LocationForm.js @@ -19,7 +19,7 @@ const common = require('src/helpers/common'); // id Int @id @default(autoincrement()) // name String // address String -// isactive Boolean @default(true) +// isActive Boolean @default(true) // content String? @db.Text // cartEvents CartEvent[] // reports Report[] @@ -65,7 +65,7 @@ export default function LocationForm() { const [location, set] = useState({ name: "", address: "", - isactive: true, + isActive: true, }); // const [isEdit, setIsEdit] = useState(false); @@ -171,11 +171,11 @@ export default function LocationForm() {