Files
ever-gauzy/apps/worker/package.json
T
Ruslan KonviserandClaude Opus 5 5e77f39920 feat(docs): close the remaining spec gaps — leaks, broken embeds, activity, OCR, extraction
A second spec audit (all 12 documents, every P0/P1 traced UI -> service -> route ->
persistence, each claimed gap independently refuted before being accepted) confirmed 42
gaps. This closes them across seven disjoint areas.

P0

* **`?relations=` leaked PRIVATE documents, including page content.** `toRelationList()`
  had no allowlist and the service spread client relations straight into `findOne()`,
  gating only the top-level row — so `GET /documents/:id?relations=children` returned other
  users' private `contentJson`. Relations are now allowlisted (`children` deliberately
  absent — child listing has its own SQL-scoped route), and any loaded `parent`/`children`
  is run through `DocumentAccessService.canRead` per row and replaced with
  `{ id: null, restricted: true }`. The allowlist alone would still leak through any
  relation added later; the masking is the real fix. Adds `GET /:id/path`, which walks
  ancestors server-side so a breadcrumb can render redacted segments.
* **Every embedded image rendered broken.** The editor set `src` to the JWT-guarded
  `/raw` route and revoked the blob, and no image node view existed — so an unauthenticated
  `<img src>` hit a guarded endpoint on every wiki page. Bytes now resolve through the
  authenticated client into an object URL while `/raw` stays the persisted `src`.
* **The activity timeline was never read back.** The subscriber wrote rows and core exposed
  `GET /activity-log`, but docs-ui had zero activity code — the detail panel printed only
  `updatedAt`. Adds the service, the component, paging, and `System` attribution.

P1/P2 highlights

* Help-center stored-XSS read path; per-route rate limits on upload/search/admin ops;
  TipTap `contentJson` schema validation with `contentHtml` derived from the validated JSON;
  editor cross-links now become real `DocumentLink` rows; org `defaultVisibility` honoured
  on create; `CreateEntitySubscriptionEvent` on create + review-request.
* Chat-tool `FEATURE_DOCUMENTS` gate now reads the per-organization DB flag instead of
  process config, so turning the feature off actually turns it off.
* `.pptx` / `.odt` / `.ods` were accepted on upload and then guaranteed to fail extraction.
  Rather than de-listing the types, first-party dependency-free extractors were written
  (Node `zlib` only): a central-directory ZIP reader with a zip-bomb fuse, and an XML reader
  that skips the doctype whole so no declared entity can expand (XXE / billion-laughs).
* Folder creation at the current/root location (on a new organization the tree is empty, so
  there was NO path to create the first folder), breadcrumbs in table view and on empty
  folders, browse keyboard shortcuts, storage-quota meter (a wire-key mismatch had left it
  permanently hidden), record->Documents panels, and a `canDeactivate` guard so leaving a
  dirty page can no longer silently lose edits.

🛑 The integration pass caught the defect that would have undone the rest: **the `DOCS`
translation namespace was never merged into ngx-translate.**
`PluginUiModule.bootstrapDeclarativePlugins()` skips any plugin declaring a `module`, and
`DocsUiPlugin` declares one, so the merge callback never ran — every label in the Documents
UI would have rendered as a raw key. Fixed with an opt-in `translateService` on the
declarative registration path (omitting it preserves prior behaviour for every other
plugin), plus a spec pinning the load-order rule that made it invisible.

Also fixed here: `docs-unsaved-changes.guard.spec.ts` drove the guard through
`TestBed.resetTestingModule()` inside its helper, which left no instantiated injector and
threw `Cannot read properties of null (reading 'ngModule')` on all six cases. The guard only
needs an injection context, so it now uses a standalone `Injector`.

Verified: plugin-docs, plugin-docs-ui, plugin-ai-chat, plugin-knowledge-base and ui-core all
build clean; 1105 tests pass (522 plugin-docs + 473 plugin-docs-ui + 110 core).

Known open, deliberately not forced: `DocumentPermissionService.canMutate` (item #36) was
not implemented by any area; item #12 covers 4 of 5 surfaces because the fifth would require
`ui-core/shared` to import `@gauzy/plugin-docs-ui`, a real nx project cycle; and
`IDocumentCreateInput.tags` exists in contracts but not on the DTO, which runs
`forbidNonWhitelisted` — latent today because nothing sends it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 14:53:43 +02:00

66 lines
2.0 KiB
JSON

{
"name": "@gauzy/worker",
"version": "0.1.0",
"description": "Gauzy Worker",
"license": "AGPL-3.0",
"homepage": "https://gauzy.co",
"repository": {
"type": "git",
"url": "https://github.com/ever-co/ever-gauzy.git"
},
"bugs": {
"url": "https://github.com/ever-co/ever-gauzy/issues"
},
"private": true,
"author": {
"name": "Ever Co. LTD",
"email": "ever@ever.co",
"url": "https://ever.co"
},
"scripts": {
"start": "yarn nx serve worker",
"start:debug": "nodemon --config nodemon-debug.json",
"start:prod": "yarn nx serve worker --configuration=production",
"build": "yarn nx build worker --configuration=development",
"build:prod": "yarn nx build worker --configuration=production"
},
"dependencies": {
"@gauzy/core": "^0.1.0",
"@gauzy/plugin": "^0.1.0",
"@gauzy/scheduler": "^0.1.0",
"@gauzy/plugin-changelog": "^0.1.0",
"@gauzy/plugin-docs": "^0.1.0",
"@gauzy/plugin-integration-activepieces": "^0.1.0",
"@gauzy/plugin-integration-ai": "^0.1.0",
"@gauzy/plugin-integration-github": "^0.1.0",
"@gauzy/plugin-integration-hubstaff": "^0.1.0",
"@gauzy/plugin-integration-make-com": "^0.1.0",
"@gauzy/plugin-integration-zapier": "^0.1.0",
"@gauzy/plugin-integration-jira": "^0.1.0",
"@gauzy/plugin-integration-sim": "^0.1.0",
"@gauzy/plugin-integration-upwork": "^0.1.0",
"@gauzy/plugin-jitsu-analytics": "^0.1.0",
"@gauzy/plugin-job-proposal": "^0.1.0",
"@gauzy/plugin-job-search": "^0.1.0",
"@gauzy/plugin-knowledge-base": "^0.1.0",
"@gauzy/plugin-product-reviews": "^0.1.0",
"@gauzy/plugin-sentry": "^0.1.0",
"@gauzy/plugin-posthog": "^0.1.0",
"@gauzy/plugin-videos": "^0.1.0",
"@gauzy/plugin-camshot": "^0.1.0",
"@gauzy/plugin-soundshot": "^0.1.0",
"@gauzy/plugin-registry": "^0.1.0",
"dotenv": "^17.2.4",
"yargs": "^17.5.0"
},
"devDependencies": {
"@nestjs/cli": "^11.0.23",
"@nestjs/schematics": "^11.1.0",
"@nestjs/testing": "^11.1.26",
"cross-env": "^10.1.0",
"nodemon": "^3.1.0",
"ts-node": "^10.9.2",
"typescript": "^5.9.3"
}
}