A re-verification of every draft and published advisory against develop found 9 fully closed and 8
with residuals. This closes the code-fixable ones. Three patterns cover almost all of them:
1. `{ id, ...body }` — the body wins. A path id spread BEFORE the body is overridden by a body `id`,
and save()/create() with an existing PK is an UPDATE of that row: every authorization check ran
against the path id while the write hit the body id. On PUT /user/:id that is account takeover
(a PROFILE_EDIT employee posts {"id":"<SUPER_ADMIN>","hash":"..."}). The id is now pinned LAST in
all 25 controllers/handlers with that shape, UserService.updateProfile pins entity.id = id, and
TenantAwareCrudService.create/save/createMany/saveMany refuse an entity whose id already names a
row of ANOTHER tenant (or a tenant-less row) — the update-through-create endpoints had no other
ownership check. (GHSA-x4mv-fhwj-g3rp, GHSA-gwpq-mmw7-vx85)
2. A client-supplied value decides an authorization branch. The register handler gated "only a
SUPER_ADMIN may register a SUPER_ADMIN" on input.user.role.name, and POST /user had no gate at
all. Both now resolve EVERY role identifier (the flat roleId and the role relation — the relation
wins on persist) from the database in the caller's tenant and fail closed on an id that does not
resolve. (GHSA-hjcg-633x-qq74, GHSA-x4mv-fhwj-g3rp)
3. Only the root row is tenant-scoped. SharedEntity turned caller-supplied shareRules.relations
straight into TypeORM relations on a @Public() token route, so a share of an OWNED Organization
could pivot featureOrganizations -> feature -> featureOrganizations -> tenant -> organizations ->
employees -> user into every tenant. Relations are now validated against entity metadata (each hop
must exist AND target a tenant-scoped entity), depth-bounded, joined rows are scope-filtered,
tenant-less roots are refused, and create/update bodies are whitelisted. (GHSA-cx2q-xmh2-pc38,
GHSA-gpg5-qwjc-8hqh)
Also:
- /invite/accept mass-assignment: AuthService.register strips id/hash/emailVerifiedAt/emailToken/
code/codeExpireAt/refreshToken from input.user, honours createdByUserId only for the authenticated
caller, pins user.tenantId to the trusted tenant; invite accept pins the invited email.
(GHSA-929w-5p4w-cxjp)
- TimeOffStatusHandler used raw repositories with no tenant scope (an admin of tenant A could
approve/deny tenant B's requests); equipment-sharing deleted the request_approval row unscoped, and
its status change went through an update() that deletes and re-inserts — a { status }-only body
replaced the record with a stub. (GHSA-gwpq-mmw7-vx85)
- Hubstaff /refresh-token no longer returns the refresh token. (GHSA-3rqg-gpm9-gx84)
- Upload filters on the endpoints that had none: POST /import (archive allowlist), POST
/ai-chat/attachments and the 5 registry upload routes (script-capable-extension denylist).
(GHSA-p334-cm7f-php5)
- docker-compose defaults NODE_ENV to production so the insecure-secret guard actually fires (compose
`environment:` overrode .env.compose and the image ENV); render blueprints generate their secrets
instead of shipping secretKey/refreshSecretKey/gauzy, and the CORP policy is overridable
(CORP_POLICY) because API and webapp live on two different *.onrender.com sites.
(GHSA-chm8-2ggf-pgjq)
And a functional bug found on the way: POST /ai-chat/attachments was broken on the default LOCAL file
provider. It used Nest's @UploadedFile(), which hands over multer's diskStorage object — no `key` (only
core's @UploadedFileStorage() maps it through provider.mapUploadedFile, where LOCAL derives key from
path) — so the service threw 400 AFTER the bytes were written, leaving an orphan. It now uses the core
decorator, never puts a browser-renderable extension on the stored object name, and deletes the stored
object when the upload is rejected (service) or when sniffFile rejects it (docs chat-capture).
PUT /product-types/:id was likewise a silent 400 for every caller (a DTO instance was passed to
EntityManager.save, which resolves metadata from the constructor); it now saves with an explicit
entity target under the verified id.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* feat(plugin-posthog): initial setup of PostHog plugin
* feat(posthog): add interfaces for PostHog module configuration
* feat(posthog): add constant for injection token
* feat(posthog): implement PosthogService with track, identify and shutdown methods
* feat(posthog): implement core module with support for sync and async config
* feat(posthog): create main module with forRoot and forRootAsync
* chore(posthog):install latest posthog-node
* feat(posthog): update PostHog interfaces to match official client options
* feat(posthog): enhance PostHog service with feature flag support and alignment with official client
* feat(posthog): update PostHog interfaces to match official client options
* feat(middleware): add PosthogRequestMiddleware for capturing request context
* feat(middleware): enhance PosthogTraceMiddleware with performance metrics
* feat(interceptor): implement PosthogErrorInterceptor for error tracking
* feat(plugin): create base PosthogPlugin structure
* feat(interceptor): implement PosthogCustomInterceptor
* feat(config):Add config posthog
* add plugin
* feat(posthog): Refactor service logic && update config
* Remove unnecessary changes
* feat(posthog):Refactor and reorganize the plugin codebase for better structure and maintainability
* fix: deepscan
* feadback integration
* suggestion integration
* remove unecessary changes
* FIx for "demo" var that was not usin .env.compose
* Adding data forlder to ever-gauzy/.deploy/redis/data
because compose could not mount biond point.
"Error response from daemon: Bind mount failed:
'ever-gauzy/.deploy/redis/data' does not exists
* Update docker-compose.yml
---------
Co-authored-by: Ruslan Konviser <evereq@gmail.com>
Note: I don't think it solve anything because we still see ERROR in logs for JITSU: [ERROR]: ❌ Airbyte integration is disabled: volume with name: jitsu_workspace hasn't been mounted to the current docker container. The volume is required for Airbyte integration. Please add -v jitsu_workspace:/home/eventnative/data/airbyte to your Jitsu container run
* Did jitsu intergration for
capturing events data, currently work in
progress
* PR fixes - adopt new Jitsu env vars naming , refactor app.module to
follow conventions , NB not final commit
* correct Jitsu app module provides definition
* refactor jitsu service handle when no configs are
found , include new events interface type
* added jitsu events types and enums
* work on adding user identity to jitsu events
* add user id and mail identity to analytics click
* clean . env file remove console logs in jitsu
service
* clean env files
* Jitsu Configuration remove unnecessary string
* Finished up adding more jitsu analytics
methods and cleanups
* rename variable function adpatExternalUrl
to getExternalUrl