Commit Graph

227 Commits

Author SHA1 Message Date
Henry
6b8ada8d90 feat: duplicate card via dropdown 2026-05-29 23:27:21 +01:00
Henry
833c69a73e cloud: enable workspace slots for partners 2026-05-29 22:58:09 +01:00
Henry
8d8cfa3bae feat(cloud): pause members when subscription is cancelled 2026-05-21 22:52:17 +01:00
Henry
861416a18e feat(cloud): set seat limit checks for partner member invitations (#506) 2026-05-21 21:36:57 +01:00
Henry
cf566e04c6 feat(cloud): improved upgrade journey 2026-05-18 23:20:11 +01:00
Nick Meinhold
f801d2a7eb fix(s3): default S3_REGION to us-east-1 instead of empty string (#495)
The AWS SDK throws "Region is missing" when S3Client is constructed
with an empty-string region, so any S3 feature (avatars, attachments,
presigned URL generation) is silently broken when S3_REGION is unset
— even though .env.example ships it unset and env.ts declares it
optional. The schema and the runtime disagreed about whether the var
was required.

Default to "us-east-1" in createS3Client. S3-compatible providers
(MinIO, Backblaze B2, R2, DigitalOcean Spaces, Wasabi) ignore the
region entirely; real AWS S3 users should set S3_REGION explicitly
to their bucket's actual region (clarified in .env.example).

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 22:56:48 +01:00
Nick Meinhold
d9157b6218 fix(workspace): point package "types" exports at src/, not stale dist/ (#496)
Each workspace package had its exports map pointing `types` at
`./dist/...d.ts` while `default` pointed at `./src/...ts`. The dist
directory is a build artifact only refreshed when someone runs
`pnpm build` in that package — meaning every other package in the
monorepo typechecks against last week's type signatures.

Concrete failure mode: contributor edits a function in
packages/shared/src/utils/foo.ts (changes a parameter type, adds a
new export, etc.), runs `pnpm typecheck` from root, sees green. The
check actually validated against the stale dist/.d.ts. Real type
errors stay invisible until CI builds shared first, by which point
the diff is already pushed.

Fix: point `types` at the same `src/` paths the runtime resolves to.
TypeScript reads .ts source as types fine when consumers share the
same TS version, which a monorepo guarantees. Verified end-to-end:
adding a new export to shared and immediately typechecking @kan/api
now picks it up without rebuilding shared, and breaking a return
type immediately fails the consumer's typecheck.

Applied to @kan/api, @kan/db, @kan/logger, @kan/shared.
@kan/email is intentionally left as-is because its source is .tsx
(JSX) — pointing types at .tsx would force every consumer to enable
--jsx in their tsconfig, which is a worse cascade than the stale
dist problem we're solving.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 22:55:07 +01:00
Henry
cc6804c21d fix(cloud): update license key on conflict 2026-05-14 14:02:17 +01:00
Henry
e26c122d76 fix: add card number fields to zod schemas 2026-05-13 22:11:29 +01:00
Henry
f459c489f9 fix: broken migrations 2026-05-13 21:39:47 +01:00
Henry
60d8e1bd83 feat(cloud): partner integration (#493)
* feat: add partnerLicenseKey and partnerTier to subscription schema

* feat: add repo funcs

* feat: set up partner webhook handler
2026-05-12 22:39:07 +01:00
Henry
3d9e859b31 refactor: small tweaks to password reset flow 2026-05-11 13:43:38 +01:00
Morfixx
71205b67dc fix: unable to change password when using magic link (#484)
* fix: fixed password not resetting & added password prompt with save guards

* fix: migrated to using setPassword
2026-05-11 13:40:59 +01:00
Midas
607672718c Add cardPublicId to card webhook payloads (#490)
* Add cardPublicId to card webhook payloads

* fix: include card publicId in webhook payloads

Add data.card.publicId to webhook payloads while keeping data.card.id for compatibility, and update card/webhook call sites and tests so webhook consumers can reliably use public IDs.
2026-05-11 13:22:21 +01:00
Henry
dd262ee50f fix: allow reordering without supplying an index when updating cards (#492) 2026-05-11 13:18:07 +01:00
Florent Azonnoudo
4658b2961c feat: add ticket numbers to cards with workspace prefix (#443)
* feat: add ticket numbers to cards with workspace prefix

- Add cardNumber to cards
- Add cardPrefix/cardCounter to workspace
- Populate initial prefixes and numbers via new migration
- Introduce generateWorkspacePrefix util and export it
- Include cardNumber in card-related API responses and search results
- Render and display tickets as PREFIX-NUMBER in UI
- Update Card component to accept ticketNumber
- Update CardModal and board cards to show number when available
- Add cardNumber to CommandPalette search results type

* feat: regen migration

* feat: enhance card and workspace schemas with cardNumber and indexing

- Updated the card repository to allocate card numbers atomically per workspace.
- Modified the card schema to include a cardNumber field and added an index on listId and cardNumber for improved query performance.
- Enhanced the workspace schema to include an index on cardPrefix for optimized lookups.
- Adjusted the migration journal to reflect the new schema changes and their timestamps.
- Updated the regex in workspace repository to allow alphanumeric prefixes in ticket IDs.

---------

Co-authored-by: Henry <henry_ball@hotmail.co.uk>
2026-04-28 22:29:41 +01:00
Henry
e32e400976 chore: clean up types (#476) 2026-04-20 22:35:39 +01:00
Louie Chillingworth
b4b07f3120 fix: remove duplicate OIDC provider registration in getSocialProviders (#475)
The getSocialProviders endpoint was manually pushing "oidc" to the 
providers array when OIDC env vars are present, but Better Auth already 
includes the OIDC provider in ctx.context.socialProviders when it is 
configured. This resulted in ["oidc","oidc"] being returned from 
/api/auth/social-providers, causing a duplicate provider registration 
that led to a TypeError: Cannot read properties of null (reading 'id') 
during the OIDC login callback, preventing all OIDC logins.

Fix: remove the manual providers.push("oidc") block as it is redundant.
2026-04-20 21:20:23 +01:00
vvaswani
e39faa1172 fix: use stable public ids for card webhook (#463)
Signed-off-by: Vikram Vaswani <2571660+vvaswani@users.noreply.github.com>
2026-04-20 21:19:31 +01:00
Morfixx
ae4bc77407 feat: added schemas for openapi (#452) 2026-04-18 21:29:35 +01:00
Henry
e36eb64c59 fix(cloud): enable upgrading new and existing workspaces onto team/pro (#470)
* feat(cloud): enable upgrading new and existing workspaces onto team/pro

* refactor: clean up

* fix: toggle spacing
2026-04-17 22:22:14 +01:00
Henry
7045cd8e25 feat(cloud): improved workspace onboarding (#462)
* feat: setup onboarding and select plan page

* feat: add workspace details step

* refactor: optimize board rendering in workspace details

* feat: tweak padding in boards mockup

* fix: validate/convert slug input

* refactor: tweak onboarding steps UX

* feat: add team to workspace plans

* feat: allow setting description when creating a workspace

* feat: add logging to next api routes

* feat: create worspace on checkout.session.completed

* chore: update types

* refactor: improve webhook logs

* feat: create workspace on successful activation

* feat: set slug on workspace name change

* feat: add returnUrl params
2026-04-11 07:59:26 +01:00
Charity
3a44957662 feat: add card context menu and duplication functionality (#381)
* feat: add card context menu and duplication functionality

* Implemented a context menu for cards allowing actions such as copying links, duplicating cards, and managing members, labels, and due dates
* Added modals for card duplication and context actions.
* Updated API with a new endpoint for duplicating cards, including options for copying labels, members, and checklists

* refactor: remove cardPublicId from context menu and related components

* Removed cardPublicId prop from CardContextMenu and CardContextMembersModal for cleaner context handling
* Updated scrollbar styling

* feat: add delete card functionality to context menu
2026-04-01 14:32:56 +01:00
Henry
20e6c99e32 feat: enhance logging with request input (#450) 2026-03-23 22:31:02 +00:00
Henry
596f346181 fix: increase maximum length for boardSlug from 24 to 60 characters (#448) 2026-03-23 16:30:29 +00:00
Henry
7b59e2ac07 feat(cloud): log to docker container 2026-03-22 07:21:30 +00:00
Henry
2a9b1fd2b5 refactor: replace @axiomhq/pino with @axiomhq/js 2026-03-20 13:56:52 +00:00
Henry
dd29dc89fd fix: remove broken dep 2026-03-19 21:33:44 +00:00
Henry
486cdf8313 feat(cloud): setup log drain (#447) 2026-03-19 21:16:47 +00:00
Henry
67cf523ee8 fix: API key authentication and REST handler errors (#446) 2026-03-19 12:20:19 +00:00
Henry
76b2c58461 fix: security improvements to checklist input (#444)
* feat: sanitize input for checklists

* feat: add basic editor

* feat: use plain text editor for checklist items

* feat: remove key from user response
2026-03-16 14:31:13 +00:00
Henry
b8d1fe230d fix: prevent empty string from throwing error 2026-03-13 23:08:46 +00:00
Henry
1fb56aafd0 feat: add logger package to improve observability (#437)
* feat: add logger package to improve observability

* chore: add LOG_LEVEL to docker compose and readme
2026-03-13 22:57:47 +00:00
Matt
8e7a95ff2b feat: workspace start of week column (closes #361) (#399)
* feat: workspace start of week column

* feat(l10n): add workspace setting for the first day of the week

Fixes #361

* feat: add Saturday as option

* chore: fix migration order

* chore: fix merge

---------

Co-authored-by: Henry <henry_ball@hotmail.co.uk>
2026-03-11 20:05:03 +00:00
Nick Meinhold
1d5e3a936c feat(api): add webhook CRUD API router and tests (#393)
* feat(api): add webhook CRUD API router and tests

Add tRPC router for managing workspace webhooks:

- list, create, update, delete endpoints (admin role required)
- test endpoint to send a synthetic payload to a webhook URL
- URL validation, event subscription filtering
- Unit tests for all router procedures
- Integration tests with PGlite test database
- Add vitest config and test infrastructure for API package

Depends on #391 (DB schema & repository).

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

* refactor(api): use assertPermission instead of assertUserInWorkspace

Replace assertUserInWorkspace with assertPermission("workspace:manage")
per project conventions. The permissions system is the preferred
authorization approach for new code.

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

* fix(api): use @kan/db alias instead of relative imports in tests

Replace relative path imports (../../db/src/...) with the @kan/db
alias configured in vitest.config.ts for consistency and robustness.

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

* refactor(api): use webhookUrlSchema in router input validation

Cherry-pick router-related changes from b2cc9ac:
- Use extracted webhookUrlSchema zod validator in create/update
  input schemas for consistent SSRF checks

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

* refactor(api): replace dynamic import with static import for webhook utility

Add packages/api/src/utils/webhook.ts with sendWebhookToUrl,
createCardWebhookPayload, and webhookUrlSchema. Replace the dynamic
import() in the test endpoint with a static import at the top of the
file for better tree-shaking, type-checking, and readability.

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

* fix(api): align sendWebhooksForWorkspace tests with merged PR #392

The merged delivery utility uses client-side event filtering
(getActiveByWorkspaceId takes 2 args, not 3). Update test assertions
to match the actual implementation.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Henry <30578846+hjball@users.noreply.github.com>
2026-03-10 22:27:52 +00:00
Henry
b4d4810f45 fix: migration order (#427) 2026-03-03 21:36:31 +00:00
Morfixx
280d8f66dd feat: initial github integration with importing projects (#421)
* feat: initial github integration with importing projects

* fix: remove unused args

* chore: remove duplicate col

---------

Co-authored-by: Henry <henry_ball@hotmail.co.uk>
2026-03-01 22:39:25 +00:00
Henry
d81950b8bd fix: publish migrate image (#423) 2026-02-27 22:38:01 +00:00
Nick Meinhold
bd25fb33f7 feat(api): add webhook delivery utility and card event integration (#392)
* feat(api): add webhook delivery utility and card event integration

Add the core webhook delivery logic and wire it into card mutations:

- Add sendWebhookToUrl() with HMAC-SHA256 signing, 10s timeout
- Add sendWebhooksForWorkspace() for fan-out delivery (fire-and-forget)
- Add createCardWebhookPayload() for building webhook payloads
- Fire webhooks on card create, update, move, and delete events
- Add unit tests for webhook utility functions

Depends on #391 (DB schema & repository).

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

* fix(api): use correct boardId in webhook payloads and add rejection safety

- Fix bug where workspaceId was incorrectly passed as boardId in all
  webhook payloads — now uses board's publicId via boardPublicId
- Replace void sendWebhooksForWorkspace() with .catch() to prevent
  unhandled promise rejections if the DB query inside fails

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

* fix(api): add SSRF protection to webhook delivery

Block webhook URLs targeting internal networks:
- Require HTTPS (reject HTTP)
- Block localhost, 127.0.0.1, ::1, 0.0.0.0
- Block cloud metadata endpoints (169.254.169.254, metadata.google.internal)
- Block private IP ranges (10.x, 172.16-31.x, 192.168.x)
- Add tests for all blocked URL patterns

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

* refactor(api): use WebhookEvent type from schema instead of duplicating

Replace the hardcoded WebhookEventType union with the canonical
WebhookEvent type from @kan/db/schema, addressing reviewer feedback
on PR #392.

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

* refactor(api): improve webhook delivery safety and validation

Cherry-pick delivery-related changes from b2cc9ac:
- Extract URL validation into reusable webhookUrlSchema zod validator
  for SSRF checks
- Wrap sendWebhooksForWorkspace in try/catch to prevent unhandled
  promise rejections
- Document SSRF risk mitigation on sendWebhookToUrl
- Add corresponding tests

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 13:15:35 +00:00
Eliott Herbert-Byrnes
af36fb133a feat: archived boards (#386)
* init: schema migration, isArchived added to
board table. refactor: board repo for isArchived filtering

* init: archived, unarchived API procedures. refactor: all query

* fix: migration error

* feat: add tabbed navigation for boards view

* Implemented a Listbox for mobile and a tabbed navigation for desktop to switch between "Boards" and "Archived" views.
* Introduced state management for active tab selection.
* Updated UI components to reflect the new navigation structure.

* init: frontend/boards lists & tabs

* chore: fixed font styling and spacing

* init:boardDropdown / boardView.

* chore:added translations

* Remove .cursor plan file from repo

* fix:build erros

* revert: remove locales changes

* fix:reverted changes under locales, replaced the archive and unarchive endpoints. Reorder migrations

* fix:migration issue

* fix: update journal.json

---------

Co-authored-by: Henry <henry_ball@hotmail.co.uk>
2026-02-26 21:39:15 +00:00
Nick Meinhold
5f190b92de fix: allow invited users to sign up when registration is disabled (#418)
* fix: allow invited users to sign up when registration is disabled

Move sign-up restriction logic from better-auth's disableSignUp config
to the existing user.create.before database hook, which already checks
for pending invitations. The frontend signup and login pages now detect
invite flows (?next=/invite/...) and bypass the disabled UI accordingly.

Closes #411

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

* test: add regression tests for sign-up hook invite bypass

Verify that the user.create.before database hook correctly:
- allows sign-up when registration is not disabled
- blocks sign-up when disabled and no invitation exists
- allows sign-up when disabled but a pending invitation exists
- respects BETTER_AUTH_ALLOWED_DOMAINS in combination with invites

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

* test: add OIDC/social sign-up path coverage for invite bypass

Address review suggestion: add explicit tests verifying the
user.create.before hook handles OIDC/social sign-ups the same way as
email/password — invited users are allowed, uninvited users are blocked.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 21:24:58 +00:00
Nick Meinhold
48a1f39588 fix(api): add missing openapi meta to checklist.update (#417)
The checklist.update procedure was inheriting the default
protectedProcedure meta (GET /protected) instead of declaring
its own OpenAPI route, making it unreachable via the REST API.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 21:12:02 +00:00
Henry
91bc319cf1 fix: prevent cross-workspace access on member and permission endpoints (#413) 2026-02-23 22:56:36 +00:00
Henry
71ecf2e6d3 fix: catch and log failed email attempts 2026-02-20 15:42:07 +00:00
Matt
b6b9423823 fix: increase max workspace url length from 24 to 64 characters (closes #379( (#398) 2026-02-17 13:40:58 +00:00
Owais Rizvi
1696aab43b fix: handle empty commenter name in mention notification emails (#400)
Use `||` instead of `??` so empty strings also fall back to email.
The nullish coalescing operator (`??`) only catches null/undefined,
so users with an empty name string would appear nameless in emails.
2026-02-17 13:39:24 +00:00
Nick Meinhold
33d2f23955 feat(db): add webhook schema, migration, and repository (#391)
* feat(db): add webhook schema, migration, and repository

Add the database foundation for workspace webhooks:

- Add workspace_webhooks table with migration (webhook_event enum,
  URL, secret, event subscriptions, active flag)
- Add webhook repository with CRUD operations
- Add webhooks schema definition with relations
- Extend card and list repos to return board/list names for
  webhook payload context

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

* fix(db): remove unused webhook_event enum and fix migration timestamp

- Remove dead webhook_event pgEnum from schema (events column uses text)
- Remove CREATE TYPE statement from migration SQL
- Fix migration journal timestamp to be chronologically after the
  notifications migration (idx 25)

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

* feat(db): return boardPublicId from card and list repo queries

Add board publicId to getWorkspaceAndCardIdByCardPublicId and
getWorkspaceAndListIdByListPublicId return values, needed for
correct boardId in webhook payloads.

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

* fix(db): add workspaceId index and document secret exposure

- Add index on workspaceId for efficient webhook lookups per workspace
- Add JSDoc comment on getActiveByWorkspaceId explaining that it
  returns secrets for server-side HMAC signing only and must never
  be exposed via client-facing endpoints

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

* refactor(db): extract parseEvents helper in webhook repo

DRY up 6 repeated JSON.parse-and-cast calls into a single helper
function, addressing reviewer feedback on PR #391.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 13:23:00 +00:00
Morfixx
961219835e refactor: docker image for less final size (#385) 2026-02-17 13:12:53 +00:00
Nick Meinhold
031a42b9eb fix: generate presigned avatar URLs for card members on board view (#388)
The board.byId query was generating presigned S3 URLs for workspace
member avatars but not for card member avatars. This caused card avatars
to silently fall back to initials since the frontend helper returns ""
for raw S3 keys.

Closes #387

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 21:10:23 +00:00
Matt
8a1189d011 feat: Activity log for uploading attachments (closes #354) (#366)
* feat: Activity log for uploading attachments (closes #354)

* chore: fix coding style

* revert: upload spinning icon patch

* refactor: add fallbacks, extended card_activity
2026-02-15 20:53:01 +00:00