diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..caa08e6 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +# These are supported funding model platforms + +patreon: angeloreale diff --git a/.github/workflows/deploy_gcp_prod.yaml b/.github/workflows/deploy_gcp_prod.yaml index d08e9d7..37493b9 100644 --- a/.github/workflows/deploy_gcp_prod.yaml +++ b/.github/workflows/deploy_gcp_prod.yaml @@ -85,6 +85,13 @@ jobs: NEXUS_STANDALONE=true PRISMA_PRIVATE_URI=${{ secrets.MONGODB_PRIVATE_URI_PROD }} PRISMA_PUBLIC_URI=${{ secrets.MONGODB_PUBLIC_URI_PROD }} + SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN_PROD }} + SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN_PROD }} + NEXT_PUBLIC_SENTRY_DSN=${{ secrets.NEXT_PUBLIC_SENTRY_DSN_PROD }} + SENTRY_PROJECT=${{ secrets.SENTRY_PROJECT_PROD }} + SENTRY_ORG=${{ secrets.SENTRY_ORG_PROD }} + VERCEL_GIT_COMMIT_SHA=${{ github.sha }} + - name: hypnos::deploy_prod::docker::Generate artifact attestation uses: actions/attest-build-provenance@v1 diff --git a/Dockerfile b/Dockerfile index 8dc48b2..ce6eb3b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -80,6 +80,12 @@ ARG MONGODB_PUBLIC_URI ARG NEXUS_MODE ARG NEXUS_KEEPALIVE +ARG SENTRY_AUTH_TOKEN +ARG SENTRY_PROJECT +ARG SENTRY_ORG +ARG NEXT_PUBLIC_SENTRY_DSN +ARG VERCEL_GIT_COMMIT_SHA + # ENV FROM ARGS VARS ENV AUTH_GITHUB_ID=$AUTH_GITHUB_ID ENV AUTH_GITHUB_SECRET=$AUTH_GITHUB_SECRET @@ -120,6 +126,12 @@ ENV MONGODB_PUBLIC_URI=$MONGODB_PUBLIC_URI ENV NEXUS_MODE=$NEXUS_MODE ENV NEXUS_KEEPALIVE=$NEXUS_KEEPALIVE +ENV SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN +ENV SENTRY_PROJECT=$SENTRY_PROJECT +ENV SENTRY_ORG=$SENTRY_ORG +ENV NEXT_PUBLIC_SENTRY_DSN=$NEXT_PUBLIC_SENTRY_DSN +ENV VERCEL_GIT_COMMIT_SHA=$VERCEL_GIT_COMMIT_SHA + RUN \ if [ -f yarn.lock ]; then yarn run build:vm; \ @@ -176,6 +188,12 @@ ARG MONGODB_PUBLIC_URI ARG NEXUS_MODE ARG NEXUS_KEEPALIVE +ARG SENTRY_AUTH_TOKEN +ARG SENTRY_PROJECT +ARG SENTRY_ORG +ARG NEXT_PUBLIC_SENTRY_DSN +ARG VERCEL_GIT_COMMIT_SHA + # ENV FROM ARGS VARS ENV AUTH_GITHUB_ID=$AUTH_GITHUB_ID ENV AUTH_GITHUB_SECRET=$AUTH_GITHUB_SECRET @@ -216,6 +234,12 @@ ENV MONGODB_PUBLIC_URI=$MONGODB_PUBLIC_URI ENV NEXUS_MODE=$NEXUS_MODE ENV NEXUS_KEEPALIVE=$NEXUS_KEEPALIVE +ENV SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN +ENV SENTRY_PROJECT=$SENTRY_PROJECT +ENV SENTRY_ORG=$SENTRY_ORG +ENV NEXT_PUBLIC_SENTRY_DSN=$NEXT_PUBLIC_SENTRY_DSN +ENV VERCEL_GIT_COMMIT_SHA=$VERCEL_GIT_COMMIT_SHA + RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs diff --git a/lib/auth/constants.ts b/lib/auth/constants.ts index 4d7fe1c..5b64a16 100644 --- a/lib/auth/constants.ts +++ b/lib/auth/constants.ts @@ -1,5 +1,6 @@ // constants.ts TS-Doc? /* eslint @typescript-eslint/consistent-type-assertions:0 */ +import _ from 'lodash'; import type { NextAuthConfig } from 'next-auth'; import { v4 as uuid } from 'uuid'; import type { PrismaClient } from '@prisma/client'; @@ -40,6 +41,7 @@ export const GetSession = async ({ cookies = '' }) => { // schema sanitizer const allUsersSideEffects = async ({ user }: any) => { + if (!user) return; const services = await GetPrivateCommonServices({}); const abilities = await GetPrivateCommonAbilities({}); const commonServices = services.map((service: any) => service?.id).map((el: any) => el); @@ -47,10 +49,13 @@ const allUsersSideEffects = async ({ user }: any) => { const [dpcpAbility] = await GetPrivateAbilities({ type: 'R', target: 'dpcp-vibemodulator', action: 'view-listings' }); - await UpdatePrivateUserServices({ user, services: [...commonServices, ...user.servicesIds], upsert: false }); + const nextAbilities = _.uniq([...commonAbilities, ...user.abilitiesIds, dpcpAbility?.id]); + const nextServices = _.uniq([...commonServices, ...user.servicesIds]); + + await UpdatePrivateUserServices({ user, services: nextServices, upsert: false }); await UpdatePrivateUserAbilities({ user, - abilities: [...commonAbilities, ...user.abilitiesIds, dpcpAbility.id], + abilities: nextAbilities, upsert: false, }); }; @@ -114,6 +119,8 @@ export const authConfig = { const { user, isNewUser } = props; try { if (isNewUser) { + // [DPCP-125] https://www.notion.so/angeloreale/Hypnos-Feature-use-lib-log-for-server-console-logs-67993255fc4e4010a08fee263089f9b7?pvs=4 + console.log('dp::hypnos::Running sign-up side-effects'); await allUsersSideEffects({ user }); } } catch (e) { @@ -127,7 +134,11 @@ export const authConfig = { async signIn(props) { const { user } = props; try { - await allUsersSideEffects({ user }); + if (user) { + // [DPCP-125] https://www.notion.so/angeloreale/Hypnos-Feature-use-lib-log-for-server-console-logs-67993255fc4e4010a08fee263089f9b7?pvs=4 + console.log('dp::hypnos::Callback: Running sign-in side-effects'); + await allUsersSideEffects({ user }); + } } catch (e) { console.warn(`Code 004: Log-in side-effects failed. If it's a new user, plese ignore: ${e}`); } diff --git a/package-lock.json b/package-lock.json index f4c0763..b206392 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "hasInstallScript": true, "license": "HPL3-ECO-AND-ANC", "dependencies": { - "@sentry/nextjs": "^8.22.0", + "@sentry/nextjs": "8.22.0", "next": "14.2.5" }, "devDependencies": { @@ -22,6 +22,7 @@ "@prisma/extension-accelerate": "1.1.0", "@prisma/nextjs-monorepo-workaround-plugin": "5.18.0", "@types/json-schema": "7.0.15", + "@types/lodash": "^4.17.7", "@types/node": "20", "@types/react": "18.3.2", "@types/uuid": "9.0.8", @@ -31,17 +32,17 @@ "@vercel/functions": "1.4.0", "@vercel/kv": "2.0.0", "bson": "6.8.0", - "dotenv": "^16.4.5", + "dotenv": "16.4.5", "eslint": "8", "eslint-config-alloy": "5.1.2", "eslint-config-next": "14.0.4", "husky": "9.0.11", - "lodash": "4.17.21", + "lodash": "^4.17.21", "mongodb": "5.0.0", "next-auth": "5.0.0-beta.20", "nodemailer": "6.9.14", "patch-package": "8.0.0", - "pm2": "^5.4.2", + "pm2": "5.4.2", "prettier": "3.2.4", "prisma": "5.18.0", "server-only": "0.0.1", @@ -2465,6 +2466,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/lodash": { + "version": "4.17.7", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz", + "integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==", + "dev": true + }, "node_modules/@types/mysql": { "version": "2.15.22", "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.22.tgz", @@ -6721,8 +6728,9 @@ }, "node_modules/lodash": { "version": "4.17.21", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, "node_modules/lodash.merge": { "version": "4.6.2", diff --git a/package.json b/package.json index 23783ea..aa2033f 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "@prisma/extension-accelerate": "1.1.0", "@prisma/nextjs-monorepo-workaround-plugin": "5.18.0", "@types/json-schema": "7.0.15", + "@types/lodash": "^4.17.7", "@types/node": "20", "@types/react": "18.3.2", "@types/uuid": "9.0.8", @@ -73,7 +74,7 @@ "eslint-config-alloy": "5.1.2", "eslint-config-next": "14.0.4", "husky": "9.0.11", - "lodash": "4.17.21", + "lodash": "^4.17.21", "mongodb": "5.0.0", "next-auth": "5.0.0-beta.20", "nodemailer": "6.9.14", diff --git a/src/app/api/v1/public/route.ts b/src/app/api/v1/public/route.ts index 9e1dbcd..c192954 100644 --- a/src/app/api/v1/public/route.ts +++ b/src/app/api/v1/public/route.ts @@ -14,6 +14,7 @@ const generateErrorResponse = (e: any, status: number) => { }; // export const dynamic = 'force-static'; + export async function GET(request: CombineRequest) { try { const url = new URL(request.url); diff --git a/src/app/api/v1/services/dpcp-vibemodulator/route.ts b/src/app/api/v1/services/dpcp-vibemodulator/route.ts index 008b791..afcc691 100644 --- a/src/app/api/v1/services/dpcp-vibemodulator/route.ts +++ b/src/app/api/v1/services/dpcp-vibemodulator/route.ts @@ -15,6 +15,7 @@ const generateErrorResponse = (e: any, status: number) => { }; // export const dynamic = 'force-static'; + export async function GET(request: CombineRequest) { try { const cookies = request?.cookies?.toString() || request?.headers?.get('cookies'); diff --git a/src/app/api/v1/services/rickmorty/route.ts b/src/app/api/v1/services/rickmorty/route.ts index 30bccad..061ff7b 100644 --- a/src/app/api/v1/services/rickmorty/route.ts +++ b/src/app/api/v1/services/rickmorty/route.ts @@ -14,6 +14,7 @@ const generateErrorResponse = (e: any, status: number) => { }; // export const dynamic = 'force-static'; + export async function GET(request: CombineRequest) { try { const url = new URL(request.url); diff --git a/src/app/api/v1/user/route.ts b/src/app/api/v1/user/route.ts index 6ff2a17..ca0a64d 100644 --- a/src/app/api/v1/user/route.ts +++ b/src/app/api/v1/user/route.ts @@ -19,7 +19,7 @@ const generateErrorResponse = (e: any, status: number) => { }; }; -// export const dynamic = 'force-static'; +export const dynamic = 'force-dynamic'; export async function POST(request: CombineRequest) { const response = { error: generateErrorResponse({ message: 'Code 000/0: Non-identified error.' }, 500) };