Skip to content

Conversation

@dhairyajangir
Copy link

@dhairyajangir dhairyajangir commented Oct 19, 2025

Fixes #5901

PR: Enforce NOT NULL and Remove Default Value for mail_attachments.created_at

Overview

This pull request addresses an important data integrity issue in the Nextcloud Mail app: previously, attachments could be created with a created_at timestamp of 0 or NULL due to a default value on the database column and missing assignment in the application logic. This made it difficult to reliably clean up old attachments and could lead to inconsistent data.

What Has Changed

1. Database Migration

  • File: lib/Migration/Version5007Date20251019000000.php
  • Purpose:
    • Alters the mail_attachments table to ensure the created_at column is always set.
    • Sets the created_at column to NOT NULL and removes any default value.
    • This enforces that every new attachment must have an explicit creation timestamp set by the application.

2. How the Migration Works

  • Checks if the mail_attachments table exists.
  • Checks if the created_at column exists.
  • Alters the column to:
    • Require a value (NOT NULL)
    • Remove any default value (default => null)
  • This ensures that the application must always provide a valid timestamp when inserting new attachments.

3. Why This Is Important

  • Data Integrity:
    Prevents the creation of attachments with missing or invalid timestamps.
  • Cleanup Reliability:
    Accurate created_at values are essential for reliably cleaning up old attachments and managing storage.
  • Prevents Future Bugs:
    This change would have prevented the original bug by making it impossible to insert attachments with a default or missing timestamp.

4. How to Test

  1. Run the migration:
    • The migration will update the schema as described.
  2. Add a new attachment:
    • Confirm that the created_at field is set to the current timestamp and is never 0 or NULL.
  3. Try inserting an attachment without a created_at value:
    • The database should reject the insert, enforcing the application logic.

5. Additional Notes

  • This migration is safe to run multiple times; it checks for the existence of the table and column before making changes.
  • No existing data is deleted or modified, but any rows with a created_at of 0 or NULL should be reviewed separately if present.
  • This change is a prerequisite for reliable cleanup jobs and future features that depend on accurate attachment timestamps.

@welcome
Copy link

welcome bot commented Oct 19, 2025

Thanks for opening your first pull request in this repository! ✌️

…eated_at

This migration updates the mail_attachments table to require a non-null created_at timestamp for all attachments and removes any default value. This ensures that every attachment record must have an explicit creation time set by the application, preventing issues with zero or missing timestamps and enabling reliable cleanup of old data.

Signed-off-by: dhairyasquad73 <dhairya.jangir.s73@kalvium.community>
@dhairyajangir dhairyajangir force-pushed the fix/attachment-createdat-timestamp-and-migration branch from b8be40e to 804f18c Compare October 19, 2025 19:24
Copy link
Member

@ChristophWurst ChristophWurst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

@ChristophWurst
Copy link
Member

Thanks a lot for the fix @dhairyajangir. If I understand correctly you are targeting #5901, right?

Out of curiosity, what tools did you use for the task?

@ChristophWurst
Copy link
Member

The commit message says migration: …. Please change it to fix(db): …

https://www.conventionalcommits.org/en/v1.0.0/#summary

@ChristophWurst
Copy link
Member

There are minor linting issues due to the wrong whitespace character used. Run composer run cs:fix to auto-fix them :)

@dhairyajangir
Copy link
Author

Thanks a lot for the fix @dhairyajangir. If I understand correctly you are targeting #5901, right?

Out of curiosity, what tools did you use for the task?

Thanks @ChristophWurst,
And Yes I am targeting #5901
and i used -

  • Visual Studio Code for editing
  • PHP for implementation and Nextcloud app code
  • Nextcloud app framework APIs (migration layer, DI, ITimeFactory)
  • ISchemaWrapper (schema change in migration)

Signed-off-by: dhairyasquad73 <dhairya.jangir.s73@kalvium.community>
@ChristophWurst
Copy link
Member

Linter issues:


   1) lib/Service/Attachment/AttachmentService.php
      ---------- begin diff ----------
--- /home/runner/actions-runner/_work/mail/mail/lib/Service/Attachment/AttachmentService.php
+++ /home/runner/actions-runner/_work/mail/mail/lib/Service/Attachment/AttachmentService.php
@@ -22,12 +22,12 @@
 use OCA\Mail\Exception\UploadException;
 use OCA\Mail\IMAP\MessageMapper;
 use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Utility\ITimeFactory;
 use OCP\Files\File;
 use OCP\Files\Folder;
 use OCP\Files\NotFoundException;
 use OCP\Files\NotPermittedException;
 use Psr\Log\LoggerInterface;
-use OCP\AppFramework\Utility\ITimeFactory;
 
 class AttachmentService implements IAttachmentService {
 	/** @var LocalAttachmentMapper */

      ----------- end diff -----------

Test failure:

There was 1 failure:

1) OCA\Mail\Tests\Unit\Service\Attachment\AttachmentServiceTest::testHandleAttachmentsCloudAttachment
Expectation failed for method name is "insert" when invoked 1 time(s)
Parameter 0 for invocation OCP\AppFramework\Db\QBMapper::insert(OCA\Mail\Db\LocalAttachment Object (...)): OCP\AppFramework\Db\Entity does not match expected value.
Failed asserting that two objects are equal.
--- Expected
+++ Actual
@@ @@
         'userId' => true
         'fileName' => true
         'mimeType' => true
+        'createdAt' => true
     )
     '_fieldTypes' => Array (...)
     'userId' => 'linus'
     'fileName' => 'cat.jpg'
     'mimeType' => 'text/plain'
-    'createdAt' => null
+    'createdAt' => 123456
     'localMessageId' => null
 )

/home/runner/actions-runner/_work/mail/mail/nextcloud/apps/mail/lib/Service/Attachment/AttachmentService.php:111
/home/runner/actions-runner/_work/mail/mail/nextcloud/apps/mail/lib/Service/Attachment/AttachmentService.php:382
/home/runner/actions-runner/_work/mail/mail/nextcloud/apps/mail/lib/Service/Attachment/AttachmentService.php:254
/home/runner/actions-runner/_work/mail/mail/nextcloud/apps/mail/tests/Unit/Service/Attachment/AttachmentServiceTest.php:489

@dhairyajangir
Copy link
Author

Linter issues:


   1) lib/Service/Attachment/AttachmentService.php
      ---------- begin diff ----------
--- /home/runner/actions-runner/_work/mail/mail/lib/Service/Attachment/AttachmentService.php
+++ /home/runner/actions-runner/_work/mail/mail/lib/Service/Attachment/AttachmentService.php
@@ -22,12 +22,12 @@
 use OCA\Mail\Exception\UploadException;
 use OCA\Mail\IMAP\MessageMapper;
 use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Utility\ITimeFactory;
 use OCP\Files\File;
 use OCP\Files\Folder;
 use OCP\Files\NotFoundException;
 use OCP\Files\NotPermittedException;
 use Psr\Log\LoggerInterface;
-use OCP\AppFramework\Utility\ITimeFactory;
 
 class AttachmentService implements IAttachmentService {
 	/** @var LocalAttachmentMapper */

      ----------- end diff -----------

Test failure:

There was 1 failure:

1) OCA\Mail\Tests\Unit\Service\Attachment\AttachmentServiceTest::testHandleAttachmentsCloudAttachment
Expectation failed for method name is "insert" when invoked 1 time(s)
Parameter 0 for invocation OCP\AppFramework\Db\QBMapper::insert(OCA\Mail\Db\LocalAttachment Object (...)): OCP\AppFramework\Db\Entity does not match expected value.
Failed asserting that two objects are equal.
--- Expected
+++ Actual
@@ @@
         'userId' => true
         'fileName' => true
         'mimeType' => true
+        'createdAt' => true
     )
     '_fieldTypes' => Array (...)
     'userId' => 'linus'
     'fileName' => 'cat.jpg'
     'mimeType' => 'text/plain'
-    'createdAt' => null
+    'createdAt' => 123456
     'localMessageId' => null
 )

/home/runner/actions-runner/_work/mail/mail/nextcloud/apps/mail/lib/Service/Attachment/AttachmentService.php:111
/home/runner/actions-runner/_work/mail/mail/nextcloud/apps/mail/lib/Service/Attachment/AttachmentService.php:382
/home/runner/actions-runner/_work/mail/mail/nextcloud/apps/mail/lib/Service/Attachment/AttachmentService.php:254
/home/runner/actions-runner/_work/mail/mail/nextcloud/apps/mail/tests/Unit/Service/Attachment/AttachmentServiceTest.php:489

I'll fix this asap!

@ChristophWurst
Copy link
Member

Take your time

- Inject ITimeFactory into AttachmentService constructor
- Set createdAt using timeFactory.getTime() when creating attachments
- Update unit tests to mock ITimeFactory and expect createdAt value
- Update integration tests to pass ITimeFactory dependency

Fixes nextcloud#5901

Signed-off-by: dhairyasquad73 <dhairya.jangir.s73@kalvium.community>
Copy link
Contributor

@kesselb kesselb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you 🙏

@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please increase the version in appinfo/info.xml to 5.6.0-alpha.4 (otherwise the migration will not run).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dhairyajangir
Copy link
Author

Thank you 🙏

my pleasure

dhairyajangir and others added 4 commits October 22, 2025 02:54
Co-authored-by: Daniel <mail@danielkesselberg.de>
Signed-off-by: dhairya <dhairya.jangir.s73@kalvium.community>
Co-authored-by: Daniel <mail@danielkesselberg.de>
Signed-off-by: dhairya <dhairya.jangir.s73@kalvium.community>
Co-authored-by: Daniel <mail@danielkesselberg.de>
Signed-off-by: dhairya <dhairya.jangir.s73@kalvium.community>
Co-authored-by: Daniel <mail@danielkesselberg.de>
Signed-off-by: dhairya <dhairya.jangir.s73@kalvium.community>
@dhairyajangir
Copy link
Author

Open for more tasks!

dhairyajangir and others added 4 commits October 23, 2025 12:12
Co-authored-by: Daniel <mail@danielkesselberg.de>
Signed-off-by: dhairya <dhairya.jangir.s73@kalvium.community>
line 7 updated `AGPL-3.0-only` set to `AGPL-3.0-or-later`

Co-authored-by: Daniel <mail@danielkesselberg.de>
Signed-off-by: dhairya <dhairya.jangir.s73@kalvium.community>
Version bump to trigger migration Version5007Date20251019000000
which enforces NOT NULL and removes default on mail_attachments.created_at

Signed-off-by: dhairyasquad73 <dhairya.jangir.s73@kalvium.community>
@kesselb kesselb changed the base branch from main to bug/5901/set-created-at-on-insert October 23, 2025 22:41
@kesselb kesselb merged commit a003bbe into nextcloud:bug/5901/set-created-at-on-insert Oct 23, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Local attachments have no created_at value assigned

3 participants