Commit Graph
42 Commits
Author SHA1 Message Date
Lauri Ojansivu fdb683892d Log every filename/content sanitization to Admin Panel / Problems
Whenever a filename or file requires sanitization — on upload, migration, the
existing-file corrector, or viewing/serving — record it to the Security event
stream (action:'sanitized'), the companion to the existing action:'blocked'
upload rejections. Each row carries:

- WHEN: the event timestamp.
- WHO: the original uploader (userId), shown as a new clickable username column
  in the Problems event report.
- FOR WHAT REASON: sanitizationReasons() — URL-encoded name, invisible
  characters, typosquatting (look-alike characters), the specific exploit KIND
  (JavaScript code, XML code, XML loop (billion laughs), server-side PHP/ASP,
  template injection, HTML code), wrong file type (.txt -> .png), filename too
  long, or empty-name-generated.
- THE FILENAME: "from" -> "to".
- WHERE: board > swimlane > list > card, plus the board's organization(s) and
  team(s) (server/lib/fileContext.js).

New: classifyExploitKinds() + sanitizationReasons() (isomorphic), the
server-only fileContext resolver, filenameSanitizeLog helpers, catalog keys
file.sanitize / file.content / file.malware, and the uploader column in the
event report. Wired at all fix points (attachments/avatars onAfterUpload,
moveToStorage, correctFileExtensions, httpStreamOutput). EICAR now uses the
file.malware key. Logging is best-effort and never breaks the upload/view path.

Tests: classifyExploitKinds + sanitizationReasons unit tests (positive +
negative) and logging-wiring source guards. CHANGELOG + design doc updated.
2026-07-20 03:11:07 +03:00
Lauri Ojansivu 81dbecfb87 Safe filename handling: display, upload, existing files, migrations
One unified filename subsystem, used everywhere a name is shown, uploaded,
served, or migrated. Design: docs/Features/Filename/Filename.md.

Display (imports/lib/fileNameDisplay.js, general cleanFileName + global
{{cleanFilename}}/{{downloadFilename}} helpers): URL-decode, normalize to
generally-used characters (NFKC + confusable-homoglyph folding so typosquatting
"payp<Cyrillic-a>l.exe" shows as "paypal.exe", only in a Latin-majority base so
genuine non-Latin names are preserved), remove invisible/control/bidi chars,
strip HTML/JS/XML/template markup. Removed the earlier invisible-char filter
button, warning triangle, inline descriptions, legend and server invisibleOnly
filter.

Upload (attachments + avatars, all backends): reject exploit-looking filenames
and EICAR virus test files; strip invisible chars; correct the extension to the
real detected type (double-click opens the right app); type-based name when
empty; cap length to a portable max (30, Amiga OS FFS) preserving the extension;
sanitize SVG JS / XML-loop content at the staging location before promoting to
final storage and delete the temp file after; enough-disk-space check with
small-RAM streaming and stop-and-remove-partial on any write error.

Existing files: general storage-agnostic detector streams a small header to
WRITABLE_PATH/files/temp, runs `file`, deletes the temp file; admin-only bounded
batch extension corrector; serve-time on-the-fly exploit sanitizer wired into
httpStreamOutput (sniffs the start, rewrites only dangerous markup, streams the
rest unchanged).

Migrations (moveToStorage/copyFile): sanitize content, finalize the name with
the same general function (detected type, corrected extension, folded
homoglyphs, capped length), save it at the destination, and number
same-name/different-content collisions (document.pdf, document-1.pdf, ...).

Tests: rewrote fileNameDisplay.test.cjs; added uploadFileName, diskSpace,
fileTypeCorrection and fileHardeningGuards unit tests (positive + negative);
updated Playwright spec 41 to the clean-name model. CHANGELOG + design doc.
2026-07-20 03:11:07 +03:00
Lauri OjansivuandClaude Opus 4.8 72e10a81b7 Make #6412 filename test negative-testable: extract pure helpers + Node test
The #6412 mocha test imported the helpers from fileStoreStrategy.js, which pulls
in Meteor, so it could only run under `meteor test` (and the local harness loaded
0 server tests here) — meaning it could not be negative-tested locally.

Extract the pure, Meteor-free helpers (truncateFilenameToBytes / sanitizeFilename
/ MAX_FILENAME_BYTES) into models/lib/filenameSanitizer.js; fileStoreStrategy.js
requires them. Add tests/filenameSanitizer.test.cjs (plain Node, `npm run
test:unit:node`) and point the mocha test at the new module. The Node test is
negative-tested: 7 passing on the fix, and the length-cap assertion fails when
the truncation is reverted. Verified `meteor build` still compiles (the helper
is bundled into the server).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 15:46:43 +03:00
Lauri OjansivuandClaude Opus 4.8 5709854ed5 tests: add #6412 filename-truncation unit test and #3897 guest-board regression
- Export truncateFilenameToBytes / sanitizeFilename from fileStoreStrategy and
  add server/lib/tests/filenameTruncation.tests.js (#6412): byte-budget
  truncation preserves the extension, never splits a multibyte codepoint, caps
  the on-disk component under 255 bytes, and still strips path traversal.
- Spec 36: a guest opening a public board renders lists with no
  "isBoardAdmin of null" crash (#3897).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 12:09:19 +03:00
Lauri OjansivuandClaude Opus 4.8 5e26cf0048 Fix ENAMETOOLONG on very long attachment filenames (#6412)
Attachment filenames were sanitized for path traversal but never length-limited,
so a very long name (made worse by multibyte UTF-8 chars like German umlauts,
2 bytes each) produced an on-disk component "<id>-<version>-<name>" exceeding the
filesystem's 255-byte per-path-component limit. Migrating such files from GridFS
to filesystem storage then failed with ENAMETOOLONG (errno -36).

sanitizeFilename now truncates the name to 200 UTF-8 bytes, measured in bytes
(not characters) and never splitting a multibyte codepoint, while preserving the
file extension. 200 bytes leaves headroom for the "<id>-<version>-" prefix so the
full component stays under 255 bytes. Applied centrally in sanitizeFilename so
every path-construction and lookup site stays consistent.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 21:08:26 +03:00
Lauri Ojansivu a86a087915 New features:
- **Admin Panel / Attachments: "Calculate file counts" on every storage backend,
  shown right below the "Read" toggle.** Azure Blob Storage and Google Cloud
  Storage now have a "Calculate file counts" button (new `getAzureStorageStats` /
  `getGcsStorageStats` methods) that reports how many attachments and avatars are
  stored on that backend, matching what Filesystem, MongoDB GridFS and S3 already
  offer. The count is read from the stored file metadata (fast, no cloud API
  calls). The S3 button was also moved up to sit directly under its "Read"
  checkbox, so all backends are consistent. Thanks to Claude.
- **Admin Panel / Attachments: bilingual, self-documenting cloud-storage fields
  (S3, Azure and Google Cloud Storage).** Each cloud-storage setting now guides
  the admin from top to bottom with both English and translated text, so it is
  easy to follow along while clicking through the provider's Cloud Console:
  - the field **label** uses the provider's own console wording in English
    (e.g. *Access key ID*, *Secret access key*, *Storage account key*,
    *Service account key (JSON)*), with the translated label shown below it;
  - a literal **example** of what the value should look like
    (e.g. `eu-west-1`, an example bucket name / endpoint / connection string),
    which is intentionally not translated;
  - a short **description** of the value, in English and then translated;
  - the **Cloud Console menu path** showing exactly where to find or create the
    value (e.g. *AWS Console → IAM → Users → your user → Security credentials →
    Access keys → Create access key*; *Azure Portal → Storage accounts → your
    account → Access keys → key1*; *Google Cloud Console → IAM & Admin →
    Service accounts → … → Keys → Add key → Create new key → JSON*), again in
    English and then translated.
  The provider field names, examples and menu paths are kept in English so they
  match what the Cloud Console actually shows, while the descriptions and menu
  paths are also translatable; section titles, the enable/read/force-path-style
  checkboxes and the Test/Save buttons remain fully translated. Thanks to Claude.
- **Admin Panel / Attachments / Move Attachment: "Repair file locations" button
  and a persistent "last move" message.** The new **Repair file locations** button
  scans all attachments and avatars and finds any whose recorded storage
  (`versions.<v>.storage` / `path` / `meta.gridFsFileId`) no longer matches where
  the binary actually is — left inconsistent by an interrupted or failed move —
  and fixes the database to point at the real location: it detects the binary in
  GridFS (by the `metadata.fileId` stamped on upload, recovering files whose
  GridFS id reference was lost) or on the filesystem (using the storage
  strategy's own thorough path resolution, so the repair agrees with what a real
  download/move would find even when `versions.<v>.path` is stale), then corrects
  `storage`, `path` and `meta.gridFsFileId` accordingly. Cloud-stored files are
  left untouched, and files found nowhere are reported as "Not found". The scan is
  streamed (memory-safe) and shows a per-scope searched / repaired / not-found
  summary. Separately, after a move finishes the page now keeps showing
  the last move operation — source → destination (scope) and the date/time as
  `YYYY-MM-DD HH:MM:SS` — so it is clear what was last done. Thanks to Claude.

 New fixes:

- **Fixed moving attachments to S3 (and other cloud storage) failing and
  crashing the server.** Uploading to S3 failed two ways, each of which crashed
  the whole server because the rejection was unhandled and SyncedCron treats
  those as fatal. The `@tweedegolf/sab-adapter-amazon-s3` adapter uploaded with a
  `PutObjectCommand` whose `Body` was a live stream: (1) with no `ContentLength`
  the AWS SDK fell back to a chunked signed upload that needs a decoded content
  length, which was undefined for a stream of unknown size — `Invalid value
  "undefined" for header "x-amz-decoded-content-length"`; and (2) if the socket
  dropped mid-upload (`socket hang up`), the SDK's body-stream promise rejected
  unhandled. Fixed by uploading the file as a complete in-memory **buffer**
  (`addFileFromBuffer`) instead of a live stream: a buffer has a known length (no
  content-length error) and no socket-bound stream to re-reject. The cloud upload
  promise now never rejects — any failure is captured and exposed via
  `waitUntilStored()`, which `moveToStorage` checks inside a try/catch so a failed
  upload leaves the source file intact and is logged cleanly. (Files are moved one
  at a time, so peak memory is one file.) Thanks to Claude.
- **Fixed `TypeError: Cannot read properties of undefined (reading 'on')` when
  moving attachments between Meteor-Files/GridFS and Filesystem.** If a file's
  source binary was missing at its recorded location (e.g. a file left
  half-moved by an earlier interrupted run — storage says "gridfs" but the
  GridFS id reference is gone, or a filesystem path that no longer exists),
  `getReadStream()`/`getWriteStream()` returned `undefined` and `moveToStorage`
  (and `copyFile`) called `.on()` on it, throwing. Both now detect a missing
  read/write stream, log a clear message (which file, version, from→to storage,
  and why), **skip that file and leave the source intact** so no data is lost,
  and continue with the rest. Use the new "Repair file locations" button to fix
  the underlying inconsistent records. Thanks to Claude.
- **Fixed moving attachments/avatars from CollectionFS to Meteor-Files crashing
  the server, hanging the Admin Panel move at "File 1 / N", and leaving broken
  avatars.** Three problems in Admin Panel / Attachments / Move Attachment:
  - **Server crash on the first file** (`uncaughtException: TypeError: Cannot read
    properties of undefined (reading '_id')` at
    `AttachmentStoreStrategyGridFs.writeStreamFinished`). The current mongodb
    driver's GridFS `GridFSBucketWriteStream` `'finish'` event no longer passes
    the stored file document, so `finishedData._id` threw and killed the process
    (which is also why the move appeared stuck at "File 1 / 4" — the background
    job died mid-file and its persisted status was frozen). The GridFS strategy
    now reads the uploaded file id from the write stream itself (`gridFSFile._id`
    / `id`), the `'finish'` handler is wrapped so it can never crash the process,
    and a startup reconciliation clears a stale "running" move status left by a
    crashed run so the UI un-sticks and a new move can be started.
  - **Broken avatar after migrating avatars.** The bulk move only repointed card
    cover references (`cards.coverId`); a user's `profile.avatarUrl` still pointed
    at the deleted legacy `/cfs/files/avatars/<oldId>` URL, so the avatar rendered
    broken. The move now repoints `profile.avatarUrl` to the migrated avatar
    (`remapReferences` handles avatars), and migrated files stamp
    `meta.migratedFromId` so references can be repaired to the **exact** new file.
    The startup repair in `server/models/users.js` (previously a no-op: it
    string-replaced the URL prefix while keeping the now-deleted id and never
    saved the document) now points each affected user's avatar at their migrated
    Meteor-Files avatar — matched precisely by `meta.migratedFromId`, otherwise
    strictly by `userId` (newest migrated avatar first), so a user can only ever
    be given their own avatar, never another user's.
  - **`ObjectID` deprecation warning** from `models/lib/grid/createObjectId.js`
    (`MongoInternals.NpmModule.ObjectID` → `ObjectId`).

Thanks to Claude and xet7 !
2026-06-06 07:21:59 +03:00
Lauri Ojansivu d30803276d - **Fixed Admin Panel / Attachments / Move Attachment doing nothing / crashing.**
Several issues in the bulk move:
- The GridFS source matcher required `meta.gridFsFileId` to be *absent*, but
  Meteor-Files always sets it, so selecting "MongoDB Meteor-Files" matched zero
  files and "nothing happened". The matcher now recognizes real GridFS files
  (`versions.*.storage === 'gridfs'` or a `meta.gridFsFileId` reference), and a
  "nothing to move" message is shown when a source is empty instead of silently
  doing nothing.
- Moving files crashed the whole server with
  `FilesCollection#findOne() not available in server` — `ReactiveCache.getAttachment`
  used a synchronous `findOne()`; it now uses `findOneAsync()`. The background
  job is also hardened so a single failing file is skipped instead of crashing
  the server via an unhandled rejection.
- The attachment **copy** API now honours the admin API upload limits (it
  previously skipped them).
- **Fixed the "MongoDB Meteor-Files" file-count statistic** in Admin Panel /
  Attachments, which counted *every* attachment metadata document (so files on
  the Filesystem were wrongly reported as being in GridFS). It now counts only
  attachments actually stored in GridFS, consistent with the move tool. Also
  renamed the mislabeled "Mongo-Files" column to "Meteor-Files". Thanks to Claude.
- **Unified attachment/avatar storage migration: move any → any.** Admin Panel /
  Attachments / Move Attachment can now move **Attachments, Avatars, or both**,
  from **any source to any destination** across Filesystem, Meteor-Files GridFS,
  Cloud (S3/Azure/GCS) and legacy CollectionFS GridFS. The default source is
  "All Read-enabled storages" (every backend whose Read flag is enabled and whose
  settings work), so everything can be consolidated into one destination in a
  single run. All metadata is preserved (board / swimlane / list / card / user /
  uploaded date / name / type / size), attachment cover references
  (`cards.coverId`) are remapped when an id changes, and the legacy source is
  deleted only after the new copy is verified. Thanks to Claude.
- **Legacy CollectionFS GridFS is now a first-class storage backend** (read,
  migrate-from, and export-to) for both attachments and avatars, via the new
  `models/lib/collectionFsStore.js` (binary keyed by `copies.<coll>.key` in the
  `cfs_gridfs.<coll>` bucket, metadata in `cfs.<coll>.filerecord`). Thanks to Claude.
- **The storage strategy layer is now collection-aware.** `moveToStorage` and the
  GridFS/Cloud strategies previously hard-coded the `Attachments` collection, so
  moving avatars to GridFS/cloud would have updated the wrong collection. The
  factory now carries its collection (`Attachments` or `Avatars`), so **avatars
  can be stored in Meteor-Files GridFS and cloud**, not only on the filesystem.
  Attachment behavior is unchanged. Thanks to Claude.
- **Read legacy CollectionFS attachments and avatars in place** (without
  migrating). The backward-compatibility layer
  (`models/lib/attachmentBackwardCompatibility.js`) was broken — it looked up the
  GridFS binary by the filerecord `_id` and by filename instead of by
  `ObjectId(copies.<coll>.key)`, so legacy files were never found. It is fixed and
  generalized for attachments and avatars. Legacy attachments now appear in the
  card attachment gallery (new `legacyBoardAttachments` publication) and stream
  from the `cfs_gridfs.attachments` bucket, and legacy avatars
  (`/cfs/files/avatars/<id>` URLs) are served from the `cfs_gridfs.avatars`
  bucket instead of redirecting to a 404.

Thanks to Claude.
2026-06-06 02:06:16 +03:00
Lauri Ojansivu 6f021aa387 Mobile / touch fixes (Fairphone 4 postmarketOS Firefox and Fairphone 4 Ubuntu Touch Morph browser; iPhone 12 Mini was already correct):
- Fixed one-finger drag-to-scroll not working in the All Boards view and the
  Calendar view on Fairphone 4 Firefox and Ubuntu Touch Morph. These browsers
  do not emit the synthetic mouse events the `@wekanteam/dragscroll` library
  relies on, so scrolling only worked in the Swimlanes/Lists views. Added a new
  native touch-scrolling helper `client/lib/dragscrollTouch.js` that scrolls the
  nearest `.dragscroll` container with a one-finger drag (iOS is skipped, since
  native momentum scrolling already works there), and added the `dragscroll`
  class to the All Boards list and the Calendar view.
- Fixed all text, buttons, the All Boards tables and the top bars (header and
  the second bar) rendering about 2x too large on Fairphone 4. `getMobileMode()`
  defaulted to mobile mode only for iPhone, so every other phone fell back to
  desktop mode, whose large desktop sizing looks oversized on a small phone
  screen. The default is now mobile mode for any phone-sized touch device
  (iPhone, Android/Mobile browsers, Ubuntu Touch, or a coarse-pointer touch
  screen with viewport width ≤ 800px); desktop browsers stay in desktop mode and
  the user's own Mobile/Desktop toggle still takes priority.
- Fixed not being able to reorder swimlanes and lists by dragging their drag
  handle on touch devices. The new touch-scroll helper was hijacking touches
  that started on a drag handle; `.handle` / `.ui-sortable-handle` elements are
  now excluded from touch-scrolling so dragging the handle reorders as expected.
- Fixed a card duplicating into two cards when it was dragged by its title-row
  drag handle while its Card Details panel was open. The card sortable in
  `client/components/lists/list.js` was re-initialized on every list re-render
  without first destroying the previous instance, so two `stop` handlers fired
  per drag. It now destroys any existing sortable before re-initializing, the
  same guard already used for swimlanes.

Attachment storage:

- Added configurable attachment storage backends in the admin panel: choose the
  default save storage and store attachments on the local filesystem, GridFS, or
  cloud object storage — S3-compatible (AWS S3, MinIO, Cloudflare R2, Backblaze
  B2, Wasabi, DigitalOcean Spaces), Azure Blob Storage, or Google Cloud Storage
  — via the `@tweedegolf/storage-abstraction` adapters (new
  `models/lib/cloudStorage.js`). Includes a "Test connection" action and
  English translations for the new settings.
- Added a server-side bulk attachment move (new `server/attachmentBulkMove.js`
  and `models/attachmentBulkMoveStatus.js`) that moves all attachments from one
  storage backend to another as a background job whose progress survives the
  admin navigating away from or closing the page.

Thanks to xet7.
2026-05-31 11:12:41 +03:00
Lauri OjansivuandCopilot Autofix powered by AI 13f78f6207 Potential fix for code scanning alert no. 58: Incomplete multi-character sanitization
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-05-30 22:48:37 +03:00
Lauri Ojansivu fc92b342ce Fix GHSA-g6vm-7757-pr88. Moved Attachment Storage options from board to Admin Panel. Changed API to use Expose Meteor user context to Express endpoints.
Thanks to Jan Kahmen of turingpoint GmbH for reporting GHSA-g6vm-7757-pr88 and xet7 for fixes and attachment improvements.

Thanks to nachocodoner about https://forums.meteor.com/t/expose-meteor-user-context-to-express-endpoints/64384.
2026-05-27 20:54:05 +03:00
Lauri Ojansivu f26a2ac9ad Added fallback so attachments and avatars can be at WRITABLE_PATH or WRITABLE_PATH/files.
Thanks to xet7 !
2026-05-16 13:46:56 +03:00
Lauri Ojansivu b42689a54d Fix attachment rename fails for clipboard uploads and keep extension metadata in sync.
Thanks to snowsky, YosserDerbali and xet7 !

Fixes #6203,
related https://github.com/wekan/wekan/pull/6217
2026-03-27 18:14:10 +02:00
Lauri Ojansivu 5c5ed102ca Export Card to Excel. Part 3. Also, fixed uploading attachments.
Thanks to xet7 !

Fixes #5324
2026-03-25 01:37:42 +02:00
Harry Adel 63ce45c538 Split shared models from Meteor 3 server runtime 2026-03-24 01:50:39 +02:00
Harry Adel 7468b30001 Fix build errors: fibers/future, duplicate sanitizeFilename, forEach await
- users.js: Replace fibers/future pattern with async/await using
  insertAsync/updateAsync for template container creation
- fileStoreStrategy.js: Remove duplicate sanitizeFilename declaration
- wekanCreator.js: Convert attachments.forEach to for...of loop
  so await works inside the iteration body
2026-03-22 18:24:07 +02:00
Harry Adel b5782c7b86 Replace underscore with native JS in models
Largest changes in cards.js (~76 calls), boards.js (~38 calls),
and activities.js (~31 calls). Key patterns:

- _.contains -> .includes() with null guards where needed
- _.findWhere/_.where -> findWhere()/where() helpers
- _.pluck -> .map()
- _.union -> [...new Set()]
- _.extend -> Object.assign()
- _.each on objects -> Object.entries().forEach() (argument order swap)
- _.debounce -> debounce() helper
- _.groupBy/_.indexBy -> groupBy()/indexBy() helpers
- _.clone -> spread operator
- _.sortBy -> [...arr].sort()
- Type checks -> native typeof
2026-03-18 22:39:06 +02:00
Harry Adel 71eb01e233 Update ReactiveCache call sites to use async/await for Meteor 3.0
Part 3 of ReactiveCache async migration:
- Add await before all ReactiveCache.getX() calls
- Make functions containing ReactiveCache calls async
- Convert forEach/map/filter loops with async callbacks to for...of
- Update model helpers, Meteor methods, JsonRoutes handlers
- Update collection hooks (.before/.after insert/update/remove)
- Update .allow() callbacks to async

Files updated across models/ and server/ directories:
- Model files: cards, boards, lists, swimlanes, activities, users,
  checklists, checklistItems, customFields, attachments, integrations,
  cardComments, settings files, creators, exporters, and more
- Server files: publications, methods, notifications, routes, migrations
2026-02-01 00:54:38 +02:00
Lauri Ojansivu a419d831a4 Fix Filebleed of Floppybleed.
Thanks to Luke Hebenstreit Twitter lheben_ and xet7 !
2026-01-28 13:20:28 +02:00
Lauri Ojansivu e9a727301d Fix SECURITY ISSUE 1: File Attachments enables stored XSS (High).
Thanks to Siam Thanat Hack (STH) !
2025-11-02 08:36:29 +02:00
Lauri Ojansivu 4283b5b0e3 Disable not working minio and s3 support temporarily.
Thanks to xet7 !
2025-10-16 17:49:39 +03:00
Martin Filser 06e374f0ff Move every Cards.findOne(idOrFirstObjectSelector, options) to the ReactiveCache 2023-07-18 21:25:28 +02:00
Martin Filser 2eadd3eb8b attachment copy changes now the boardId, listId and swimlaneId in the collection data
- fixing admin attachment view, copied card attachments were wrong if copied to another board / list / swimlane
2023-06-28 21:21:09 +02:00
Lauri Ojansivu fb37f48a86 Updated dependencies. 2023-04-12 08:23:22 +03:00
Lauri Ojansivu cd1750f368 Forked minio npm package to @wekanteam/minio to update package dependencies. S3/MinIO support In Progress.
Thanks to xet7 !

Related #142
2023-01-16 15:11:31 +02:00
Lauri Ojansivu 391607ec79 Store files to S3. Part 4. In Progress.
Thanks to xet7 !
2022-12-27 21:42:06 +02:00
Lauri Ojansivu 028633b00a Fix some S3 typos. 2022-12-26 05:01:15 +02:00
Lauri Ojansivu 21e2eabd60 Store files to S3. In Progress.
Thanks to xet7 !

Related #142
2022-12-21 23:48:47 +02:00
Martin Filser f6d7377977 Remove duplicate IDs issue 2022-12-19 21:14:08 +01:00
Martin Filser 1516615934 Copy attachment copies now all versions
- for now only the version "original" exists, but as other method already
  consider that other version's can exist
2022-08-18 17:31:41 +02:00
Martin Filser 26e1c1dc4a Attachment file rename is now possible
- Relates to: #2099
2022-05-20 12:38:46 +02:00
Martin Filser 1fc3ed407a Merge remote-tracking branch 'origin/upgrade-meteor' into upgrade-meteor 2022-05-03 17:50:30 +02:00
Martin Filser 000e27a4a1 Board copy moves the attachments to the "copied from board storage" 2022-04-30 21:05:04 +02:00
Martin Filser fbb0ed5ec1 Board copy work now again
- there was an error at attachment copy
- fixes: https://github.com/wekan/wekan/issues/4485#issue-1211353265
2022-04-30 21:04:37 +02:00
Martin Filser 58d760a615 FileStoreStrategy, moveToStorage, wrong variable in error handling 2022-04-30 21:04:21 +02:00
Martin Filser efc19ea88c FileStoreStrategyFactory, added logic to determine the right file storage strategy to use 2022-04-23 09:58:59 +02:00
Martin Filser a064e03fc7 Store file on filesystem renew's the storage path 2022-04-20 20:50:41 +02:00
Martin Filser 9d587e76ab Remove filesCollection from FileStoreStrategy classes 2022-04-20 20:50:41 +02:00
Martin Filser cfb88baa7f removed createInterceptDownload file and use existing code for http download 2022-04-20 20:50:41 +02:00
Martin Filser 72b8672e62 Move storage names for filesystem and gridfs to constants 2022-04-20 20:50:41 +02:00
Martin Filser 99c37bd521 removed createOnAfterRemove file and use existing code for remove file from GridFS 2022-04-20 20:50:41 +02:00
Martin Filser 9ef45a75af removed createOnAfterUpload file and use existing code for initial file move to GridFS 2022-04-20 20:50:41 +02:00
Martin Filser 883beba9ed Split AttachmentStoreStrategy classes to new FileStoreStrategy classes 2022-04-20 20:50:41 +02:00