diff --git a/.cspell.json b/.cspell.json index c74ccd6170b..0c03406dea2 100644 --- a/.cspell.json +++ b/.cspell.json @@ -3,106 +3,106 @@ "language": "en", "$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json", "words": [ - "buildjet", - "vcpu", - "zfgk", - "Zrdm", - "superfly", - "flyctl", - "trufflesecurity", - "trufflehog", - "slnt", - "wght", - "Crismon", - "Civo", - "CIVO", - "apicivo", - "apistagecivo", - "stagecivo", - "appcivo", - "knowledeg", - "timeframe", - "keyrings", - "dearmor", - "containerd", - "traefik", - "Jitsu", - "jitsu", - "Repobeats", - "scriptable", - "Evereq", - "inotify", - "cpus", "activitywatch", "adminer", + "AGPL", + "airbyte", + "Akveo", + "Alexi", + "alish", + "Alish", + "apicivo", "apicw", - "appcw", "apidemo", + "apidemocivo", "apidemocw", + "apistagecivo", "apistagecw", - "apidemocivo", - "democivo", - "stagecw", - "AGPL", - "Akveo", - "Alexi", + "appbaseio", + "appcivo", + "appcw", "Artboard", "asar", "asymmetrik", "autobuild", "Autobuild", "automake", - "Buildx", - "buildx", + "badal", + "basicstyles", "billrate", "binutils", "bmap", "Buildable", - "coreweave", - "CoreWeave", + "buildjet", + "buildx", + "Buildx", "cacheable", "camelcase", + "Chahal", "chartjs", "CHATWOOT", "checkmark", + "chetan", + "Chetan", "Chinthagunta", "circlon", + "Civo", + "CIVO", "ckeditor", "cloc", "Cloudinary", "CLOUDINARY", "Codacy", "codecov", + "Codegen", "codelyzer", "Codementor", "codeql", "commitlint", "compat", "compodoc", + "configurator", + "containerd", "conv", "copyfiles", + "coreweave", + "CoreWeave", + "cpus", "cqrs", - "DOCKERHUB", + "Crismon", + "cubejs", + "CUBEJS", + "datatables", "Datepicker", "daterangepicker", "datetime", - "democw", "datname", "daygrid", + "dbname", "DDTHH", + "dearmor", "Dejavu", + "democivo", + "democw", "dependecies", + "Desterrro", "devkit", + "Dister", + "DOCKERHUB", "doctl", "dpkg", - "everco", + "Dsonar", "echarts", "editorplaceholder", "empl", "entrypoint", "envalid", "envsubst", + "EOSQL", "esbuild", + "eventnative", + "everco", + "Evereq", "exif", "ezkfxg", "Fargate", @@ -112,6 +112,7 @@ "filepond", "FIVERR", "Flickr", + "flyctl", "fontawesome", "fontface", "formcontrol", @@ -123,38 +124,93 @@ "fullscreenable", "gauzydesktop", "gauzydesktoptimer", + "gauzydevsess", + "gauzyprodsess", "gauzyserver", + "gitmodules", "Gitter", "godaddy", "googlemaps", "Grafana", "graphicsmagick", + "gridcell", "grpc", "Guazy", + "Harbir", "healthcheck", + "Hoster", "HUBSTAFF", "huntr", "IAWS", + "ibase", + "icns", "icnsutils", "icrud", "ienvironment", "IKPI", "ILIKE", + "ilinked", "immer", + "initdb", + "inotify", "instantaneaous", + "INTERTRX", + "INTERVALSRVCE", + "INTERVTRX", "ionicons", + "IPCCIS", + "IPCINIT", + "IPCLS", + "IPCNOTIF", + "IPCNTFSHOT", + "IPCPERM", + "IPCQCI", + "IPCQNVGLOGIN", + "IPCQSAVEIMG", + "IPCQSHEET", + "IPCQSLOT", + "IPCQWIN", + "IPCREFRESH", + "IPCRESTORE", + "IPCRMAFK", + "IPCRMAW", + "IPCRMSLOT", + "IPCRMUSER", + "IPCRMWK", + "IPCRTNSLOT", + "IPCSAVEINTER", + "IPCSAVESHOT", + "IPCSAVESLOT", + "IPCSTARTMR", + "IPCSTOPTMR", + "IPCTKSCAPTURE", + "IPCTKSHOT", + "IPCUPDATESYNCINTERVAL", + "IPCUPDATESYNCTMR", + "IPCWS", + "iqueue", + "iremote", "ISMTP", + "itimer", "IURL", + "iwindow", "jasminewd", "javascripts", + "Jaye", "Jenkinfile", + "jitsu", + "Jitsu", + "jitsucom", "julianday", "kafkajs", "KEYCLOAK", "KEYMETRICS", "keyresult", "keyresults", + "keyrings", + "killall", "knexfile", + "knowledeg", "Konviser", "KPIS", "kube", @@ -162,6 +218,7 @@ "kubectl", "Kubernetes", "kurkle", + "Kyoster", "Lask", "latlng", "letsencrypt", @@ -171,9 +228,18 @@ "libstdc", "linebreak", "linkedin", + "MAINDB", + "MAINLOADURL", + "MAINOPENEXT", + "MAINSTRSERVER", + "MAINUNEXCEPTION", + "MAINUPDTABORT", + "MAINWB", + "MAINWININIT", "masuk", "mathieudutour", "maximizable", + "memlock", "Metadatas", "metatype", "microservices", @@ -182,6 +248,8 @@ "MINIO", "minte", "mjml", + "msedge", + "Mustero", "napi", "nasm", "nats", @@ -199,79 +267,116 @@ "nsis", "nstudio", "ntegral", + "openai", + "OPENAI", "openapi", "openfromhere", + "opentelemetry", "orgname", "Orgs", "originalname", "ormconfig", "ormlogs", + "OTEL", + "OTLP", "oxsecurity", "packagr", "pagedata", "pageobjects", + "pantone", "Parens", "payperiod", "pdfmake", - "pgrep", + "pdfmaker", + "Pdfmaker", "pgcrypto", + "pgrep", "pgsql", "pgweb", "Pgweb", "piecelabel", "pinghost", + "pino", "postbuild", "postgre", "postgres", "postmarkapp", "prebuild", "preload", + "presigner", + "prestart", "pricetags", + "PRKILL", + "PRMIG", + "Probot", + "PROJECTRX", "psql", "pulumi", "Pulumi", + "Qube", "Quer", + "r_emailaddress", + "r_liteprofile", "randomcolor", + "reference", + "Rememberd", + "rememberMe", + "Repobeats", "repos", + "resave", "roboto", "Ruslan", - "swapoff", + "sarif", + "SARIF", + "SCALEWAY", + "Scayt", "screenfull", + "scriptable", "scrollbars", "scrollblock", - "setuptools", - "sonarqube", - "Qube", - "Sonarscanner", - "killall", - "Dsonar", + "scrollgrid", "setuid", + "setuptools", "Shaked", - "Scayt", "Sharings", "siderbar", + "signin", + "Signoz", "signups", + "slnt", "sluggable", + "Smee", "snyk", "socicon", "solidvar", + "sonarqube", + "Sonarscanner", "sosedoff", + "Sqls", + "sqlserver", "squirrelly", "sslmode", "SSSSZ", "stackoverflow", + "stagecivo", + "stagecw", "stefanzweifel", "streamifier", "stylelint", "Sumanth", + "superfly", + "swapoff", + "swatchbook", "swiper", "Tabset", "takeshot", + "TASKTRX", + "thmb", + "timeframe", "timegrid", "TIMELOG", "timelogs", "Timeoff", - "TOOLSDIRECTORY", "TIMERTRX", "TIMERTRXER", "TIMERTRXERUPDATE", @@ -282,11 +387,17 @@ "timeslots", "timestamptz", "titlecase", + "TMRSRVCE", "toastr", + "TOOLSDIRECTORY", + "traefik", + "trufflehog", + "trufflesecurity", "tsbuildinfo", "twing", "typeorm", "Udemy", + "ulimits", "UNINVOICED", "UNPROCESSABLE", "unsubmit", @@ -295,134 +406,25 @@ "Upwork", "UPWORK", "urlpath", + "USERSRVCE", + "USERTRX", + "uuidv4", + "vcpu", + "VULTR", "Wakatime", "wasabisys", "webapp", "websockets", - "xpack", - "xplat", - "Sqls", + "wght", "Whitespaces", - "datatables", - "dbname", - "EOSQL", - "rememberMe", - "Rememberd", - "basicstyles", - "itimer", - "iremote", - "iqueue", - "ilinked", - "swatchbook", - "uuidv4", - "reference", "workdiary", "Workdiary", - "thmb", - "gitmodules", - "sqlserver", - "pdfmaker", - "Pdfmaker", - "prestart", - "resave", - "signin", - "ibase", - "iwindow", - "Probot", - "Smee", - "badal", - "MAINSTRSERVER", - "MAINLOADURL", - "MAINDB", - "MAINWININIT", - "MAINOPENEXT", - "MAINUPDTABORT", - "MAINWB", - "IPCRMAFK", - "IPCQSHEET", - "IPCQSLOT", - "IPCSAVESLOT", - "IPCRMUSER", - "IPCINIT", - "IPCPERM", - "IPCUPDATESYNCTMR", - "IPCTKSCAPTURE", - "IPCUPDATESYNCINTERVAL", - "IPCNOTIF", - "IPCSAVEINTER", - "IPCRESTORE", - "IPCSTARTMR", - "IPCRMSLOT", - "IPCQWIN", - "IPCRMAW", - "IPCRMWK", - "IPCSTOPTMR", - "IPCRTNSLOT", - "IPCNTFSHOT", - "IPCTKSHOT", - "IPCSAVESHOT", - "IPCQSAVEIMG", - "IPCQNVGLOGIN", - "IPCREFRESH", - "IPCCIS", - "IPCWS", - "IPCQCI", - "IPCLS", - "PRMIG", - "PRKILL", - "INTERVALSRVCE", - "TMRSRVCE", - "USERSRVCE", - "INTERTRX", - "INTERVTRX", - "PROJECTRX", - "TASKTRX", - "USERTRX", - "MAINUNEXCEPTION", - "Harbir", - "Chahal", - "pino", - "Jaye", - "Alish", - "alish", + "xpack", + "xplat", "Yoster", - "Hoster", - "Dister", - "Kyoster", - "Mustero", - "Desterrro", - "Chetan", - "chetan", "Yostorono", - "sarif", - "SARIF", - "gridcell", - "scrollgrid", - "r_liteprofile", - "r_emailaddress", - "Signoz", - "OTEL", - "OTLP", - "opentelemetry", - "presigner", - "SCALEWAY", - "VULTR", - "Codegen", - "icns", - "pantone", - "msedge", - "openai", - "OPENAI", - "initdb", - "cubejs", - "CUBEJS", - "jitsucom", - "configurator", - "eventnative", - "airbyte", - "ulimits", - "memlock", - "appbaseio" + "zfgk", + "Zrdm" ], "useGitignore": true, "ignorePaths": [ diff --git a/.deploy/api/Dockerfile b/.deploy/api/Dockerfile index 901133c84b1..841ab909dd4 100644 --- a/.deploy/api/Dockerfile +++ b/.deploy/api/Dockerfile @@ -88,6 +88,8 @@ ARG COMPANY_NAME ARG OTEL_ENABLED ARG OTEL_EXPORTER_OTLP_HEADERS ARG OTEL_EXPORTER_OTLP_TRACES_ENDPOINT +ARG REDIS_ENABLED +ARG REDIS_URL FROM node:18-alpine3.17 AS dependencies @@ -370,6 +372,8 @@ ENV COMPANY_NAME=${COMPANY_NAME} ENV OTEL_ENABLED=${OTEL_ENABLED} ENV OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=${OTEL_EXPORTER_OTLP_TRACES_ENDPOINT} ENV OTEL_EXPORTER_OTLP_HEADERS=${OTEL_EXPORTER_OTLP_HEADERS} +ENV REDIS_ENABLED=${REDIS_ENABLED} +ENV REDIS_URL=${REDIS_URL} EXPOSE ${API_PORT} diff --git a/.deploy/k8s/k8s-manifest.civo.prod.yaml b/.deploy/k8s/k8s-manifest.civo.prod.yaml index 2e1efa67b85..22179e380ed 100644 --- a/.deploy/k8s/k8s-manifest.civo.prod.yaml +++ b/.deploy/k8s/k8s-manifest.civo.prod.yaml @@ -83,6 +83,10 @@ spec: value: '$DB_NAME' - name: DB_PORT value: '$DB_PORT' + - name: REDIS_ENABLED + value: '$REDIS_ENABLED' + - name: REDIS_URL + value: '$REDIS_URL' - name: AWS_ACCESS_KEY_ID value: '$AWS_ACCESS_KEY_ID' - name: AWS_SECRET_ACCESS_KEY diff --git a/.deploy/k8s/k8s-manifest.civo.stage.yaml b/.deploy/k8s/k8s-manifest.civo.stage.yaml index 46cccbdd798..57e9c425d28 100644 --- a/.deploy/k8s/k8s-manifest.civo.stage.yaml +++ b/.deploy/k8s/k8s-manifest.civo.stage.yaml @@ -83,6 +83,10 @@ spec: value: '$DB_NAME' - name: DB_PORT value: '$DB_PORT' + - name: REDIS_ENABLED + value: '$REDIS_ENABLED' + - name: REDIS_URL + value: '$REDIS_URL' - name: AWS_ACCESS_KEY_ID value: '$AWS_ACCESS_KEY_ID' - name: AWS_SECRET_ACCESS_KEY diff --git a/.deploy/k8s/k8s-manifest.cw.prod.yaml b/.deploy/k8s/k8s-manifest.cw.prod.yaml index 42550f41f46..7dd6f1485c2 100644 --- a/.deploy/k8s/k8s-manifest.cw.prod.yaml +++ b/.deploy/k8s/k8s-manifest.cw.prod.yaml @@ -109,6 +109,10 @@ spec: value: '$DB_NAME' - name: DB_PORT value: '$DB_PORT' + - name: REDIS_ENABLED + value: '$REDIS_ENABLED' + - name: REDIS_URL + value: '$REDIS_URL' - name: AWS_ACCESS_KEY_ID value: '$AWS_ACCESS_KEY_ID' - name: AWS_SECRET_ACCESS_KEY diff --git a/.deploy/k8s/k8s-manifest.cw.stage.yaml b/.deploy/k8s/k8s-manifest.cw.stage.yaml index 9e87beda5e1..8527603399f 100644 --- a/.deploy/k8s/k8s-manifest.cw.stage.yaml +++ b/.deploy/k8s/k8s-manifest.cw.stage.yaml @@ -109,6 +109,10 @@ spec: value: '$DB_NAME' - name: DB_PORT value: '$DB_PORT' + - name: REDIS_ENABLED + value: '$REDIS_ENABLED' + - name: REDIS_URL + value: '$REDIS_URL' - name: AWS_ACCESS_KEY_ID value: '$AWS_ACCESS_KEY_ID' - name: AWS_SECRET_ACCESS_KEY diff --git a/.deploy/k8s/k8s-manifest.prod.yaml b/.deploy/k8s/k8s-manifest.prod.yaml index 264efae9bb0..c487d8532f8 100644 --- a/.deploy/k8s/k8s-manifest.prod.yaml +++ b/.deploy/k8s/k8s-manifest.prod.yaml @@ -62,10 +62,10 @@ spec: image: registry.digitalocean.com/ever/gauzy-api:latest resources: requests: - memory: "1536Mi" - cpu: "1000m" + memory: '1536Mi' + cpu: '1000m' limits: - memory: "2048Mi" + memory: '2048Mi' env: - name: API_HOST value: 0.0.0.0 @@ -107,6 +107,10 @@ spec: value: '$DB_NAME' - name: DB_PORT value: '$DB_PORT' + - name: REDIS_ENABLED + value: '$REDIS_ENABLED' + - name: REDIS_URL + value: '$REDIS_URL' - name: AWS_ACCESS_KEY_ID value: '$AWS_ACCESS_KEY_ID' - name: AWS_SECRET_ACCESS_KEY diff --git a/.deploy/k8s/k8s-manifest.stage.yaml b/.deploy/k8s/k8s-manifest.stage.yaml index db361f31188..f48483242ce 100644 --- a/.deploy/k8s/k8s-manifest.stage.yaml +++ b/.deploy/k8s/k8s-manifest.stage.yaml @@ -101,6 +101,10 @@ spec: value: '$DB_NAME' - name: DB_PORT value: '$DB_PORT' + - name: REDIS_ENABLED + value: '$REDIS_ENABLED' + - name: REDIS_URL + value: '$REDIS_URL' - name: AWS_ACCESS_KEY_ID value: '$AWS_ACCESS_KEY_ID' - name: AWS_SECRET_ACCESS_KEY diff --git a/.env.compose b/.env.compose index c60fb38a51d..031daddbb9b 100644 --- a/.env.compose +++ b/.env.compose @@ -68,6 +68,10 @@ DB_POOL_SIZE=40 DB_CONNECTION_TIMEOUT=1000 DB_SLOW_QUERY_LOGGING_TIMEOUT=3000 +REDIS_ENABLED=true +# redis[s]://[[username][:password]@][host][:port][/db-number] +REDIS_URL=redis://localhost:6379 + EXPRESS_SESSION_SECRET=gauzy # JWT Refresh Token Configuration diff --git a/.env.demo.compose b/.env.demo.compose index 1a1dc59f55e..3e1bd8e3e3e 100644 --- a/.env.demo.compose +++ b/.env.demo.compose @@ -69,6 +69,11 @@ DB_POOL_SIZE=40 DB_CONNECTION_TIMEOUT=1000 DB_SLOW_QUERY_LOGGING_TIMEOUT=3000 +# we don't run Redis in basic Demo setup +REDIS_ENABLED=false +# redis[s]://[[username][:password]@][host][:port][/db-number] +REDIS_URL=redis://localhost:6379 + EXPRESS_SESSION_SECRET=gauzy # JWT Refresh Token Configuration diff --git a/.env.docker b/.env.docker index 6cfc404c3a1..4f0ed5dfe0f 100644 --- a/.env.docker +++ b/.env.docker @@ -67,6 +67,10 @@ DB_POOL_SIZE=40 DB_CONNECTION_TIMEOUT=1000 DB_SLOW_QUERY_LOGGING_TIMEOUT=3000 +REDIS_ENABLED=false +# redis[s]://[[username][:password]@][host][:port][/db-number] +REDIS_URL=redis://localhost:6379 + EXPRESS_SESSION_SECRET=gauzy # JWT Configuration diff --git a/.env.local b/.env.local index 9143c1b3831..c7f5a974b7e 100644 --- a/.env.local +++ b/.env.local @@ -67,6 +67,10 @@ DB_POOL_SIZE=40 DB_CONNECTION_TIMEOUT=1000 DB_SLOW_QUERY_LOGGING_TIMEOUT=3000 +REDIS_ENABLED=false +# redis[s]://[[username][:password]@][host][:port][/db-number] +REDIS_URL=redis://localhost:6379 + EXPRESS_SESSION_SECRET=gauzy # JWT Configuration diff --git a/.env.sample b/.env.sample index dd9589dbb67..5a72bbe699e 100644 --- a/.env.sample +++ b/.env.sample @@ -51,6 +51,10 @@ DB_TYPE=better-sqlite3 # DB_CONNECTION_TIMEOUT=1000 # DB_SLOW_QUERY_LOGGING_TIMEOUT=3000 +REDIS_ENABLED=false +# redis[s]://[[username][:password]@][host][:port][/db-number] +REDIS_URL=redis://localhost:6379 + EXPRESS_SESSION_SECRET=gauzy # JWT Configuration diff --git a/.github/workflows/deploy-civo-prod.yml b/.github/workflows/deploy-civo-prod.yml index 47efa2d3389..4bc9a861134 100644 --- a/.github/workflows/deploy-civo-prod.yml +++ b/.github/workflows/deploy-civo-prod.yml @@ -53,6 +53,8 @@ jobs: DB_PORT: '${{ secrets.DB_PORT }}' DB_CA_CERT: '${{ secrets.DB_CA_CERT }}' DB_SSL_MODE: '${{ secrets.DB_SSL_MODE }}' + REDIS_ENABLED: '${{ secrets.REDIS_ENABLED }}' + REDIS_URL: '${{ secrets.REDIS_URL }}' CLOUD_PROVIDER: 'CIVO' SENTRY_DSN: '${{ secrets.SENTRY_DSN }}' SENTRY_TRACES_SAMPLE_RATE: '${{ secrets.SENTRY_TRACES_SAMPLE_RATE }}' diff --git a/.github/workflows/deploy-civo-stage.yml b/.github/workflows/deploy-civo-stage.yml index aece8a62952..8d0535b963a 100644 --- a/.github/workflows/deploy-civo-stage.yml +++ b/.github/workflows/deploy-civo-stage.yml @@ -54,6 +54,8 @@ jobs: DB_PORT: '${{ secrets.DB_PORT }}' DB_CA_CERT: '${{ secrets.DB_CA_CERT }}' DB_SSL_MODE: '${{ secrets.DB_SSL_MODE }}' + REDIS_ENABLED: '${{ secrets.REDIS_ENABLED }}' + REDIS_URL: '${{ secrets.REDIS_URL }}' CLOUD_PROVIDER: 'CIVO' SENTRY_DSN: '${{ secrets.SENTRY_DSN }}' SENTRY_TRACES_SAMPLE_RATE: '${{ secrets.SENTRY_TRACES_SAMPLE_RATE }}' diff --git a/.github/workflows/deploy-cw-prod.yml b/.github/workflows/deploy-cw-prod.yml index d2326d48ccb..37000266467 100644 --- a/.github/workflows/deploy-cw-prod.yml +++ b/.github/workflows/deploy-cw-prod.yml @@ -53,6 +53,8 @@ jobs: DB_PORT: '${{ secrets.DB_PORT }}' DB_CA_CERT: '${{ secrets.DB_CA_CERT }}' DB_SSL_MODE: '${{ secrets.DB_SSL_MODE }}' + REDIS_ENABLED: '${{ secrets.REDIS_ENABLED }}' + REDIS_URL: '${{ secrets.REDIS_URL }}' CLOUD_PROVIDER: 'CW' SENTRY_DSN: '${{ secrets.SENTRY_DSN }}' SENTRY_TRACES_SAMPLE_RATE: '${{ secrets.SENTRY_TRACES_SAMPLE_RATE }}' diff --git a/.github/workflows/deploy-cw-stage.yml b/.github/workflows/deploy-cw-stage.yml index 9e70067266f..512af9bfe2b 100644 --- a/.github/workflows/deploy-cw-stage.yml +++ b/.github/workflows/deploy-cw-stage.yml @@ -54,6 +54,8 @@ jobs: DB_PORT: '${{ secrets.DB_PORT }}' DB_CA_CERT: '${{ secrets.DB_CA_CERT }}' DB_SSL_MODE: '${{ secrets.DB_SSL_MODE }}' + REDIS_ENABLED: '${{ secrets.REDIS_ENABLED }}' + REDIS_URL: '${{ secrets.REDIS_URL }}' CLOUD_PROVIDER: 'CW' SENTRY_DSN: '${{ secrets.SENTRY_DSN }}' SENTRY_TRACES_SAMPLE_RATE: '${{ secrets.SENTRY_TRACES_SAMPLE_RATE }}' diff --git a/.github/workflows/deploy-do-prod.yml b/.github/workflows/deploy-do-prod.yml index 84948e43b9d..a9b6e410d80 100644 --- a/.github/workflows/deploy-do-prod.yml +++ b/.github/workflows/deploy-do-prod.yml @@ -48,6 +48,8 @@ jobs: DB_PORT: '${{ secrets.DB_PORT }}' DB_CA_CERT: '${{ secrets.DB_CA_CERT }}' DB_SSL_MODE: '${{ secrets.DB_SSL_MODE }}' + REDIS_ENABLED: '${{ secrets.REDIS_ENABLED }}' + REDIS_URL: '${{ secrets.REDIS_URL }}' CLOUD_PROVIDER: 'DO' SENTRY_DSN: '${{ secrets.SENTRY_DSN }}' SENTRY_TRACES_SAMPLE_RATE: '${{ secrets.SENTRY_TRACES_SAMPLE_RATE }}' diff --git a/.github/workflows/deploy-do-stage.yml b/.github/workflows/deploy-do-stage.yml index ae15f64a67f..06a5cc3d869 100644 --- a/.github/workflows/deploy-do-stage.yml +++ b/.github/workflows/deploy-do-stage.yml @@ -49,6 +49,8 @@ jobs: DB_PORT: '${{ secrets.DB_PORT }}' DB_CA_CERT: '${{ secrets.DB_CA_CERT }}' DB_SSL_MODE: '${{ secrets.DB_SSL_MODE }}' + REDIS_ENABLED: '${{ secrets.REDIS_ENABLED }}' + REDIS_URL: '${{ secrets.REDIS_URL }}' CLOUD_PROVIDER: 'DO' SENTRY_DSN: '${{ secrets.SENTRY_DSN }}' SENTRY_TRACES_SAMPLE_RATE: '${{ secrets.SENTRY_TRACES_SAMPLE_RATE }}' diff --git a/.vscode/settings.json b/.vscode/settings.json index 478c58fee04..495357e231d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -25,6 +25,5 @@ "**/public/**/*.jpg": true, "**/public/**/*.pdf": true }, - "angular.enable-strict-mode-prompt": false, - "cSpell.words": [] + "angular.enable-strict-mode-prompt": false } diff --git a/apps/gauzy/package.json b/apps/gauzy/package.json index ac805541345..81a0d4bf52a 100644 --- a/apps/gauzy/package.json +++ b/apps/gauzy/package.json @@ -99,7 +99,6 @@ "detect-passive-events": "^1.0.4", "echarts": "^5.0.1", "eva-icons": "^1.1.3", - "express-session": "^1.17.2", "fast-json-stringify": "^2.7.12", "file-saver": "^2.0.5", "filepond": "^4.25.1", diff --git a/apps/gauzy/src/app/@shared/employee/edit-employee-membership-form/edit-employee-membership-form.component.html b/apps/gauzy/src/app/@shared/employee/edit-employee-membership-form/edit-employee-membership-form.component.html index 2b358bc61ec..d446483e910 100644 --- a/apps/gauzy/src/app/@shared/employee/edit-employee-membership-form/edit-employee-membership-form.component.html +++ b/apps/gauzy/src/app/@shared/employee/edit-employee-membership-form/edit-employee-membership-form.component.html @@ -55,11 +55,11 @@ - -
+ +
{{ title }}
- + {{ entity.name }} diff --git a/apps/gauzy/src/app/@shared/employee/edit-employee-membership-form/edit-employee-membership-form.component.scss b/apps/gauzy/src/app/@shared/employee/edit-employee-membership-form/edit-employee-membership-form.component.scss index 1b2d2b2af63..bc305a5414d 100644 --- a/apps/gauzy/src/app/@shared/employee/edit-employee-membership-form/edit-employee-membership-form.component.scss +++ b/apps/gauzy/src/app/@shared/employee/edit-employee-membership-form/edit-employee-membership-form.component.scss @@ -17,10 +17,16 @@ } .entities { - margin-bottom: 0.5rem; + display: flex; + flex-direction: column; + gap: 0.5rem; } :host{ height: 100%; @include dialog(var(--gauzy-card-2), var(--gauzy-card-1)); -} \ No newline at end of file + nb-card-header, + nb-card-body { + padding: 1rem; + } +} diff --git a/apps/gauzy/src/app/@shared/employee/employee-location/employee-location.component.html b/apps/gauzy/src/app/@shared/employee/employee-location/employee-location.component.html index 77f5d92a5cd..327feb840d6 100644 --- a/apps/gauzy/src/app/@shared/employee/employee-location/employee-location.component.html +++ b/apps/gauzy/src/app/@shared/employee/employee-location/employee-location.component.html @@ -1,5 +1,5 @@ - +
diff --git a/apps/gauzy/src/app/@shared/employee/employee-location/employee-location.component.scss b/apps/gauzy/src/app/@shared/employee/employee-location/employee-location.component.scss index bbee1264dfb..4fa394aa012 100644 --- a/apps/gauzy/src/app/@shared/employee/employee-location/employee-location.component.scss +++ b/apps/gauzy/src/app/@shared/employee/employee-location/employee-location.component.scss @@ -4,9 +4,12 @@ height: 100%; nb-card { background-color: var(--gauzy-card-2); - height: 100%; + border-radius: 0; + nb-card-body { - height: 100%; + background-color: var(--card-background-color); + border-radius: 0.625rem; + form { display: flex; flex-direction: column; diff --git a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-contact/edit-employee-contact.component.html b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-contact/edit-employee-contact.component.html index a743ce87afa..c8f8c288073 100644 --- a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-contact/edit-employee-contact.component.html +++ b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-contact/edit-employee-contact.component.html @@ -1,9 +1,11 @@ - +
+ +
diff --git a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-contact/edit-employee-contact.component.ts b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-contact/edit-employee-contact.component.ts index 13a18a01a3c..73c67e68a6e 100644 --- a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-contact/edit-employee-contact.component.ts +++ b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-contact/edit-employee-contact.component.ts @@ -22,6 +22,18 @@ import { ToastrService } from 'apps/gauzy/src/app/@core/services/toastr.service' :host { overflow-y: auto; height: calc(100vh - 20.5rem); + + .container-contact { + background-color: var(--gauzy-card-2); + padding: 1rem; + height: 100%; + } + + nb-card { + margin: 0 !important; + background-color: var(--gauzy-card-3) !important; + border-radius: var(--card-border-radius); + } } ` ] diff --git a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-employment/edit-employee-employment.component.html b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-employment/edit-employee-employment.component.html index 82ce328a06f..cdba800ed23 100644 --- a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-employment/edit-employee-employment.component.html +++ b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-employment/edit-employee-employment.component.html @@ -1,206 +1,208 @@ - - - -
-
-
- - - + + +
+ +
+
+
+ + + +
-
-
-
-

- {{ - 'FORM.NOTIFICATIONS.STARTED_WORK_ON' | translate - }} -

+
+
+

+ {{ + 'FORM.NOTIFICATIONS.STARTED_WORK_ON' | translate + }} +

+
-
-
-
-
- - +
+
+
+ + +
-
-
-
-
-

- {{ 'FORM.LABELS.DESCRIPTION' | translate }} -

-
- +
+
+
+

+ {{ 'FORM.LABELS.DESCRIPTION' | translate }} +

+
+ +
-
-
-
-
- - +
+
+ + + +
+
+
+
+ + + {{ empL.level }} + +
-
-
- - - {{ empL.level }} +
+
+ + - + +
-
-
-
-
-
- - - +
+
+ + + +
-
-
- - - +
+
+
+ + +
-
-
-
-
-
- - +
+
+ + +
-
-
- - +
+
+
+ + {{ + 'EMPLOYEES_PAGE.EDIT_EMPLOYEE.DISPLAY_BONUS_ANONYMOUSLY' + | translate + }} + +
-
-
-
-
- - {{ - 'EMPLOYEES_PAGE.EDIT_EMPLOYEE.DISPLAY_BONUS_ANONYMOUSLY' - | translate - }} - -
+
+
-
-
- -
- + +
diff --git a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-employment/edit-employee-employment.component.scss b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-employment/edit-employee-employment.component.scss index a777a5fbbb2..3b8b48a7af7 100644 --- a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-employment/edit-employee-employment.component.scss +++ b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-employment/edit-employee-employment.component.scss @@ -13,14 +13,32 @@ $radius: nb-theme(border-radius); font-weight: 600; text-align: justify; } -.card{ +.card { background-color: var(--gauzy-card-2); border: unset; } :host { + background: var(--gauzy-card-2); + overflow-y: auto; + @include nb-card_overrides( auto, calc($default-card-height + 0.25rem), $default-radius ); + + nb-card { + border-radius: 0; + } + + nb-card-body { + background-color: var(--gauzy-card-2); + padding: 1rem; + + .form-container { + background-color: var(--gauzy-sidebar-background-2); + border-radius: var(--border-radius); + padding: 1rem; + } + } } diff --git a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-location/edit-employee-location.component.scss b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-location/edit-employee-location.component.scss index b1243b3f443..2239ac7a443 100644 --- a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-location/edit-employee-location.component.scss +++ b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-location/edit-employee-location.component.scss @@ -12,4 +12,14 @@ } } } + + ::ng-deep { + nb-card { + padding: 1rem; + + nb-card-body { + margin: 0 !important; + } + } + } } diff --git a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-main/edit-employee-main.component.scss b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-main/edit-employee-main.component.scss index d67449f26e1..00ff1f6a4cb 100644 --- a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-main/edit-employee-main.component.scss +++ b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-main/edit-employee-main.component.scss @@ -19,9 +19,7 @@ $radius: nb-theme(border-radius); } .content { - background-color: var(--gauzy-card-2); padding: 20px; - border-radius: 0 $radius $radius $radius; } :host { @@ -34,4 +32,9 @@ $radius: nb-theme(border-radius); @include nb-ltr(padding-left, 1rem); @include nb-rtl(padding-right, 1rem); } + + .employee-form { + overflow: auto; + overflow-x: hidden; + } } diff --git a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-profile.component.html b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-profile.component.html index d46645d7b69..b6d433df26f 100644 --- a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-profile.component.html +++ b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-profile.component.html @@ -1 +1 @@ - + diff --git a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-profile.component.scss b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-profile.component.scss new file mode 100644 index 00000000000..2ea07f1ce18 --- /dev/null +++ b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-profile.component.scss @@ -0,0 +1,25 @@ +:host { + ::ng-deep .tabset-container .route-tabset { + overflow-x: scroll; + overflow-y: hidden; + + &::-webkit-scrollbar { + /* Chrome, Safari, Opera */ + display: none; + /* IE, Edge */ + -ms-overflow-style: none; + /* Firefox */ + scrollbar-width: none; + } + + @media only screen and (max-width: 1280px) { + li a.tab-link { + display: flex !important; + + nb-icon { + margin-bottom: 0; + } + } + } + } +} diff --git a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-profile.component.ts b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-profile.component.ts index e4a1d8dcfa9..f3e9ea8880b 100644 --- a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-profile.component.ts +++ b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-profile.component.ts @@ -25,6 +25,7 @@ import { selector: 'ngx-edit-employee-profile', templateUrl: './edit-employee-profile.component.html', styleUrls: [ + './edit-employee-profile.component.scss', '../../../../@shared/user/edit-profile-form/edit-profile-form.component.scss' ], providers: [EmployeeStore] diff --git a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-projects/edit-employee-projects.component.html b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-projects/edit-employee-projects.component.html index 79917f6f8df..40dcb620244 100644 --- a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-projects/edit-employee-projects.component.html +++ b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-projects/edit-employee-projects.component.html @@ -1,9 +1,11 @@ - +
+ +
diff --git a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-projects/edit-employee-projects.component.ts b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-projects/edit-employee-projects.component.ts index 5ea52fe6595..b2c052306c2 100644 --- a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-projects/edit-employee-projects.component.ts +++ b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-projects/edit-employee-projects.component.ts @@ -21,8 +21,18 @@ import { TranslationBaseComponent } from './../../../../../@shared/language-base styles: [ ` :host { - overflow-y: auto; height: calc(100vh - 20.5rem); + + .container-projects { + padding: 1rem; + background-color: var(--gauzy-card-2); + height: 100%; + } + + nb-card { + background-color: var(--gauzy-card-3) !important; + border-radius: var(--card-border-radius); + } } ` ] diff --git a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-rate/edit-employee-rate.component.ts b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-rate/edit-employee-rate.component.ts index 8bc32167d53..84fca2ea09a 100644 --- a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-rate/edit-employee-rate.component.ts +++ b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-rate/edit-employee-rate.component.ts @@ -8,7 +8,7 @@ import { Component } from '@angular/core'; styles: [ ` :host { - overflow-y: auto; + overflow-y: auto; height: calc(100vh - 20.5rem); } ` diff --git a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-settings/edit-employee-other-settings.component.html b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-settings/edit-employee-other-settings.component.html index b66cbc73fa2..e57d4d6ca18 100644 --- a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-settings/edit-employee-other-settings.component.html +++ b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee-profile/edit-employee-settings/edit-employee-other-settings.component.html @@ -17,14 +17,6 @@

-
- -
@@ -82,5 +74,13 @@

+
+ +
diff --git a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee.component.scss b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee.component.scss index 0bbb115887b..b606299863a 100644 --- a/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee.component.scss +++ b/apps/gauzy/src/app/pages/employees/edit-employee/edit-employee.component.scss @@ -103,7 +103,7 @@ :host { @include nb-card_overrides( - unset, + hidden, calc($default-card-height + 3.5rem), $default-radius ); diff --git a/package.json b/package.json index 7acf575bf82..fe13df5b35a 100644 --- a/package.json +++ b/package.json @@ -381,6 +381,9 @@ "overrides": { "prebuild": { "node-gyp": "$node-gyp" + }, + "iconv": { + "node-gyp": "9.3.1" } }, "engines": { diff --git a/packages/core/package.json b/packages/core/package.json index b7a5cd4f554..13c090bedca 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -113,7 +113,7 @@ "dotenv": "^16.0.3", "email-templates": "^8.0.8", "express": "^4.17.2", - "express-session": "^1.17.2", + "express-session": "^1.17.3", "fast-json-stringify": "^2.4.1", "fastify-swagger": "^4.12.4", "fs-extra": "^10.1.0", @@ -149,7 +149,8 @@ "pg": "^8.11.3", "pg-query-stream": "^4.5.3", "prettier": "^2.8.4", - "redis": "^3.1.2", + "redis": "^4.6.12", + "connect-redis": "^7.1.0", "reflect-metadata": "^0.1.13", "request": "^2.88.2", "rimraf": "^3.0.2", diff --git a/packages/core/src/app.module.ts b/packages/core/src/app.module.ts index ad88e9676ef..a67ee84f8b6 100644 --- a/packages/core/src/app.module.ts +++ b/packages/core/src/app.module.ts @@ -3,7 +3,7 @@ import { APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core'; import { MulterModule } from '@nestjs/platform-express'; import { ThrottlerModule, ThrottlerModuleOptions } from '@nestjs/throttler'; import { ThrottlerBehindProxyGuard } from 'throttler/throttler-behind-proxy.guard'; -import { SentryInterceptor, SentryModule } from '@ntegral/nestjs-sentry'; +import { GraphqlInterceptor, SentryInterceptor, SentryModule } from '@ntegral/nestjs-sentry'; import { ServeStaticModule, ServeStaticModuleOptions } from '@nestjs/serve-static'; import { HeaderResolver, I18nModule } from 'nestjs-i18n'; import { Integrations as SentryIntegrations } from '@sentry/node'; @@ -230,7 +230,12 @@ if (environment.sentry && environment.sentry.dsn) { integrations: sentryIntegrations, tracesSampleRate: process.env.SENTRY_TRACES_SAMPLE_RATE ? parseInt(process.env.SENTRY_TRACES_SAMPLE_RATE) - : 0.01 + : 0.01, + close: { + enabled: true, + // Time in milliseconds to forcefully quit the application + timeout: 3000 + } }) ] : []), @@ -427,12 +432,18 @@ if (environment.sentry && environment.sentry.dsn) { useFactory: () => new SentryInterceptor({ filters: [ + /* Note: It is possible to filter exceptions, e.g. only those that error codes are bigger than 499, but for now we want to see all of them { type: HttpException, filter: (exception: HttpException) => 500 > exception.getStatus() // Only report 500 errors } + */ ] }) + }, + { + provide: APP_INTERCEPTOR, + useFactory: () => new GraphqlInterceptor() } ] : []) diff --git a/packages/core/src/bootstrap/index.ts b/packages/core/src/bootstrap/index.ts index bd2c5193492..95963d482b9 100644 --- a/packages/core/src/bootstrap/index.ts +++ b/packages/core/src/bootstrap/index.ts @@ -4,8 +4,11 @@ import { ConflictException, INestApplication, Type } from '@nestjs/common'; import { NestFactory, Reflector } from '@nestjs/core'; import { NestExpressApplication } from '@nestjs/platform-express'; import { SentryService } from '@ntegral/nestjs-sentry'; +import * as Sentry from '@sentry/node'; import { useContainer } from 'class-validator'; import * as expressSession from 'express-session'; +import RedisStore from 'connect-redis'; +import { createClient } from 'redis'; import * as helmet from 'helmet'; import * as chalk from 'chalk'; import { join } from 'path'; @@ -56,6 +59,30 @@ export async function bootstrap(pluginConfig?: Partial): Promise< if (sentry && sentry.dsn) { // Attach the Sentry logger to the app app.useLogger(app.get(SentryService)); + + // NOTE: possible below is not needed because already included inside SentryService constructor + + process.on('uncaughtException', (error) => { + console.error('Uncaught Exception:', error); + Sentry.captureException(error); + Sentry.flush(2000).then(() => { + process.exit(1); + }); + }); + + process.on('unhandledRejection', (reason, promise) => { + console.error('Unhandled Rejection at:', promise, 'reason:', reason); + Sentry.captureException(reason); + }); + } else { + process.on('uncaughtException', (error) => { + console.error('Uncaught Exception:', error); + process.exit(1); + }); + + process.on('unhandledRejection', (reason, promise) => { + console.error('Unhandled Rejection at:', promise, 'reason:', reason); + }); } app.use(json({ limit: '50mb' })); @@ -76,14 +103,71 @@ export async function bootstrap(pluginConfig?: Partial): Promise< // app.use(csurf()); // We use sessions for Passport Auth - app.use( - expressSession({ - secret: env.EXPRESS_SESSION_SECRET, - resave: true, // we use this because Memory store does not support 'touch' method - saveUninitialized: true - // cookie: { secure: true } // TODO - }) - ); + // For production we use RedisStore + // https://github.com/tj/connect-redis + + let redisWorked = false; + + if (process.env.REDIS_ENABLED) { + try { + const redisClient = await createClient({ + url: process.env.REDIS_URL + }) + .on('error', (err) => { + console.log('Redis Client Error: ', err); + }) + .on('connect', () => { + console.log('Redis Client Connected'); + }) + .on('ready', () => { + console.log('Redis Client ready'); + }) + .on('reconnecting', () => { + console.log('Redis Client reconnecting'); + }) + .on('end', () => { + console.log('Redis Client end'); + }); + + // connecting to Redis + await redisClient.connect(); + + // ping Redis + const res = await redisClient.ping(); + console.log('Redis Client ping: ', res); + + const redisStore = new RedisStore({ + client: redisClient, + prefix: env.production ? 'gauzyprodsess:' : 'gauzydevsess:' + }); + + app.use( + expressSession({ + store: redisStore, + secret: env.EXPRESS_SESSION_SECRET, + resave: false, // required: force lightweight session keep alive (touch) + saveUninitialized: true + // cookie: { secure: true } // TODO + }) + ); + + redisWorked = true; + } catch (error) { + console.log(error); + } + } + + if (!redisWorked) { + app.use( + // this runs in memory, so we lose sessions on restart of server/pod + expressSession({ + secret: env.EXPRESS_SESSION_SECRET, + resave: true, // we use this because Memory store does not support 'touch' method + saveUninitialized: true + // cookie: { secure: true } // TODO + }) + ); + } app.use(helmet()); const globalPrefix = 'api'; @@ -165,7 +249,7 @@ export async function registerPluginConfig(pluginConfig: Partial) } }); - let registeredConfig = getConfig(); + const registeredConfig = getConfig(); return registeredConfig; } diff --git a/packages/core/src/core/file-storage/file-storage.middleware.ts b/packages/core/src/core/file-storage/file-storage.middleware.ts index 3c0c9da7dd6..df012b8561a 100644 --- a/packages/core/src/core/file-storage/file-storage.middleware.ts +++ b/packages/core/src/core/file-storage/file-storage.middleware.ts @@ -5,10 +5,7 @@ import { TenantSettingService } from '../../tenant/tenant-setting/tenant-setting @Injectable() export class FileStorageMiddleware implements NestMiddleware { - - constructor( - private readonly tenantSettingService: TenantSettingService - ) { } + constructor(private readonly tenantSettingService: TenantSettingService) {} /** * @@ -16,32 +13,33 @@ export class FileStorageMiddleware implements NestMiddleware { * @param _response * @param next */ - async use( - _request: Request, - _response: Response, - next: NextFunction - ) { - const authHeader = _request.headers.authorization; - - if (authHeader) { - const token = authHeader.split(' ')[1]; - - // Decode JWT token - const decodedToken: any = jwt.decode(token); - - let tenantSettings = {}; - if (decodedToken && decodedToken.tenantId) { - - // Fetch tenant settings based on the decoded tenantId - tenantSettings = await this.tenantSettingService.get({ - where: { - tenantId: decodedToken.tenantId - } - }); - } + async use(_request: Request, _response: Response, next: NextFunction) { + try { + const authHeader = _request.headers.authorization; + + if (authHeader) { + const token = authHeader.split(' ')[1]; + + // Decode JWT token + const decodedToken: any = jwt.decode(token); - // Attach tenantSettings to the request object - _request['tenantSettings'] = tenantSettings; + let tenantSettings = {}; + + if (decodedToken && decodedToken.tenantId) { + // Fetch tenant settings based on the decoded tenantId + tenantSettings = await this.tenantSettingService.get({ + where: { + tenantId: decodedToken.tenantId + } + }); + } + + // Attach tenantSettings to the request object + _request['tenantSettings'] = tenantSettings; + } + } catch (error) { + console.log('Error while getting Tenant settings: %s', error?.message); + console.log(_request.path, _request.url); } next(); diff --git a/packages/core/src/integration-tenant/integration-tenant.service.ts b/packages/core/src/integration-tenant/integration-tenant.service.ts index bdbdfff4614..3d94e08cc5f 100644 --- a/packages/core/src/integration-tenant/integration-tenant.service.ts +++ b/packages/core/src/integration-tenant/integration-tenant.service.ts @@ -38,7 +38,7 @@ export class IntegrationTenantService extends TenantAwareCrudService { + async create(input: IIntegrationTenantCreateInput): Promise { try { const tenantId = RequestContext.currentTenantId() || input.tenantId; let { organizationId, entitySettings = [], settings = [] } = input; @@ -84,9 +82,7 @@ export class IntegrationTenantService extends TenantAwareCrudService { + public async getIntegrationByOptions(input: IIntegrationTenantFindInput): Promise { try { const tenantId = RequestContext.currentTenantId() || input.tenantId; const { organizationId, name } = input; @@ -101,11 +97,11 @@ export class IntegrationTenantService extends TenantAwareCrudService { + async getIntegrationTenantSettings(input: IIntegrationTenantFindInput): Promise { try { const tenantId = RequestContext.currentTenantId() || input.tenantId; + const { organizationId, name } = input; return await this.findOneByOptions({ @@ -137,7 +131,7 @@ export class IntegrationTenantService extends TenantAwareCrudService 0) { + if (integrationTenant && integrationTenant.settings && integrationTenant.settings.length > 0) { // Convert settings array to an object const { apiKey, apiSecret, openAiApiSecretKey } = arrayToObject( - settings, + integrationTenant.settings, 'settingsName', 'settingsValue' ); @@ -76,6 +77,7 @@ export class IntegrationAIMiddleware implements NestMiddleware { } } catch (error) { console.log('Error while getting AI integration settings: %s', error?.message); + console.log(request.path, request.url); } // Continue to the next middleware or route handler diff --git a/packages/core/src/integration/github/github.middleware.ts b/packages/core/src/integration/github/github.middleware.ts index 7cb6e23ecda..d96c3f76ff9 100644 --- a/packages/core/src/integration/github/github.middleware.ts +++ b/packages/core/src/integration/github/github.middleware.ts @@ -19,6 +19,7 @@ export class GithubMiddleware implements NestMiddleware { const tenantId = queryParameters.tenantId ? queryParameters.tenantId.toString() : request.header('Tenant-Id'); + const organizationId = queryParameters.organizationId ? queryParameters.organizationId.toString() : request.header('Organization-Id'); @@ -27,7 +28,7 @@ export class GithubMiddleware implements NestMiddleware { if (isNotEmpty(tenantId) && isNotEmpty(organizationId)) { try { // Fetch integration settings from the service - const { settings = [] } = await this._integrationTenantService.findOneByIdString( + const integrationTenant = await this._integrationTenantService.findOneByIdString( integrationId, { where: { @@ -45,16 +46,23 @@ export class GithubMiddleware implements NestMiddleware { } } ); - /** Create an 'integration' object and assign properties to it. */ - request['integration'] = new Object({ - // Assign properties to the integration object - id: integrationId, - name: IntegrationEnum.GITHUB, - // Convert the 'settings' array to an object using the 'settingsName' and 'settingsValue' properties - settings: arrayToObject(settings, 'settingsName', 'settingsValue') - }); + + if (integrationTenant && integrationTenant.settings.length > 0) { + /** Create an 'integration' object and assign properties to it. */ + request['integration'] = new Object({ + // Assign properties to the integration object + id: integrationId, + name: IntegrationEnum.GITHUB, + // Convert the 'settings' array to an object using the 'settingsName' and 'settingsValue' properties + settings: arrayToObject(integrationTenant.settings, 'settingsName', 'settingsValue') + }); + } } catch (error) { - console.log('Error while getting AI integration settings: %s', error?.message); + console.log( + `Error while getting integration (${IntegrationEnum.GITHUB}) tenant inside middleware: %s`, + error?.message + ); + console.log(request.path, request.url); } } } diff --git a/packages/core/src/main.ts b/packages/core/src/main.ts index 5643b0833c0..dfc0807e3a8 100644 --- a/packages/core/src/main.ts +++ b/packages/core/src/main.ts @@ -2,6 +2,6 @@ import { bootstrap } from './bootstrap'; import { devConfig } from './dev-config'; bootstrap(devConfig).catch((error) => { - console.log(error); + console.error(error); process.exit(1); -}); \ No newline at end of file +}); diff --git a/yarn.lock b/yarn.lock index 9636f23a0ff..f3596503924 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8163,6 +8163,40 @@ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== +"@redis/bloom@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@redis/bloom/-/bloom-1.2.0.tgz#d3fd6d3c0af3ef92f26767b56414a370c7b63b71" + integrity sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg== + +"@redis/client@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@redis/client/-/client-1.5.13.tgz#78786218fc1632ee4b5f7d73b8d456c95880e086" + integrity sha512-epkUM9D0Sdmt93/8Ozk43PNjLi36RZzG+d/T1Gdu5AI8jvghonTeLYV69WVWdilvFo+PYxbP0TZ0saMvr6nscQ== + dependencies: + cluster-key-slot "1.1.2" + generic-pool "3.9.0" + yallist "4.0.0" + +"@redis/graph@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@redis/graph/-/graph-1.1.1.tgz#8c10df2df7f7d02741866751764031a957a170ea" + integrity sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw== + +"@redis/json@1.0.6": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@redis/json/-/json-1.0.6.tgz#b7a7725bbb907765d84c99d55eac3fcf772e180e" + integrity sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw== + +"@redis/search@1.1.6": + version "1.1.6" + resolved "https://registry.yarnpkg.com/@redis/search/-/search-1.1.6.tgz#33bcdd791d9ed88ab6910243a355d85a7fedf756" + integrity sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw== + +"@redis/time-series@1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@redis/time-series/-/time-series-1.0.5.tgz#a6d70ef7a0e71e083ea09b967df0a0ed742bc6ad" + integrity sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg== + "@rollup/plugin-babel@^5.3.0": version "5.3.1" resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283" @@ -14330,7 +14364,7 @@ cls-hooked@^4.2.2: emitter-listener "^1.0.1" semver "^5.4.1" -cluster-key-slot@^1.1.0: +cluster-key-slot@1.1.2, cluster-key-slot@^1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac" integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA== @@ -14819,6 +14853,11 @@ connect-history-api-fallback@^2.0.0: resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== +connect-redis@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/connect-redis/-/connect-redis-7.1.0.tgz#6618334697f2ed91536848cdc03734def2138acf" + integrity sha512-UaqO1EirWjON2ENsyau7N5lbkrdYBpS6mYlXSeff/OYXsd6EGZ+SXSmNPoljL2PSua8fgjAEaldSA73PMZQ9Eg== + connect@^3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" @@ -19094,7 +19133,7 @@ express-handlebars@^6.0.3: graceful-fs "^4.2.10" handlebars "^4.7.7" -express-session@^1.17.2: +express-session@^1.17.3: version "1.17.3" resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.17.3.tgz#14b997a15ed43e5949cb1d073725675dd2777f36" integrity sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw== @@ -20280,6 +20319,11 @@ generic-names@^4.0.0: dependencies: loader-utils "^3.2.0" +generic-pool@3.9.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/generic-pool/-/generic-pool-3.9.0.tgz#36f4a678e963f4fdb8707eab050823abc4e8f5e4" + integrity sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g== + genfun@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/genfun/-/genfun-5.0.0.tgz#9dd9710a06900a5c4a5bf57aca5da4e52fe76537" @@ -32962,6 +33006,18 @@ redis@^3.1.2: redis-errors "^1.2.0" redis-parser "^3.0.0" +redis@^4.6.12: + version "4.6.12" + resolved "https://registry.yarnpkg.com/redis/-/redis-4.6.12.tgz#b607c93e9b0dd09e641f837092e9a68cc6ac6570" + integrity sha512-41Xuuko6P4uH4VPe5nE3BqXHB7a9lkFL0J29AlxKaIfD6eWO8VO/5PDF9ad2oS+mswMsfFxaM5DlE3tnXT+P8Q== + dependencies: + "@redis/bloom" "1.2.0" + "@redis/client" "1.5.13" + "@redis/graph" "1.1.1" + "@redis/json" "1.0.6" + "@redis/search" "1.1.6" + "@redis/time-series" "1.0.5" + "ref-napi@^2.0.1 || ^3.0.2": version "3.0.3" resolved "https://registry.yarnpkg.com/ref-napi/-/ref-napi-3.0.3.tgz#e259bfc2bbafb3e169e8cd9ba49037dd00396b22" @@ -38668,6 +38724,11 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== +yallist@4.0.0, yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" @@ -38678,11 +38739,6 @@ yallist@^3.0.0, yallist@^3.0.2, yallist@^3.1.1: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: version "1.10.2" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"