Conversation
e01d756 to
234e641
Compare
961bbd3 to
fc4e6c8
Compare
8d19aa3 to
db410bf
Compare
db410bf to
06324ac
Compare
06324ac to
3991cc8
Compare
Signed-off-by: SebastianKrupinski <[email protected]>
3991cc8 to
8c5effd
Compare
| * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors | ||
| * SPDX-FileCopyrightText: 2014-2016 owncloud, Inc. | ||
| * SPDX-License-Identifier: AGPL-3.0-only | ||
| * SPDX-License-Identifier: AGPL-3.0-or-later |
There was a problem hiding this comment.
Revert. I don't think we can do this retroactively
There was a problem hiding this comment.
Or do you mean it should be "AGPL-3.0-only"
There was a problem hiding this comment.
To change the license of a file we need the permissions from all contributors, hence it might be easier to just stay with AGPL-3.0-only.
That might be Christoph, Joas, Richard, Anna, me, Andy, Hamza according to the commit history. I cannot guarantee the corrects of that information.
- https://github.com/nextcloud/mail/commits/main/lib/Command/CreateAccount.php
- https://github.com/nextcloud/mail/commits/4531545c6102a06fee7ea9a31f65375a866c257c/lib/command/createaccount.php?browsing_rename_history=true&new_path=lib/Command/CreateAccount.php&original_branch=main
- https://github.com/owncloud-archive/mail/commits/master/lib/command/createaccount.php
I'm okay with changing the license ;)
There was a problem hiding this comment.
Ah! I see what you mean. Okay, I can change is back if its a big deal but it seems that all the contributors are NC employees, so idk
There was a problem hiding this comment.
I changed it back to avoid issues
There was a problem hiding this comment.
Pull request overview
Adds initial JMAP support by introducing protocol-aware client creation, new console commands, CI integration for a JMAP-capable test server, and the necessary persistence changes.
Changes:
- Add protocol routing via
ProtocolFactoryplus a newJmapClientFactory. - Introduce new/updated console commands for creating and testing IMAP/JMAP accounts, with aliases for backwards compatibility.
- Add DB migrations + entity fields for JMAP-related identifiers and account protocol/path, plus integration/unit tests and CI updates.
Reviewed changes
Copilot reviewed 25 out of 27 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Unit/Command/CreateJmapAccountTest.php | Unit tests for the new JMAP account creation command. |
| tests/Unit/Command/CreateImapAccountTest.php | Updates unit tests to reflect renamed IMAP account creation command + alias. |
| tests/Integration/Protocol/ProtocolFactoryJmapTest.php | Integration test for establishing a JMAP client connection via ProtocolFactory. |
| tests/Integration/Protocol/ProtocolFactoryImapTest.php | Integration test for establishing an IMAP client connection via ProtocolFactory. |
| tests/Integration/Framework/JmapTestAccount.php | Test fixture to create/persist a JMAP test account for integration tests. |
| tests/Integration/Db/MailAccountTest.php | Extends DB/API serialization tests for new protocol and path fields. |
| package.json | Bumps app package version. |
| package-lock.json | Bumps lockfile version metadata to match package version. |
| lib/Protocol/ProtocolFactory.php | Adds protocol-gated IMAP/JMAP client creation and connector resolution scaffolding. |
| lib/Migration/Version5800Date20260401000001.php | Adds protocol and path columns to mail_accounts. |
| lib/Migration/Version5800Date20260401000002.php | Adds JMAP-related columns (rpid, rid, state) to mail_mailboxes. |
| lib/Migration/Version5800Date20260401000003.php | Adds rid column to mail_messages. |
| lib/JMAP/JmapClientFactory.php | New factory to build authenticated JMAP clients from account configuration. |
| lib/Db/Message.php | Adds rid field accessors/storage to message entity. |
| lib/Db/Mailbox.php | Adds rpid/rid/state fields accessors/storage to mailbox entity. |
| lib/Db/MailAccount.php | Adds protocol + path fields/constants and includes them in JSON output. |
| lib/Contracts/ITransmissionConnector.php | Introduces protocol-agnostic transmission connector interface. |
| lib/Contracts/IMessageConnector.php | Introduces protocol-agnostic message connector interface. |
| lib/Contracts/IMailboxConnector.php | Introduces protocol-agnostic mailbox connector interface. |
| lib/Command/TestAccount.php | Adds unified IMAP/JMAP connection test command (aliasing the old diagnose name). |
| lib/Command/DiagnoseAccount.php | Removes old IMAP-only diagnose command implementation. |
| lib/Command/CreateJmapAccount.php | Adds console command to create JMAP accounts. |
| lib/Command/CreateImapAccount.php | Renames IMAP create command and adds an alias for the previous command name. |
| composer.lock | Adds the JMAP client dependency (and transitive deps) to the lockfile. |
| composer.json | Adds VCS repository + requires the JMAP client package. |
| appinfo/info.xml | Registers new/renamed commands and bumps app version. |
| .github/workflows/test.yml | Updates integration test services to include a JMAP-capable mail server and setup steps. |
| */ | ||
| private function resolveConnector(Account $account, string $interface): mixed { | ||
| $protocol = $account->getMailAccount()->getProtocol(); | ||
| $class = self::CONNECTOR_MAP[$protocol][$interface] ?? null; |
There was a problem hiding this comment.
Does that work with the map commented out? 🤔
There was a problem hiding this comment.
Yes it works with the map commented out,
Part 2 has the actual references.
| $schema = $schemaClosure(); | ||
| $mailboxesTable = $schema->getTable('mail_mailboxes'); | ||
| if (!$mailboxesTable->hasColumn('rpid')) { | ||
| $mailboxesTable->addColumn('rpid', Types::STRING, [ |
There was a problem hiding this comment.
I'm a fan of self-speaking variable names, and hence I would prefer a name that is easy to match to the specification.
rpid = remote_parent_id
r = remote_id
Looking at the sample at https://jmap.io/spec/rfc8621/#section-2.6, state is outside the list and should be the same for all mailboxes, or does that state depends on the requested mailboxes?
There was a problem hiding this comment.
Okay, I can change the field names.
As for the state, yes jmap has a unified state for all changes. You can sync all messages from all mailboxes with a single delta request or per mailbox BUT we handle sync on a per mailbox basis that means I need to know the last sync state for that mailbox, hence the per mailbox state.
There was a problem hiding this comment.
Changed the field names
| /** | ||
| * @psalm-api | ||
| */ | ||
| #[AddColumn(table: 'mail_accounts', name: 'protocol', type: ColumnType::STRING)] |
There was a problem hiding this comment.
Please also list path so the list is complete
|
Please correct the license in your composer.json: https://github.com/SebastianKrupinski/jmap-client-php/blob/30dce48d854abc7d416f3784bc796b379775bdd3/composer.json#L7 |
|
jmap-client currently requires guzzlehttp as dependency. Issue 1: While guzzle is already a dependency for server via 3rdparty, guzzle will be installed another time here leadiing to another copy of guzzle. Issue 2: Not using the nextcloud http client means our protections like ssrf, dns pinning, configuration of proxies through config.php are not applied. Solution:
|
| 'debug' => $this->getDebug(), | ||
| 'classificationEnabled' => $this->getClassificationEnabled(), | ||
| 'imipCreate' => $this->getImipCreate(), | ||
| 'protocol' => $this->getProtocol() ?? self::PROTOCOL_IMAP, |
There was a problem hiding this comment.
| 'protocol' => $this->getProtocol() ?? self::PROTOCOL_IMAP, | |
| 'protocol' => $this->getProtocol(), |
(default already in declaration, proctol cannot be null)
Signed-off-by: SebastianKrupinski <[email protected]>
I agree this is a good upgrade for the client, but this will have to wait, due to the time available for the implementation of this I cannot redesign the jmap-client at the moment. |

Summary