1
0
Commit Graph

4481 Commits

Author SHA1 Message Date
Ahmed Bouhuolia 0971b3c9ce update pnpm-lock.yaml 2026-05-18 23:54:21 +02:00
Ahmed Bouhuolia e9b5974182 wip 2026-05-18 23:52:45 +02:00
Ahmed Bouhuolia 73578ab902 wip 2026-05-18 16:08:33 +02:00
Ahmed Bouhuolia c69515f618 wip 2026-05-18 13:29:16 +02:00
Ahmed Bouhuolia b1766a9c6f Merge branch 'develop' into feat/ee-workspaces-multi-org-pr 2026-05-18 13:25:35 +02:00
Ahmed Bouhuolia 54dd475ec3 Merge pull request #1097 from bigcapitalhq/fix/sortorder-sql-injection
fix(server): prevent SQL injection via sortOrder in DynamicListing (GHSA-hcp2-qqg6-jjpm)
2026-05-16 21:42:43 +02:00
Ahmed Bouhuolia c23bc76afa fix(server): prevent SQL injection via sortOrder in DynamicListing (GHSA-hcp2-qqg6-jjpm)
Validate sortOrder against an allowlist at the DTO layer, normalize the
direction centrally in DynamicFilterSortBy.buildQuery, and re-sanitize
inside every orderByRaw modifier so attacker-controlled SQL cannot reach
the ORDER BY clause.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 21:35:22 +02:00
Ahmed Bouhuolia 9f5aebec1d Merge pull request #1096 from bigcapitalhq/fix/predictable-s3-attachment-keys
fix(server): use CSPRNG for attachment S3 keys (GHSA-gj48-p5ff-g67f)
2026-05-16 19:59:22 +02:00
Ahmed Bouhuolia ace15dbdeb fix(server): use CSPRNG for attachment S3 keys (GHSA-gj48-p5ff-g67f)
The multer-s3 storage factory used `Date.now().toString()` as the S3 key
for every upload, yielding a 13-digit ms-epoch key. The keyspace for any
time window equals the millisecond count of that window, so an attacker
holding a registered account can enumerate keys for known upload moments
(e.g. ~10 minutes for a 10-second window with a 10-proxy rotation), then
download files via `GET /attachments/:id/presigned-url`. Two uploads in
the same millisecond also collide and silently overwrite each other.

Replace the key callback with `${organizationId}/${randomUUID()}`:

  * `randomUUID()` from `node:crypto` is a v4 UUID with 122 bits of
    entropy, making brute-force enumeration infeasible.
  * The `<organizationId>/` prefix (read from the `nestjs-cls` store
    populated by `ClsModule` middleware in `App.module.ts`) limits the
    blast radius of any hypothetical bucket-listing leak to a single
    tenant.

Add a tenant migration applying `unique` to `documents.key` so any future
key collision surfaces as a DB error instead of a silent S3 overwrite.

Legacy 13-digit numeric keys remain accessible via their stored values;
only new uploads use the new format.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 19:38:39 +02:00
Ahmed Bouhuolia cd8d10afc0 Merge pull request #1094 from bigcapitalhq/fix/tenant-bypass-organization-id-header
fix(server): prevent cross-tenant access via organization-id header
2026-05-15 21:19:36 +02:00
Ahmed Bouhuolia 7efac090a9 fix(server): prevent cross-tenant access via organization-id header
Resolve a CLS middleware in App.module.ts to copy the request
`organization-id` header straight into `cls.organizationId`, which the
TenancyDB factory used to pick the per-tenant database. The JWT path
never set `organizationId` from the authenticated user, and
TenancyGlobalGuard only checked that the header was present — so any
authenticated user could read or write another tenant's database by
sending their own JWT plus the victim's `organization-id`.

Make the JWT-resolved tenant the source of truth and validate the
header at the edge:

- AuthSigninService.verifyPayload now loads the user's tenant and sets
  `cls.organizationId` from `tenant.organizationId`, mirroring the
  API-key path in AuthApiKeyAuthorizeService.
- TenancyGlobalGuard rejects with `Organization mismatch.` when the
  request header disagrees with the CLS value set by the auth guard.
- App.module.ts no longer seeds `cls.organizationId` from the
  attacker-controlled request header.

GHSA-2g96-86rw-qmvg

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 20:43:14 +02:00
Ahmed Bouhuolia a9d2316fc2 Merge pull request #1093 from bigcapitalhq/fix/attachment-tenant-isolation
fix(server): prevent cross-tenant attachment access (IDOR)
2026-05-15 14:54:19 +02:00
Ahmed Bouhuolia e18e61000d fix(server): prevent cross-tenant attachment access (IDOR)
Add tenant-scoped document lookup with throwIfNotFound() before S3
operations in GetAttachment, DeleteAttachment, and
GetAttachmentPresignedUrl services. This prevents users from reading,
deleting, or generating presigned URLs for attachments belonging to
other tenants.

Also adds RequirePermission decorators to the three attachment
endpoints and introduces Attachment ability subject with View and
Delete actions.

GHSA-rc4v-wq22-v6cf

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 14:47:18 +02:00
Ahmed Bouhuolia c53bf60406 wip 2026-05-12 18:25:52 +02:00
Ahmed Bouhuolia 3c87abd34e Merge pull request #1091 from bigcapitalhq/chore/update-openapi-sdk-types
chore(sdk): update OpenAPI spec and generated types
2026-05-12 18:24:55 +02:00
abouolia 66ffff5b8d chore(sdk): update OpenAPI spec and generated types 2026-05-12 08:56:28 +00:00
Ahmed Bouhuolia f8afa00f29 Merge pull request #1089 from c-premus/fix/dynamic-filter-pagination 2026-05-12 10:53:54 +02:00
Ahmed Bouhuolia f3cb3b9722 Merge pull request #1090 from rebekah-create/fix/liabilties-typo 2026-05-12 08:53:45 +02:00
rebekah-create 3cbc4842b9 fix(server): correct "Liabilties" typo to "Liabilities" in balance sheet
The balance sheet rendered "Current Liabilties" in the Liabilities
section because of a typo in the i18n key, the schema reference, the
swagger example responses, and the generated SDK fixtures. Fixed all
five locations so PDF/HTML/JSON renders all read "Current Liabilities".

- packages/server/src/i18n/en/balance_sheet.json: rename key and value
- packages/server/src/modules/FinancialStatements/modules/BalanceSheet/
  BalanceSheetSchema.ts: update i18n key reference
- packages/server/src/modules/FinancialStatements/modules/BalanceSheet/
  BalanceSheet.swagger.ts: fix three example response strings
- shared/sdk-ts/openapi.json + schema.ts: regenerate to match
2026-05-12 00:10:44 -04:00
Chris 46012a1b1c Fix pagination params silently ignored on collection GET endpoints
Hoist `page` and `pageSize` declarations from the per-module DTOs into
the shared DynamicFilterQueryDto base class. Without these declarations,
the global ValidationPipe (whitelist: true) strips the params from the
request before the service layer sees them, so list services fall back
to their default page=1, pageSize=12 regardless of what the client sent.

Affects 10 collection GET endpoints whose query DTOs are empty subclasses
of DynamicFilterQueryDto: expenses, bills, credit-notes, manual-journals,
payments-received, sale-invoices, sale-estimates, sale-receipts,
vendor-credits, item-categories.

The 3 already-working DTOs (Customers, Vendors, Items) keep their local
page/pageSize declarations as redundant overrides — no behavior change.

Closes #1088
2026-04-29 11:51:49 +00:00
Ahmed Bouhuolia 6ef1a6a651 wip 2026-04-17 01:10:27 +02:00
Ahmed Bouhuolia 91f3c28737 wip 2026-04-15 22:09:25 +02:00
Ahmed Bouhuolia a1430db37e wip 2026-04-15 00:35:17 +02:00
Ahmed Bouhuolia 70ff1fc179 wip 2026-04-14 21:36:40 +02:00
Ahmed Bouhuolia ff1cfb63bf chore: update pnpm-lock.yaml dependency resolutions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 23:54:45 +02:00
Ahmed Bouhuolia 52c97f1401 Merge pull request #1075 from bigcapitalhq/fix/export-i18n-column-headers
fix(server): localize i18n column headers in CSV/XLSX/PDF exports
2026-04-13 18:37:38 +02:00
Ahmed Bouhuolia 3db9061c60 fix(server): localize i18n column headers in export (CSV/XLSX/PDF)
Export column headers displayed raw i18n keys like
`expense.field.payment_account` instead of translated names like
"Payment Account" because ExportResourceService never resolved the
i18n keys before rendering.

Inject I18nService and translate column names in both
getExportableColumns() (CSV/XLSX) and getPrintableColumns() (PDF).

Closes #1073

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 18:32:24 +02:00
Ahmed Bouhuolia 37d5546763 Merge pull request #1074 from bigcapitalhq/fix/financial-reports-base-currency
fix(server): use correct base currency in financial reports
2026-04-13 17:58:19 +02:00
Ahmed Bouhuolia a7a0a7fbe7 fix(server): use correct base currency in financial reports
Reports (Receivable Aging Summary, Payable Aging Summary, Inventory
Valuation, Sales Tax Liability Summary, Vendor Balance Summary) were
not assigning baseCurrency from meta in their constructors, causing
currency formatting to fall back to USD instead of the organization's
base currency.

Closes #1069

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 17:52:46 +02:00
Ahmed Bouhuolia a306c62710 wip 2026-04-07 20:43:46 +02:00
Ahmed Bouhuolia ceef73ba0a wip 2026-04-04 00:35:56 +02:00
Ahmed Bouhuolia 6e04440fbd wip 2026-04-03 11:51:34 +02:00
Ahmed Bouhuolia 5944aa3972 Merge pull request #1063 from Y8C68/fix/attachment-content-type 2026-04-03 09:16:08 +02:00
Y8C68 dd58f50387 fix(server): handle missing ContentType in attachment download
GET /api/attachments/:id crashes with "Cannot read properties of
undefined (reading extension)" when the S3 object has no ContentType
metadata. This happens when files are uploaded without explicit content
type (e.g., via API integrations).

mime.extension(undefined) returns undefined, which then causes the
Content-Disposition header template to fail.

Fix: fallback to "application/octet-stream" when ContentType is missing,
and "bin" when mime.extension() returns undefined.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 06:11:28 +00:00
Ahmed Bouhuolia dfdbd7af6c feat(workspaces): add API endpoints and types for workspace management
- Implemented endpoints for listing, creating, and deleting workspaces, along with fetching build job status.
- Defined new data transfer objects (DTOs) for workspace creation and response handling.
- Updated OpenAPI schema to reflect the new workspace operations and their respective request/response structures.
- Introduced a new module for workspace-related functionalities in the SDK.
2026-04-01 23:33:30 +02:00
Ahmed Bouhuolia 1a73d499ee feat(workspaces): enhance workspace creation and job management
- Introduced a transaction for creating tenants, linking users, and saving metadata in the `CreateWorkspaceService`.
- Moved tenant marking as building to the `markAsBuilding` method for better separation of concerns.
- Added `WorkspaceBuildJobResponseDto` for improved API response structure.
- Updated `GetWorkspacesService` to utilize a transformer for cleaner data mapping.
- Added unit tests for `CreateWorkspaceService` to ensure robust functionality and error handling.
2026-04-01 23:32:28 +02:00
Ahmed Bouhuolia e9747f4f9e Merge pull request #1056 from bigcapitalhq/chore/webapp-format-script
chore(webapp): add Prettier format and format:check scripts
v0.25.20
2026-03-27 18:24:29 +02:00
Ahmed Bouhuolia ccb34e2155 chore(webapp): add format and format:check scripts
Add Prettier scripts to webapp package for code formatting, consistent
with the existing server package setup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-27 18:21:23 +02:00
Ahmed Bouhuolia 1c93244801 Merge pull request #1055 from bigcapitalhq/chore/update-openapi-sdk-types 2026-03-27 17:43:51 +02:00
abouolia 2492a5b043 chore(sdk): update OpenAPI spec and generated types 2026-03-27 14:37:15 +00:00
Ahmed Bouhuolia b0db59a495 feat(webapp): customer/vendor form ux improvement (#1053)
* feat(webapp): customer/vendor form ux improvement
2026-03-27 16:34:52 +02:00
rmb 580392a408 fix: bulk uncategorize transactions API endpoint (#1054)
* fix: bulk uncategorize transactions - fix API endpoint and error handling

* refactor: use params object instead of URLSearchParams for delete request

Simplifies the API call by passing params object directly to the delete
method instead of manually building URLSearchParams.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Ahmed Bouhuolia <a.bouhuolia@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-27 16:30:19 +02:00
Ahmed Bouhuolia a1d1f53773 fix: typescript errors 2026-03-27 16:29:44 +02:00
Ahmed Bouhuolia f5d1800c8c wip 2026-03-27 16:11:33 +02:00
Ahmed Bouhuolia 4dc5c5abe0 wip 2026-03-27 13:14:54 +02:00
Ahmed Bouhuolia d5cc3d1a71 wip 2026-03-27 11:29:57 +02:00
Ahmed Bouhuolia 50ba91ecf1 fix 2026-03-27 09:57:03 +02:00
Ahmed Bouhuolia 5ba753e808 wip 2026-03-27 01:08:57 +02:00
Ahmed Bouhuolia 2e90e3cc5b wip 2026-03-26 18:04:33 +02:00
Ahmed Bouhuolia 8b59f28125 wip 2026-03-26 17:40:24 +02:00