DAVx5 Select deprecated

With the DAVx5 Select integration, Android users can set up calendar and contact synchronization via CalDAV/CardDAV directly from the OX App Suite onboarding wizard. The onboarding wizard presents three scenarios: one to install the DAVx5 Select app from the Google Play Store, one to configure it with a one-time setup link that automatically provisions DAV URLs, an app-specific password, and optional UI customization, and a manual fallback that displays the DAV base URL for users who prefer to enter their credentials by hand.

How It Works

The onboarding wizard presents the following scenarios for Android devices:

  1. Install (davx5install): A link to the DAVx5 Select app on the Google Play Store. The user scans this QR code first to install the app.
  2. Setup (davx5setup): A one-time configuration link. Once the app is installed, the user scans this QR code to configure it:
    1. The middleware generates a one-time token (which internally encodes the user identity) and returns a davx5://setup?config=<https_url> link together with an expiresInSeconds field indicating how long the token remains valid. The full HTTPS configuration URL is passed as the config query parameter.
    2. The user opens the link (or scans the QR code) on their Android device within the token's lifetime.
    3. The DAVx5 Select app extracts the HTTPS URL from the config query parameter and fetches the configuration from the middleware.
    4. The middleware redeems the one-time token, resolves the user from the token's session reservation, creates an app-specific password scoped to CalDAV/CardDAV, and returns a JSON response containing DAV URLs, credentials, and optional UI customization.
    5. The DAVx5 Select app is now configured and starts syncing.
  3. Manual (davx5manual): A fallback that displays a DAV URL and the user's login for manual entry into DAVx5 Select. No token is generated and no app-specific password is created; the user types their regular credentials into the app, and DAVx5 performs service discovery from any single entry point. The URL is resolved from com.openexchange.client.onboarding.davx5.base.url, then com.openexchange.client.onboarding.davx5.caldav.url, then com.openexchange.client.onboarding.davx5.carddav.url — the first non-empty value wins. Declared as an alternatives: entry on davx5setup, so clients that can't use the automated flow fall back to this scenario.

After initial setup, the DAVx5 client periodically re-queries the same endpoint with Basic Auth (using the app-specific password) to fetch updated configuration. These re-queries return only customization data (no credentials). The user identity is derived from the authenticated credentials, not the URL.

Deployment

Dependencies

The feature requires the following packages:

  • open-xchange-client-onboarding (DAVx5 onboarding provider and configuration REST endpoint)
  • open-xchange-authentication-application-storage-rdb (app-specific password storage, optional)

The CalDAV and/or CardDAV capabilities must be enabled for the target users, since the onboarding provider checks for the caldav or carddav capability.

The bundle exposes a davx5 capability that is awarded when both the davx5install and davx5setup onboarding scenarios are enabled for a user. Clients can check for this capability to determine whether DAVx5 onboarding is available. The optional davx5manual fallback scenario is orthogonal to this capability — it does not need to be enabled for the capability to be granted.

Note: The open-xchange-authentication-application-storage-rdb package is optional. If app-specific passwords are not available, the initial setup response will still contain DAV URLs and customization but will not include credentials (basicAuth is omitted). The manual scenario does not require app-specific passwords at all.

Configuration

Enabling the Feature

The DAVx5 onboarding scenarios must be enabled and listed in the Android device scenarios. The default configuration already includes davx5install (Play Store link), davx5setup (configuration link), and davx5manual (manual fallback). Verify the following properties in client-onboarding.properties:

com.openexchange.client.onboarding.enabledScenarios=..., davx5install, davx5setup, davx5manual, ...
com.openexchange.client.onboarding.android.phone.scenarios=..., davx5install, davx5setup, davx5manual, ...
com.openexchange.client.onboarding.android.tablet.scenarios=..., davx5install, davx5setup, davx5manual, ...

The scenarios must be defined in client-onboarding-scenarios.yml. The default configuration ships with all three:

# Links to the DAVx5 Select app on Google Play Store
davx5install:
    enabled: true
    type: link
    link:
        url: https://play.google.com/store/apps/details?id=com.davx5.select
        type: playstore
    providers: [app]
    alternatives: []
    icon: "fa-calendar, fa-users"
    displayName_t10e: "DAVx5 Select"
    description_t10e: "Install DAVx5 Select from Google Play Store."

# Generates a one-time configuration link for DAVx5 Select
davx5setup:
    enabled: true
    type: link
    providers: [davx5]
    alternatives: [davx5manual]
    icon: "fa-calendar, fa-users"
    displayName_t10e: "DAVx5 Select"
    description_t10e: "Set up DAVx5 Select to synchronize your Calendar and Address Book data."

# Manual fallback: displays DAV base URL and login for user-entered setup
davx5manual:
    enabled: true
    type: manual
    providers: [davx5]
    alternatives: []
    icon: fa-wrench
    displayName_t10e: "DAVx5 Select (Manual)"
    description_t10e: "To manually set up DAVx5 Select, please use the following information."

The manual scenario requires at least one of com.openexchange.client.onboarding.davx5.base.url, com.openexchange.client.onboarding.davx5.caldav.url, or com.openexchange.client.onboarding.davx5.carddav.url to be configured. They are consulted in that order and the first non-empty value is returned as the single davx5_url field. If all three are empty, requests for davx5manual fail with a missing-property error naming base.url.

Application passwords must be enabled and the calcarddav app type must be configured. See Application-specific Passwords for details:

com.openexchange.authentication.application.enabled=true
com.openexchange.authentication.application.appTypes=..., calcarddav, ...

The calcarddav application type must be defined in app-password-apps.yml:

calcarddav:
    displayName_t10e: Calendar and Addressbook Client (CalDAV/CardDAV)
    restrictedScopes: [dav,read_caldav,write_caldav,read_carddav,write_carddav]
    requiredCapabilities: [caldav,carddav]
    sortOrder: 50

DAV URL Configuration

By default, the DAV URLs are left empty and must be configured to match your deployment:

# DAV base URL.
# Example: https://dav.example.org/dav
com.openexchange.client.onboarding.davx5.base.url=

# CalDAV URL.
# Example: https://dav.example.org/caldav
com.openexchange.client.onboarding.davx5.caldav.url=

# CardDAV URL.
# Example: https://dav.example.org/carddav
com.openexchange.client.onboarding.davx5.carddav.url=

App Password Settings

These properties control how the app-specific password is created during the initial setup:

Property Description Default
com.openexchange.client.onboarding.davx5.appPasswordType App password type to use. Must match an entry in app-password-apps.yml. calcarddav
com.openexchange.client.onboarding.davx5.appPasswordName Display name prefix for the app password in the user's password list. DAVx5 Select

UI Customization

All customization properties are config-cascade aware and can be overridden per context or user for per-customer branding.

Property Description Default
com.openexchange.client.onboarding.davx5.customization.productName Product name shown in DAVx5 Select. OX App Suite
com.openexchange.client.onboarding.davx5.customization.description Product description shown in DAVx5 Select. Sync your calendars and contacts
com.openexchange.client.onboarding.davx5.customization.logoImage Logo image (see Image Requirements below). (empty)
com.openexchange.client.onboarding.davx5.customization.headerImage Header/banner image (see Image Requirements below). (empty)

Image Requirements

Images can be provided as either a data: URI (embedded) or an HTTPS URL (externally hosted).

Data URIs:

  • Format: PNG (data:image/png;base64,...). JPEG is also accepted but PNG is preferred for logos with transparency.
  • Logo image: square, recommended 512 x 512 px.
  • Header image: landscape, recommended 1024 x 256 px.
  • Maximum encoded size: 256 KB per image. Larger data URIs increase the configuration response size and may cause timeouts or memory pressure on low-end Android devices.

HTTPS URLs:

  • Must be publicly reachable from the user's Android device (not an internal-only hostname).
  • The DAVx5 client fetches these URLs directly. See Security Considerations for privacy implications.
  • Prefer serving images with appropriate Cache-Control headers to avoid repeated downloads.

Support Information

Property Description Default
com.openexchange.client.onboarding.davx5.support.linkDestination Support link destination URL. (empty)
com.openexchange.client.onboarding.davx5.support.linkTitle Support link title. (empty)
com.openexchange.client.onboarding.davx5.support.description Support description text. (empty)

Onboarding Settings

Property Description Default
com.openexchange.client.onboarding.davx5.tokenTimeoutSeconds Token timeout in seconds for the one-time configuration link. The user must scan the QR code and open it within this time. 30

Rate Limiting

Property Description Default
com.openexchange.client.onboarding.davx5.rateLimit.maxPerMinute Maximum number of requests per IP per minute for the configuration endpoint. Set to 0 to disable. 10

Note: The rate limit property is evaluated before user identification and is therefore not config-cascade aware. It applies globally and cannot be overridden per context or user.

REST API

Configuration Endpoint

GET /davx5/v1/config/{token}

The token is an opaque one-time string generated by the onboarding flow. It internally identifies the user and context via the session reservation.

Initial Setup (Unauthenticated)

When called without an Authorization header, the endpoint redeems the one-time token, resolves the user identity from the session reservation, creates an app-specific password, and returns the full configuration:

{
  "baseRoot": "https://dav.example.org/dav/",
  "caldavRoot": "https://dav.example.org/caldav/",
  "carddavRoot": "https://dav.example.org/carddav/",
  "basicAuth": {
    "username": "peter@example.org",
    "password": "app-specific-password-here"
  },
  "customization": {
    "productName": "Example Mail",
    "description": "Sync service brought to you by Example Corp",
    "logoImage": "data:image/png;base64,iVBOR...",
    "headerImage": "https://example.com/header.png"
  },
  "supportInfos": {
    "linkDestination": "https://example.com/support",
    "linkTitle": "Contact Support",
    "description": "In case of any problem, please visit our support page."
  }
}

Response headers: Cache-Control: no-store

Authenticated Re-query (Basic Auth)

When called with a Basic Authorization header (using the app-specific password), the endpoint derives the user identity from the credentials and returns only customization and support data (no credentials, no DAV URLs). The token path segment is ignored in this mode — the DAVx5 client simply re-uses the same URL it received during initial setup.

{
  "customization": { ... },
  "supportInfos": { ... }
}

Error Responses

Status Code Description
401 Invalid Basic Auth credentials (re-query mode).
403 Token is invalid, expired, or already used (initial setup).
429 Rate limit exceeded.
500 Internal server error.
503 Authentication service unavailable (re-query mode).

Security Considerations

  • Opaque URLs: The configuration URL contains only an opaque token. No user identifiers, context IDs, or other internal information is leaked in the URL.
  • One-time tokens: The configuration token can only be used once. It is atomically consumed on first use via SessionReservationService. Any subsequent attempt returns 403 Forbidden.
  • Token expiry: Tokens expire after 30 seconds by default (configurable via com.openexchange.client.onboarding.davx5.tokenTimeoutSeconds).
  • Scoped passwords: The app-specific password is limited to dav, read_caldav, write_caldav, read_carddav, write_carddav. It cannot access mail, drive, or admin APIs.
  • Credential-derived identity: Authenticated re-queries derive the user identity entirely from the validated credentials (via AppAuthenticatorService). No path parameters are trusted for user identification.
  • HTTPS enforcement: The davx5://setup?config= URI embeds the full HTTPS URL as a query parameter. The DAVx5 client extracts and fetches this URL, ensuring TLS.
  • Rate limiting: IP-based rate limiting protects against brute-force attempts on the configuration endpoint.
  • External image URLs and privacy: When logoImage or headerImage are configured as HTTPS URLs (instead of data: URIs), the DAVx5 client fetches them directly from the user's device. This reveals the user's IP address, device type, and request timing to the image host. If privacy is a concern, prefer embedded data: URIs or host images on infrastructure you control.