Skip to content

[Bug]: Calendar invitations not sent when email addresses contain capital letters #51989

@peleroux

Description

@peleroux

⚠️ This issue respects the following points: ⚠️

Bug description

Hello,
we are using nextcloud 31.0.2 and Calendar 5.2.0.
When we add or modify an event on a calendar, no invitations are sent.

When an iCalendar object changes, the function calendarObjectChange (defined in apps/dav/lib/CalDAV/Schedule/Plugin.php) is called.
This function get the addresses of the owner by calling the getAddressesForPrincipal function (defined in apps/dav/lib/CalDAV/Schedule/Plugin.php and calling its parent defined in 3rdparty/sabre/dav/lib/CalDAV/Schedule/Plugin.php).
Then it calls the function processICalendarChange (defined in 3rdparty/sabre/dav/lib/CalDAV/Schedule/Plugin.php).

processICalendarChange calls parseEvent (defined in 3rdparty/sabre/vobject/lib/ITip/Broker.php) to get messages to send.
This function does tests like "if (in_array($eventInfo['organizer'], $userHref)) {" to check if the organizer of the event is the one who modified the event.
$userHref comes from the previous call to getAddressesForPrincipal.
In our case:

parseEvent calls parseEventInfo (defined in vobject/lib/ITip/Broker.php). This function gets the organizer address by calling "$organizer = $vevent->ORGANIZER->getNormalizedValue();".
The getNormalizedValue method (defined in vobject/lib/Property/ICalendar/CalAddress.php) is:
public function getNormalizedValue()
{
$input = $this->getValue();
if (!strpos($input, ':')) {
return $input;
}
list($schema, $everythingElse) = explode(':', $input, 2);
$schema = strtolower($schema);
if ('mailto' === $schema) {
$everythingElse = strtolower($everythingElse);
}

    return $schema.':'.$everythingElse;
}

So addresses returned by parseEventInfo are all lowercase.

Addresses returned by getAddressesForPrincipal must be all lowercase too.

I fixed this issue by modifying getAddressesForPrincipal (in apps/dav/lib/CalDAV/Schedule/Plugin.php) this way:
protected function getAddressesForPrincipal($principal) {
$result = parent::getAddressesForPrincipal($principal);

    if ($result === null) {
        $result = [];
    }

    // iterate through items and html decode values
    foreach ($result as $key => $value) {

$result[$key] = urldecode($value);

        $result[$key] = strtolower(urldecode($value));
    }

    return $result;
}

With this modification, the invitation emails are sent as expected but I am not sure if this is the best way to fix this issue.

Then I got another similar problem when accepting the invitation.
When the response arrives, the accept function (defined in apps/dav/lib/Controller/InvitationResponseController.php) is called.
This function calls handleITipMessage (defined in apps/dav/lib/CalDAV/InvitationResponse/InvitationResponseServer.php).
This function calls scheduleLocalDelivery (defined in apps/dav/lib/CalDAV/Schedule/Plugin.php and calling its parent defined in 3rdparty/sabre/dav/lib/CalDAV/Schedule/Plugin.php).
The parent calls getPrincipalByUri (defined in 3rdparty/sabre/dav/lib/DAVACL/Plugin.php).
This function calls findByUri (defined in apps/dav/lib/Connector/Sabre/Principal.php).
This function calls getByEmail (defined in lib/private/User/Manager.php).
This function calls getUsersForUserValueCaseInsensitive (defined in lib/private/AllConfig.php).
This function calls getUsersForUserValue (defined in lib/private/AllConfig.php):
public function getUsersForUserValueCaseInsensitive($appName, $key, $value) {
if ($appName === 'settings' && $key === 'email') {
return $this->getUsersForUserValue($appName, $key, strtolower($value));
}
Here the email is forced to lower case.
This function calls searchUsersByValueString (defined in lib/private/Config/UserConfig.php):
public function getUsersForUserValue($appName, $key, $value) {
/** @var list $result /
$result = iterator_to_array(\OCP\Server::get(IUserConfig::class)->searchUsersByValueString($appName, $key, $value));
return $result;
}
This call is case-sensitive so it does not find the user by its mail address and we get an error.
I forced a case-insensitive lookup by changing getUsersForUserValue thus:
public function getUsersForUserValue($appName, $key, $value) {
/
* @var list $result */

$result = iterator_to_array(\OCP\Server::get(IUserConfig::class)->searchUsersByValueString($appName, $key, $value));

    $result = iterator_to_array(\OCP\Server::get(IUserConfig::class)->searchUsersByValueString($appName, $key, $value, true));
    return $result;
}

With this modification, the responses are treated correctly.

I am not sure my fixes are correct but there is a problem when email address of users are not all lowercase in the database.

Thank you.

Steps to reproduce

1.Your email address must contain capital letter
2.Create an event in calendar
3.No invitation email are sent

Expected behavior

Invitation emails should be sent even if the email address contains capital letter.

Nextcloud Server version

31

Operating system

Debian/Ubuntu

PHP engine version

PHP 8.3

Web server

Apache (supported)

Database engine version

MariaDB

Is this bug present after an update or on a fresh install?

Fresh Nextcloud Server install

Are you using the Nextcloud Server Encryption module?

None

What user-backends are you using?

  • Default user-backend (database)
  • LDAP/ Active Directory
  • SSO - SAML
  • Other

Configuration report

{
    "system": {
        "instanceid": "***REMOVED SENSITIVE VALUE***",
        "passwordsalt": "***REMOVED SENSITIVE VALUE***",
        "secret": "***REMOVED SENSITIVE VALUE***",
        "trusted_domains": [
            "nuage-test.lip6.fr"
        ],
        "datadirectory": "***REMOVED SENSITIVE VALUE***",
        "overwrite.cli.url": "https:\/\/nuage-test.lip6.fr",
        "overwritehost": "nuage-test.lip6.fr",
        "overwriteprotocol": "https",
        "trusted_proxies": "***REMOVED SENSITIVE VALUE***",
        "memcache.local": "\\OC\\Memcache\\APCu",
        "redis": {
            "host": "***REMOVED SENSITIVE VALUE***",
            "port": 6379
        },
        "memcache.locking": "\\OC\\Memcache\\Redis",
        "dbtype": "mysql",
        "version": "31.0.2.1",
        "dbname": "***REMOVED SENSITIVE VALUE***",
        "dbhost": "***REMOVED SENSITIVE VALUE***",
        "dbport": "",
        "dbtableprefix": "oc_",
        "mysql.utf8mb4": true,
        "dbuser": "***REMOVED SENSITIVE VALUE***",
        "dbpassword": "***REMOVED SENSITIVE VALUE***",
        "installed": true,
        "ldapIgnoreNamingRules": false,
        "ldapProviderFactory": "\\OCA\\User_LDAP\\LDAPProviderFactory",
        "mail_smtpmode": "smtp",
        "mail_smtpauthtype": "LOGIN",
        "mail_from_address": "***REMOVED SENSITIVE VALUE***",
        "mail_domain": "***REMOVED SENSITIVE VALUE***",
        "mail_smtphost": "***REMOVED SENSITIVE VALUE***",
        "skeletondirectory": "",
        "default_phone_region": "FR",
        "maintenance": false,
        "maintenance_window_start": 22,
        "integrity.check.disabled": false,
        "auth.bruteforce.protection.enabled": false,
        "updater.release.channel": "stable",
        "apps_paths": [
            {
                "path": "\/var\/www\/html\/apps",
                "url": "\/apps",
                "writable": false
            },
            {
                "path": "\/var\/www\/html\/custom_apps",
                "url": "\/custom_apps",
                "writable": true
            }
        ],
        "mail_smtpport": "25",
        "loglevel": 2,
        "app_install_overwrite": [
            "calendar",
            "tasks",
            "files_downloadactivity",
            "drawio",
            "quota_warning",
            "files_texteditor",
            "gallery"
        ],
        "theme": "",
        "mail_sendmailmode": "smtp"
    }
}

List of activated Apps

Enabled:
  - activity: 4.0.0
  - app_api: 5.0.2
  - bruteforcesettings: 4.0.0
  - calendar: 5.2.0
  - circles: 31.0.0
  - cloud_federation_api: 1.14.0
  - comments: 1.21.0
  - contactsinteraction: 1.12.0
  - dashboard: 7.11.0
  - dav: 1.33.0
  - federatedfilesharing: 1.21.0
  - federation: 1.21.0
  - files: 2.3.1
  - files_downloadlimit: 4.0.0
  - files_pdfviewer: 4.0.0
  - files_reminders: 1.4.0
  - files_sharing: 1.23.1
  - files_trashbin: 1.21.0
  - files_versions: 1.24.0
  - firstrunwizard: 4.0.0
  - logreader: 4.0.0
  - lookup_server_connector: 1.19.0
  - mail: 4.3.4
  - nextcloud_announcements: 3.0.0
  - notifications: 4.0.0
  - oauth2: 1.19.1
  - password_policy: 3.0.0
  - photos: 4.0.0-dev.1
  - privacy: 3.0.0
  - profile: 1.0.0
  - provisioning_api: 1.21.0
  - recommendations: 4.0.0
  - related_resources: 2.0.0
  - serverinfo: 3.0.0
  - settings: 1.14.0
  - sharebymail: 1.21.0
  - support: 3.0.0
  - survey_client: 3.0.0
  - systemtags: 1.21.1
  - text: 5.0.0
  - theming: 2.6.1
  - twofactor_backupcodes: 1.20.0
  - updatenotification: 1.21.0
  - user_ldap: 1.22.0
  - user_status: 1.11.0
  - viewer: 4.0.0
  - weather_status: 1.11.0
  - webhook_listeners: 1.2.0
  - workflowengine: 2.13.0
Disabled:
  - admin_audit: 1.21.0
  - encryption: 2.19.0
  - files_external: 1.23.0
  - suspicious_login: 9.0.1
  - twofactor_nextcloud_notification: 5.0.0
  - twofactor_totp: 13.0.0-dev.0

Nextcloud Signing status

No errors have been found.

Nextcloud Logs

Additional info

No response

Metadata

Metadata

Labels

Type

Projects

Status

📄 To do

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions