3245 Commits
Author SHA1 Message Date
b2b41dd3ca fix: Remap internal links when duplicating a document tree (#13270)
* fix: Remap internal links when duplicating a document tree

Duplicating a document tree now assigns the identifiers of every duplicate
before any content is written, so links and mentions between the documents
being duplicated point at the copies rather than the originals.

* fix: Remap fully qualified links when duplicating a document tree

Links written as a full url to this installation are now remapped alongside
relative ones, and stay fully qualified. Where a link is displayed as its own
url the text is updated to match.

Also trims surrounding whitespace in sanitizeUrl, which otherwise failed
validation and prepended a second scheme to an already qualified url.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: Remap links across trees when duplicating a collection

The collection duplication task duplicated each root document separately, so
only links within a single tree were remapped. It now duplicates the whole
collection as one unit, with identifiers assigned across every tree before any
content is written.

* fix: Match document links by identifier rather than host when duplicating

An installation can be reached through more than one host, so comparing a
link's host against the configured url left fully qualified links to a
document in the duplicated set unmapped. The document a link identifies now
decides whether it is replaced, and the host it was written with is kept.

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 22:44:06 -04:00
000f2f98fb feat: Add TextPack (.textpack) support (#13235)
* feat: Add TextPack (.textpack) import support

Adds a single-document importer for TextPack, the zipped variant of
TextBundle used by Bear, Ulysses, iA Writer and others. Bare .textbundle
directories are not supported, as a directory cannot be delivered through
a browser file input.

The bundle's text entry may use any extension, per the spec, with
info.json's type deciding whether it can be read as markdown. Assets are
inlined as data URIs for the existing attachment pipeline to pick up,
bounded by the attachment size limit and a memory ceiling, and only for
media types markdown-it accepts as a link destination.

Also fixes an existing bug where a file embedded in an HTML or email
import as a data URI was stored in the document as base64 rather than
being uploaded as an attachment.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Refactor to individual converters

* refactor

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 20:42:05 -04:00
Tom MoorandGitHub 33c8d51e08 perf: Avoid membership joins in search (#13269)
* perf: Avoid membership joins in search

* feedback
2026-08-02 18:29:16 -04:00
Tom MoorandGitHub 03ec96fd91 Return a compact success payload from MCP mutation tools (#13257)
* fix: Return a compact success payload from MCP mutation tools

Mutation tools serialized the entire resource — and for documents the
full markdown body — back to the client on every write, which the caller
already has. They now acknowledge the write with the identifying fields
needed to reference the resource.

The one exception is update_document with editMode "patch", which still
echoes the resulting content so the caller can verify what was replaced.

For move_document and restore_document the breadcrumb is now resolved
after the transaction commits, so it reflects the new location rather
than the cached pre-move document structure.

* test: Update MCP scope enforcement tests for the new response shape

* test: Assert the success acknowledgement across all mutation tool variants
2026-08-02 15:06:25 -04:00
Tom MoorandGitHub b1b3db3430 Update all MCP tools to Markdown (#13234)
* Update all MCP tools to MD input+output

* feedback
2026-08-02 07:58:15 -04:00
273a146381 fix: Shared with me section disappears when page one holds only deleted docs (#13255)
Memberships pointing at soft-deleted or archived documents were still
returned by userMemberships.list and groupMemberships.list, consuming
slots in the first page the sidebar requests. Inner join the document so
they are excluded from the query entirely.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 07:56:42 -04:00
257c2bfdc0 fix: Whitelist fields in URL unfurl presenter (#13254)
Restores field-level picking in presentURL instead of casting the entire
UnfurlData blob, so transient metadata attached by unfurl plugins or
internal callers is never serialized into API responses.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 07:41:50 -04:00
Tom MoorandGitHub bc3b3b3f97 fix: Log failures when scheduling collection duplication task (#13251) 2026-08-02 11:21:16 +00:00
Tom MoorandGitHub efc68de4a0 fix: error id guards break for non-Error throwables (#13250)
Widen the narrowed instanceof Error checks introduced in the TypeScript 6
upgrade with a shared errToId helper that accepts any object carrying a
string id, restoring the login email-matching recovery path.
2026-08-02 07:19:24 -04:00
9ee3c1c999 fix: Missing revision on restore returns 404 instead of authorization error (#13249)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 07:18:42 -04:00
Tom MoorandGitHub 890f0451a8 feat: Multi-select documents (#13041)
* first pass

* refactor

* refactor

* wip

* Fix BatchableApiMethods docs; remove ApiClient batch test

* Refactor actions

* refactor batch send to share error code handling

* Remove multi-select from read-only
Refactor performBatch to common

* refactor
2026-08-01 20:45:20 -04:00
13b9b2c62d feat: Add support for web page and eml import (#13229)
* feat: Add support for web page and email import

* fix: Type mailparser result explicitly

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Combine HTML and Web Page

* fix: Validate mime type before inlining MIME archive parts

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 18:30:06 -04:00
8b35f7bd17 feat: Import file dialog (#13228)
* feat: Replace import document file picker with a modal

Choosing "Import document" now opens a dialog that lists the supported
file formats with an icon for each, and accepts files either dropped onto
it or chosen with the system file picker.

Also closes the gaps between the formats the dialog advertises and those
the importer actually accepts:

- `.tsv` was offered by the file picker but rejected by the server, it is
  now converted to a table like CSV
- `.csv` and `.htm` are now recognised by extension, so they still import
  when the browser reports an unhelpful mime type
- `.markdown` is now offered by the file picker, it was already supported

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dj1UnjnRX336CQcdzw3ott

* Add intermediate dialog for file import

* tweaks, polish

* Update failure message

* test

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-08-01 17:46:47 -04:00
Tom MoorandGitHub a6b5898283 fix: Silence false positive sequelize class fields warning (#13224)
sequelize-strict-attributes defines per-instance accessors for attributes
omitted from a query's selection, which trips Sequelize's public class field
detection. The removed `Fix` decorator used to suppress this per model; do it
once on the base model instead.
2026-08-01 11:47:37 -04:00
Tom MoorandGitHub e6908c1511 feat: Inline read-only comments (#13209)
* feat: Inline read-only comments

* Improve anchor disambiguation

* fix: Spurious edits from inline comments
2026-08-01 08:08:52 -04:00
Tom MoorandGitHub 6e8b20e35f fix: OIDC forced secure cookie (#13217)
closes #13180
2026-08-01 07:24:31 -04:00
Tom MoorandGitHub 23d20d749d fix: policy serialization (#13211)
* fix: Membership IDs not serialized correctly in policies

* fix: Policy serialization
2026-07-31 21:41:16 -04:00
Tom MoorandGitHub a01b38665e fix: Shared content should not resolve for a suspended workspace (#13213) 2026-07-31 21:41:01 -04:00
Tom MoorandGitHub aae3e4b81a perf: Reduce connections required for findByPk (#13214) 2026-07-31 13:19:40 -04:00
Tom MoorandGitHub 9a50a980f8 Update CSRF handling to set secure host-bound where possible (#13203) 2026-07-30 17:27:11 -04:00
a15e66740a perf: Reduce data loading on revisions.list endpoint (#13202)
* perf: Reduce data loading on revisions.list endpoint

* test: Cover includeContent option on Document.findByPk

Also fixes a JSDoc typo on the includeViews option.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-30 08:34:17 -04:00
yoominhoandGitHub 647352f6a0 perf: O(1) title lookup in markdown import merge (#13117)
collectDocumentsAndAttachments merged a folder/file sharing a title by scanning
the sibling list with out.find(d => d.title === child.title) once per child —
O(n²) over the number of siblings in one directory, which for a flat import can
be large. Index the siblings by title in a Map and look up in O(1). First
occurrence wins, matching find; the merge still mutates the same object.
2026-07-29 23:04:08 -04:00
Tom MoorandGitHub ade792f709 feat: Add ability to duplicate collection (#13197)
* feat: Add ability to duplicate collection

* Add confirmation dialog
2026-07-29 21:28:59 -04:00
Tom MoorandGitHub f228714c7a fix: googletagmanager not included in CSP unless enabled through env (#13195)
* fix: googletagmanager not incuded in CSP unless enabled through ENV

* Remove other points of CSP surgery, hey it proves the value of the refactor
2026-07-29 20:48:37 -04:00
Tom MoorandGitHub 97964071f2 fix: Cannot duplicate document from read-only collection (#13198)
* fix: Cannot duplicate document from read-only collection

* Improve validation
2026-07-29 20:48:32 -04:00
Tom MoorandGitHub 4c78dd8ade fix: Memory leak in cancan cache (#13194) 2026-07-29 18:20:47 -04:00
Tom MoorandGitHub f8ccdf143c fix: urls.unfurl does not correctly treat as internal on FQD (#13189) 2026-07-28 21:54:17 -04:00
Tom MoorandGitHub 71e9f1a5df Remove cache mutation in unfurl (#13183) 2026-07-28 17:59:58 -04:00
Tom MoorandGitHub 31374d4099 perf: Adds a short-lived cache for nested policies (#13172)
* perf: Adds a short-lived cache for recursive policies

* Freeze default object

* Add additional tests

* Refactor to use ALS

* Remove redundant depth
2026-07-28 17:44:47 -04:00
Tom MoorandGitHub 9b03db016c fix: Recalculate memberships in the same transaction when moving doc (#13182)
closes #13181
2026-07-28 17:44:16 -04:00
Tom MoorandGitHub c5f9646337 Icon picker glow-up (#13177)
* Icon panel glow-up

* Move colorPalette to shared/constants
2026-07-28 08:47:09 -04:00
Tom MoorandGitHub f97523f0b0 Add days until expiry to export email (#13175) 2026-07-27 21:43:35 -04:00
Tom MoorandGitHub b0ed00fef4 fix: Cannot view past 25 archived collections (#13171) 2026-07-27 20:41:52 -04:00
Tom MoorandGitHub d0900e7277 fix: relationships.list drafts (#13170) 2026-07-27 19:25:50 -04:00
Tom MoorandGitHub 7b751ab04b perf: Attach output stream before adding zip entries (#13167)
* perf: Attach output stream before adding zip entries

* fix: Handle failure
2026-07-27 19:13:18 -04:00
Tom MoorandGitHub 715694684c chore: Encyrpted.test.ts flaky test (#13169) 2026-07-27 18:50:23 -04:00
Tom MoorandGitHub 8cdd2895a3 chore: Refactor get+post combos to register (#13168) 2026-07-27 18:39:20 -04:00
Tom MoorandGitHub 9ae7517efb fix: Re-check file operation permissions at download (#13148)
* fix: Re-check file operation permissions at download

* feedback

* Address feedback and copy across to other findByPk overrides
2026-07-27 18:32:17 -04:00
Tom MoorandGitHub 5befd94fb8 perf: Fix streaming file outputs passthrough (#13153)
* perf: Fix streaming file outputs passthrough correctly

* test
2026-07-27 18:23:51 -04:00
Tom MoorandGitHub 86335325e8 fix: attachments.redirect should be considered in read scope. (#13155)
closes #13152
2026-07-27 17:43:06 -04:00
17452bda5b Move socket management from client -> server (#13120)
* Move socket management from client -> server

* feedback

* fix: Reconcile collection rooms on visibility change

Handle collections.update transitions between private and team-visible by
joining or rebuilding the collection channel, route collection events through
the members channel so guests are excluded, and use removeData for the
collection ids cache invalidation.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-26 17:47:34 -04:00
Tom MoorandGitHub fc40988891 fix: Lock contention on documents.create (#13149)
* wip

* fix: Lock contention on documents.create

* revert
2026-07-26 17:35:15 -04:00
Tom MoorandGitHub 84c4cbc431 fix: Narrow validation on relationships.list (#13147) 2026-07-26 16:49:24 -04:00
Tom MoorandGitHub 6190684d59 fix: collaboratorIds async/distributed nature should not guard persistence (#13145)
* fix: collaboratorIds async/distributed should not guard persistence

* feedback
2026-07-26 11:41:55 -04:00
Tom MoorandGitHub 6268bc149a fix: Add missing zod schema check for incoming document.text (#13143)
* fix: Add missing zod schema check for incoming document.text

* feedback

* test
2026-07-26 08:25:25 -04:00
Tom MoorandGitHub 22cb3f1baf chore: Tighten rate limits on document mutations (#13142) 2026-07-26 08:18:01 -04:00
Tom MoorandGitHub 9d066c2a92 fix: Avoid user serialization on public share response (#13144)
* fix: Avoid user serialization on public share response

* fix: shares.list does not return shares from deleted users
2026-07-26 08:17:09 -04:00
e1c906a1c2 feat: Fuse powered local content search (#13115)
* wip

* generalize

* refactor

* Extract SearchResultIcon for command bar results

Both search action builders rendered the same document icon inline. Move it
into a shared component alongside the other command bar pieces, forwarding
size so the command bar can continue to size icons via cloneElement.

Also drop the redundant charAt(0).toUpperCase() on the initial, as the Icon
component already normalizes it.

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

* PR feedback
Prevent same doc showing twice in cmd k
Improve result ordering in main app command bar
Refactor to flattenTree

* Upgrade Fuse to 7.5.0, use workers

* fix: Re-register search actions when index is enriched

Include result contexts in the command bar registration key so that
snippets refresh when the same documents are enriched, and only mark a
server search as cached once its results are actually fed to the index.

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-25 13:16:53 -04:00
Tom MoorandGitHub c2fd3ddb5a perf: Removes JSDom usage on main server -> worker (#13128)
* refactor

* fix: Test setup for awaited jobs

* feedback
2026-07-25 12:43:18 -04:00
Tom Moor 5a9fb0024f fix: Immediately stop retrying malformed imports 2026-07-25 12:38:57 -04:00