Skip to main content

Microsoft 365 integration - Releases

← App details

Nextcloud 35

Microsoft 365 integration 1.0.1
Release Details
UpdatedOct. 16, 2026, 1:56 p.m.
Changelog

Added

  • Admin setting Sync interval (60–3600 s, default 300) for the background job; Nextcloud's cron must run at least that often (documented in the admin guide).
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhRuMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYxMDE1MTk1ODQ0WhcNMzcwMTIwMTk1ODQ0WjAbMRkwFwYD
VQQDDBBpbnRlZ3JhdGlvbl9tMzY1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEApWBRPJ2upm8vSw86u9SfuJ8ts5Eof79s71iRrxWV/YQ4M1oc5ZIwQy+P
38QNAayun4ZnVBJZghI7oEeu9BEfTdPDfbdXg7VyZr7qfnP9VDGiN50Cqx/FEmK4
NzejcyJLVOHJdoESx+owQbnsmMV89L9RdzP2u/qbZm4hMpzbj+/JDaM1BTW0iucY
vId2Aw6bSD6wUn1mA+y6NVCqS8PQcO54BQNAzvy4t1liN1EtntKxIvnh6RvtAN+6
Fh8YyNAMxEFn0pIxGveQLNvcjux5lpJqqypAvoHCiI9uP3j/F/qR9HeVTLbDhZod
xf0c6Vj4foU8J6hWnsp21s3tpFAjFEJlVHwbmo42Dl+78O4tQCbvoX7FfZmy4iAK
P7mmPqTEMHJEVhROyVd9lt2q977azqDEzGqFORDCeMHQW6k2HQ7ab9A5uon316fP
zfzs1ObibScihSBFQ4p2LV3SiPhH/xZfo9pm/1lsbAn7+J6VG4+S050X91tUmP5t
Ao1CFp5/qBoKb2wNPUMUkqnvG705CtWAAa22RR+T/C3drgRQYJ5O1aZ8cVP0KWdH
aTXXYdMbGEPXoFPikNSwhxuJ3EDTUG0nRVD5Df7dlYnCNwHIShaQgP7AyiqDPoSw
9P4NU/uJqcst2X79hufywPQqMNHfy9Tv0pvGs0Lv8kFT8mhjjTsCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAjeoLWgiZcu4FzAv6hRhx4TQnGpmFC3cz+NscaJZP4iUr
xrhHBJ7HgSjYmqLf+Y+A5NVPKAUf7XJ6LovJQzeN2t8gmcTuhnPVQLrSAdX9lbUi
uX3zR/aoZH5PEQCwzOpHICnKVFsS0t6f31mGP3OCOlNh5SolMKSfGefpBCtkqHDP
sIVl8DrC5QL5RjbpJJb1Fk6FyUdXKeOZ8R6doXTfekxzFqkeECENw48k0TQwp4wP
XHczcaum+uy1/nOCrUWV0mE/g3CJIyWWrkHoNvKOD9q7Apn174qkknGEXEAmZaQK
Dlyaa48a0ekpnxDWJTzSx4PfjCtiayqEcy0d/0bskg==
-----END CERTIFICATE-----
Signatureinv2Ikv2Cm00nt4BqLa8KwDqMxMjXoZJ8oiLh/a/3K5ZMwTQjjjbUqew+9LDRb+Rf/+Nkk++8vkQ0jNZ1CRM6IIfG3TCyQ9XGZ1xPJd+Lw69YMDyQxqW3Ybprc+g2xgub0Yl4bp4Heu26eJLFNKRqgZx0BTh4tFeN02iC8rmpWif4zSXQuQdGWeaFI+6dhs4Cuh8kj+ab2nrE1V51gLTFFv29R0P1FKLmgeRKt7WXqXyQ8hDW3yw3S1sh0T5G+qLDhS3IcHRqOOU7eXKBb20WgNRMWOv3je+UUgRe+73fiJ0kZUCW4ZYNT2l7lrjijATAuCyK1BEQSVU/UUMJVg4oZscW/kafdPTX9VscSo7WrGe1C9H6oYQYzFUkzEGVP4fSMCvEXhiVSCLtKSly2TxUIh6c4/au7mYu3G9Yq6LsJVz+NStdcbp7oOddjJFjcOiu3RakNNOpV2kHlWSwooTykJXyfKZNWzgGqmIyHKfJe0DuYmko+ntc5Sc00FooBkJO4zx1ngfVWIUl5rsEhqungtecNX2E8T0NlgL/am5WAEkkoDAk8cMiAuL31BFAW+GyMH2CMxBfVdPulyDYXHoG0sJZO/McaVbbXc36cAO7pYSy8KoMHHHREXWSPQNlbKzIezU10edhaGdFOWsGKxldJ8Xe1LvVghKWKbgDLKe4n8=
Signature digestsha512
Dependencies
Required Nextcloud versions >=32.0.0,<36.0.0
Minimum Integer bits32
PHP>=8.1.0
Microsoft 365 integration 1.0.0
Release Details
UpdatedOct. 16, 2026, 1:10 p.m.
Changelog

Documentation

  • README split into a short overview plus docs/admin.md (Entra ID registration step by step, permissions and why, account types, secret rotation, occ commands, troubleshooting by AADSTS code, scaling, uninstall), docs/user.md and docs/privacy.md (data flow, storage, retention, logging and deletion for data protection officers). Wrong menu paths fixed: the settings live under Connected accounts.
  • SECURITY.md (private reporting, scope, design notes) and CONTRIBUTING.md (setup, checks, conventions, fixture rules, release steps).
  • Known limitations extended (own mailbox only, 1 MB cap, failed objects retried on change, write-cap rounds).
  • Changelog switched to the Keep a Changelog format.

Lifecycle and data hygiene

  • Deleting a Nextcloud user now removes their tokens, pairs, correlations, queued jobs and notifications (UserDeletedEvent). Before, the background job kept recreating an orphaned calendar for the deleted principal every 5 minutes.
  • Disconnecting removes the queued sync job and, with purge, the correlations as well (they were left behind). Without purge the pairs are only disabled and resume on reconnect.
  • Connecting a different Microsoft account resets the pairs: remote ids and delta links of the old mailbox are meaningless for the new one.
  • Changing client id or tenant in the admin settings invalidates every user's tokens and notifies them to connect again; changing only the secret keeps them valid.
  • A bad secret, unknown client id or wrong tenant (invalid_client, unauthorized_client) is now reported as an admin configuration error (config_error) instead of asking every user to reconnect.
  • If a user deletes (or trashes) the local calendar or address book of a pair, the pair is disabled with local_missing instead of silently recreating the collection and replaying old cursors against it, which would have deleted everything on the Microsoft side. Re-enabling the pair starts fresh and re-pairs existing objects by UID.
  • Users flagged for reconnect are skipped by the background job without touching Graph.
  • app:disable / app:remove run an uninstall step that removes the background jobs and open notifications; tables, tokens and pairs stay so that re-enabling resumes.
  • New occ integration_m365:reset --pair ID | --user UID | --all: forget cursors and correlations of one pair (next run re-pairs by UID), purge one user, or wipe everything before app:remove. Local calendars and address books are never touched.
  • last_error now holds machine-readable codes (reauth_required, config_error, local_missing, items_failed:N) so the UI can translate them.

App Store listing

  • App icon (neutral two-way sync glyph, img/app.svg / img/app-dark.svg), used for the settings sections and the notification instead of the generic core icon.
  • info.xml: screenshots (placeholders in screenshots/, to be replaced by real captures), user and admin documentation links, repository, requirements (cron, Entra ID registration) in the description.

Admin and user experience

  • Admin settings: "Test connection" verifies client ID, secret and tenant against Entra ID without a user (client-credentials grant; multi-tenant settings can only be verified by a user login), copy button for the redirect URI, optional client-secret expiry date with a warning 30 days ahead, link to the admin guide, and a notice when a registration change asked users to reconnect.
  • Entra ID errors during login and in the connection test are mapped to actionable messages (redirect URI mismatch, missing consent, wrong client ID or tenant, wrong or expired secret, account type not allowed, Conditional Access, revoked login) with the AADSTS number kept for reference; the error no longer stays in the address bar.
  • Personal settings: disconnect asks whether to keep the collection settings or forget the synchronisation state; "Sync now" reports failures (reconnect needed, admin configuration, server error) instead of pretending the job was queued; error codes in the tables are shown as translated text; dates follow the Nextcloud locale.
  • Fixed: buttons used the nextcloud/vue 8 type prop and therefore all rendered as secondary buttons; variant is the nextcloud/vue 9 prop.
  • Fixed: the redirect after connecting pointed at a non-existent anchor.
  • Accessibility: checkboxes, name fields and conflict selects carry labels naming the collection, tables are labelled by their heading, column headers have a scope, decorative icons are hidden from screen readers.

Translations

  • German translation (de informal, de_DE formal) for every string in the settings pages, notifications and server-side messages; maintained in tools/l10n-de.py until the app is on Transifex (.tx/config and .l10nignore are in place). A unit test checks that every source string is translated and that placeholders survive.
  • Server-side messages that reach the user (login errors, "not configured", "not connected", the default "Contacts" folder name) now go through the Nextcloud translation system.

Tests

  • Unit tests for OAuthService (PKCE/state, refresh, invalid_grant → one notification, invalid_client → admin error, redirect, registration test), GraphClient (paging, host allow-list, delta expiry, throttling and back-off, retry rules per method, 401 refresh, error mapping, $batch sub-request retries), LifecycleService, UserDeletedListener, Notifier, EntraErrors, UserSyncService (locking, reauth skip, missing local collection, --full), background jobs and both controllers; SyncEngine now also covers both-deleted, delete-versus-change in both directions and policies, identical concurrent edits, the write cap, per-item failures, deferred photos and To Do lists. 133 tests.
  • time() and sleep() go through ITimeFactory / an overridable pause so that tests do not wait.

Compatibility and CI

  • Test matrix now covers what info.xml claims: PHP 8.1 with OCP stable32, 8.2 with stable33, 8.3 and 8.4 with stable35 (lint, psalm, PHPUnit on every entry).
  • New install job: the packaged app is installed into a real Nextcloud 32 (PHP 8.1) and 35 (PHP 8.4) server, enabled (migrations), its commands, settings pages, background job and uninstall step are exercised and the server log must stay clean.
  • Conformance fixtures are diffed against the vdirsyncer-graph repository on every run.
  • ESLint (@nextcloud/eslint-config) and stylelint (@nextcloud/stylelint-config) for the frontend; sources reformatted accordingly. .nvmrc pins Node 22.
  • Release workflow: runs the full test workflow first, checks tag, info.xml, package.json and CHANGELOG against each other, installs the signed build into a server and runs integrity:check-app, fails loudly when signing secrets are missing and warns when the App Store token is absent. Server checkout pinned to a tag.
  • Code made acceptable to the older psalm that resolves on PHP 8.1; psr/http-message declared as the dev dependency it is.

Robustness

  • Fixed: a throttled or failed photo fetch inside a $batch was taken as "contact has no photo"; the content hash changed and the local contact was rewritten without its picture. Photos that could not be fetched now defer the contact to the next run; throttled sub-requests are retried with their Retry-After.
  • Graph client: retries 429/503/504 for every request and 500/502 plus network errors for idempotent ones, honours Retry-After in seconds and HTTP-date form, backs off exponentially with full jitter, and gives up immediately when Graph asks for more than 20 s (the next run tries again). Connect timeout of 10 s.
  • The pair lock is taken with one conditional UPDATE: cron and "Sync now" can no longer both pass a read-then-write check. --full resets the cursors under the lock.
  • Background job is now time sensitive (instances with a maintenance window only synced during that window), spends at most 240 s per run and visits users least recently synced first, so nobody starves when a run is cut short. One failing user no longer aborts the others.
  • A pair skipped because another run holds its lock no longer makes the "Sync now" job re-queue itself every tick.
  • Deferred (documented limitation): a run cut short by the write cap re-lists the whole remote collection next time; initial imports of very large collections therefore cost more Graph pages than strictly necessary.

Security

  • nextLink/deltaLink (stored and replayed) and every other absolute URL are only followed on https://graph.microsoft.com; anything else is refused before a bearer token is attached.
  • Authorization code, token responses, token request parameters and raw upload bodies carry #[\SensitiveParameter] so they never appear in logged stack traces.
  • Collection updates validate the lengths of remote id and names (HTTP 400 instead of a database error) and report Graph/token failures of the read-only probe as 502/400 instead of 500.
  • Calendars and address books are only used when they belong to the user's principal and are not in the trash bin.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhRuMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYxMDE1MTk1ODQ0WhcNMzcwMTIwMTk1ODQ0WjAbMRkwFwYD
VQQDDBBpbnRlZ3JhdGlvbl9tMzY1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEApWBRPJ2upm8vSw86u9SfuJ8ts5Eof79s71iRrxWV/YQ4M1oc5ZIwQy+P
38QNAayun4ZnVBJZghI7oEeu9BEfTdPDfbdXg7VyZr7qfnP9VDGiN50Cqx/FEmK4
NzejcyJLVOHJdoESx+owQbnsmMV89L9RdzP2u/qbZm4hMpzbj+/JDaM1BTW0iucY
vId2Aw6bSD6wUn1mA+y6NVCqS8PQcO54BQNAzvy4t1liN1EtntKxIvnh6RvtAN+6
Fh8YyNAMxEFn0pIxGveQLNvcjux5lpJqqypAvoHCiI9uP3j/F/qR9HeVTLbDhZod
xf0c6Vj4foU8J6hWnsp21s3tpFAjFEJlVHwbmo42Dl+78O4tQCbvoX7FfZmy4iAK
P7mmPqTEMHJEVhROyVd9lt2q977azqDEzGqFORDCeMHQW6k2HQ7ab9A5uon316fP
zfzs1ObibScihSBFQ4p2LV3SiPhH/xZfo9pm/1lsbAn7+J6VG4+S050X91tUmP5t
Ao1CFp5/qBoKb2wNPUMUkqnvG705CtWAAa22RR+T/C3drgRQYJ5O1aZ8cVP0KWdH
aTXXYdMbGEPXoFPikNSwhxuJ3EDTUG0nRVD5Df7dlYnCNwHIShaQgP7AyiqDPoSw
9P4NU/uJqcst2X79hufywPQqMNHfy9Tv0pvGs0Lv8kFT8mhjjTsCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAjeoLWgiZcu4FzAv6hRhx4TQnGpmFC3cz+NscaJZP4iUr
xrhHBJ7HgSjYmqLf+Y+A5NVPKAUf7XJ6LovJQzeN2t8gmcTuhnPVQLrSAdX9lbUi
uX3zR/aoZH5PEQCwzOpHICnKVFsS0t6f31mGP3OCOlNh5SolMKSfGefpBCtkqHDP
sIVl8DrC5QL5RjbpJJb1Fk6FyUdXKeOZ8R6doXTfekxzFqkeECENw48k0TQwp4wP
XHczcaum+uy1/nOCrUWV0mE/g3CJIyWWrkHoNvKOD9q7Apn174qkknGEXEAmZaQK
Dlyaa48a0ekpnxDWJTzSx4PfjCtiayqEcy0d/0bskg==
-----END CERTIFICATE-----
SignaturenkGATOR6zcwDPXIvxgSfpdybK+oT2n3+F0/jxi4368Z42KOn0MUz/hStMW3pdKQBxDW66OuSI9ehV16vNjnHZtd1+243aW1dyPpl/f5xGQq6aMBWjEtWD+uzInX38vQMebW2KOlExA8oPeW62God33LgI/f/mcej5PFUq8ieZuKC8QtuX/KpQ0fVDML9I7IFD3J28E95r87+SNPpbx4IOOdE38/YRmhM5BgEWMYG2gMDWUUpgQK46NgdE2GCq9zW3C4DzaMnclflgozETWR/sKERZePp4TnEDcacZ/Kz82lgtvr6f1FnEOQNxnXLJwInp/IS+z+paexuNVOYmkKX2ZKFFUx0wyFgIOyu4xIUHLT2IELlE7iyUuOnH+tTbwEfw7axdLJpAWvWF439pr2vUQec9XJyOfvfj1fnJm2O04VOJuSMezGdSNb96a7G8CWefW93SYfAaacV58d4HGO0u2WYXMdryXkStK5M+kmaRhrq+IDyFhm5t5DKKtAuN+thtTeimqrWV4qryoPyF1mWNc1lYGfLPhdP3x9MhbQFomIwgjs6xwEY/FALZNGKTkBRRXK5WhtkkDLN4S4UHyQTsofJwUfpAHJLlznco52nQyp/mwcULWaOF9D8gDOryMI2RQ4DhZhw5WRcGKZ4K1dOnhaPbvjvteGyfHALbWuVdok=
Signature digestsha512
Dependencies
Required Nextcloud versions >=32.0.0,<36.0.0
Minimum Integer bits32
PHP>=8.1.0
Microsoft 365 integration 0.2.2
Release Details
UpdatedOct. 16, 2026, 8:48 a.m.
Changelog
  • Fixed: the reconnect notification linked to a non-existent settings section (blank page); it now opens Connected accounts.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhRuMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYxMDE1MTk1ODQ0WhcNMzcwMTIwMTk1ODQ0WjAbMRkwFwYD
VQQDDBBpbnRlZ3JhdGlvbl9tMzY1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEApWBRPJ2upm8vSw86u9SfuJ8ts5Eof79s71iRrxWV/YQ4M1oc5ZIwQy+P
38QNAayun4ZnVBJZghI7oEeu9BEfTdPDfbdXg7VyZr7qfnP9VDGiN50Cqx/FEmK4
NzejcyJLVOHJdoESx+owQbnsmMV89L9RdzP2u/qbZm4hMpzbj+/JDaM1BTW0iucY
vId2Aw6bSD6wUn1mA+y6NVCqS8PQcO54BQNAzvy4t1liN1EtntKxIvnh6RvtAN+6
Fh8YyNAMxEFn0pIxGveQLNvcjux5lpJqqypAvoHCiI9uP3j/F/qR9HeVTLbDhZod
xf0c6Vj4foU8J6hWnsp21s3tpFAjFEJlVHwbmo42Dl+78O4tQCbvoX7FfZmy4iAK
P7mmPqTEMHJEVhROyVd9lt2q977azqDEzGqFORDCeMHQW6k2HQ7ab9A5uon316fP
zfzs1ObibScihSBFQ4p2LV3SiPhH/xZfo9pm/1lsbAn7+J6VG4+S050X91tUmP5t
Ao1CFp5/qBoKb2wNPUMUkqnvG705CtWAAa22RR+T/C3drgRQYJ5O1aZ8cVP0KWdH
aTXXYdMbGEPXoFPikNSwhxuJ3EDTUG0nRVD5Df7dlYnCNwHIShaQgP7AyiqDPoSw
9P4NU/uJqcst2X79hufywPQqMNHfy9Tv0pvGs0Lv8kFT8mhjjTsCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAjeoLWgiZcu4FzAv6hRhx4TQnGpmFC3cz+NscaJZP4iUr
xrhHBJ7HgSjYmqLf+Y+A5NVPKAUf7XJ6LovJQzeN2t8gmcTuhnPVQLrSAdX9lbUi
uX3zR/aoZH5PEQCwzOpHICnKVFsS0t6f31mGP3OCOlNh5SolMKSfGefpBCtkqHDP
sIVl8DrC5QL5RjbpJJb1Fk6FyUdXKeOZ8R6doXTfekxzFqkeECENw48k0TQwp4wP
XHczcaum+uy1/nOCrUWV0mE/g3CJIyWWrkHoNvKOD9q7Apn174qkknGEXEAmZaQK
Dlyaa48a0ekpnxDWJTzSx4PfjCtiayqEcy0d/0bskg==
-----END CERTIFICATE-----
SignatureZKwv0BMmPcHzxa0jZ39sRv7Gohm0iuJUHogNehq3dnWl9PxQJl64qIQHh3zCIl8hlGZuK5ERvbLFNs/DLGg8aqpbotVGO17lAzy136m4nAxYuscv2MKijcE8pBiaJSuPa0TwEIrR32JvHQwXMNMpk/qA2hc8JqIuB7gyNmp0nB+8Ltuq41v9TkntDeslFVJLuI/1/I+IZ/0TQqdyZEuV3Vlq/gt8kNgjvhw0p/vdONHPoq3uXSSnqIKxJMv6/KoYZvSvD3NLLYuJLhHUGpewP9x8jDvWeZoiOFEZvyRCqUMqtpUb4VPvba2zizF1gVID4RZ4G0jXbMrlpzyymCpac63oYJzmXmSWvaSoQl8qLAPfYaHYL4jJHBiHPr2fFNXNAOXkYxrHqEjYJwIQXy37vBlPIC+DYpcpMsZFRn7BW/qaPw9FNxJlaRtTRjZto2fhhz7onM8uzyA3tFNjVxL9yPHnqeWVQETk8E9zZuAI49+fJ4+35uVqb2v2n+2HRpHExswEu5tNCBeqQJRtuD1KIixhQqa4gRmYryRhEd/vS2WBjXJr6Gv2T2OK0prynolY0y9LH+WjAFoK811qy5idZCeZHZfFHam3qrEOZaru+dxSAdkCQFU/w5zJWdgCybm6dBaSp0CM1a5/FBNK/BvsnsChE+FhJAQ0HkLxM04dkbA=
Signature digestsha512
Dependencies
Required Nextcloud versions >=32.0.0,<36.0.0
Minimum Integer bits32
PHP>=8.1.0
Microsoft 365 integration 0.2.1
Release Details
UpdatedOct. 16, 2026, 7:43 a.m.
Changelog
  • When Microsoft rejects the refresh token (password change, revoked sessions, consent withdrawn) the user now gets a Nextcloud notification linking to the personal settings; it is cleared on reconnect. The Microsoft error (e.g. AADSTS50173) is written to the log.
  • README: setup guide for any tenant (Entra ID app registration, scopes, consent).
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhRuMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYxMDE1MTk1ODQ0WhcNMzcwMTIwMTk1ODQ0WjAbMRkwFwYD
VQQDDBBpbnRlZ3JhdGlvbl9tMzY1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEApWBRPJ2upm8vSw86u9SfuJ8ts5Eof79s71iRrxWV/YQ4M1oc5ZIwQy+P
38QNAayun4ZnVBJZghI7oEeu9BEfTdPDfbdXg7VyZr7qfnP9VDGiN50Cqx/FEmK4
NzejcyJLVOHJdoESx+owQbnsmMV89L9RdzP2u/qbZm4hMpzbj+/JDaM1BTW0iucY
vId2Aw6bSD6wUn1mA+y6NVCqS8PQcO54BQNAzvy4t1liN1EtntKxIvnh6RvtAN+6
Fh8YyNAMxEFn0pIxGveQLNvcjux5lpJqqypAvoHCiI9uP3j/F/qR9HeVTLbDhZod
xf0c6Vj4foU8J6hWnsp21s3tpFAjFEJlVHwbmo42Dl+78O4tQCbvoX7FfZmy4iAK
P7mmPqTEMHJEVhROyVd9lt2q977azqDEzGqFORDCeMHQW6k2HQ7ab9A5uon316fP
zfzs1ObibScihSBFQ4p2LV3SiPhH/xZfo9pm/1lsbAn7+J6VG4+S050X91tUmP5t
Ao1CFp5/qBoKb2wNPUMUkqnvG705CtWAAa22RR+T/C3drgRQYJ5O1aZ8cVP0KWdH
aTXXYdMbGEPXoFPikNSwhxuJ3EDTUG0nRVD5Df7dlYnCNwHIShaQgP7AyiqDPoSw
9P4NU/uJqcst2X79hufywPQqMNHfy9Tv0pvGs0Lv8kFT8mhjjTsCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAjeoLWgiZcu4FzAv6hRhx4TQnGpmFC3cz+NscaJZP4iUr
xrhHBJ7HgSjYmqLf+Y+A5NVPKAUf7XJ6LovJQzeN2t8gmcTuhnPVQLrSAdX9lbUi
uX3zR/aoZH5PEQCwzOpHICnKVFsS0t6f31mGP3OCOlNh5SolMKSfGefpBCtkqHDP
sIVl8DrC5QL5RjbpJJb1Fk6FyUdXKeOZ8R6doXTfekxzFqkeECENw48k0TQwp4wP
XHczcaum+uy1/nOCrUWV0mE/g3CJIyWWrkHoNvKOD9q7Apn174qkknGEXEAmZaQK
Dlyaa48a0ekpnxDWJTzSx4PfjCtiayqEcy0d/0bskg==
-----END CERTIFICATE-----
SignatureLznrfOO+tCgKsPCmgkRIDbziD6G/tORiyX5Nsc+UMVBDxz0aJ8IPQp/fYDQzKgvIqLMtmez9Qhzkf1JXUgsZ4w8vLJCv3QWggSnn7jVHXfiLwGH1MFlry91PK+PitVe8EcCjO76wSvYDajq4DgkIogkdMIEgbULhDHRA+/3QQO0b1sfd2HUJGVG3Vz58DV5bspvzG4enxNMgz142vNFQNmFDe3zxKHQtrmNagkWMYFg2n5r1nKW55IZD2RnwLmRqfmnWHRV7loYpl8BlZITCiV5p5H7teK/1h06rDxMwnWTamsPk5x7mSO9sfUTJyctivRZZYNqonw8S63EDSWlJlmXZ1GL8+hArDkoMXL13164GkCn1jggbSm8hQJTLMu34oz1T47Iuhh+mfRunw9ex8hCqLr6cnQzI9Da3Bt9DtAjf+s0euilY1YwQaWKVSrNICgnCZ0NQIfwZv1D3qEegs12T0axy6c2htTnm+k2kC1UA/5MBoXWF2loBACmZlqSnGfPlLhM4xnmNqEw7Wqk0kgnlV2Sq41TJAEO2DE3AOKqAQAeNbHBN4em06rft5xaveP6F9+qsowzm0uWBTl9AZ4voma4fmPghCbO9qFAqWfQiC0L2oGdNIoiOjF3vO2RH4DwhCYG5Jm2Jj45EPFfjSHYs1eDb7gRZPAKMM86f724=
Signature digestsha512
Dependencies
Required Nextcloud versions >=32.0.0,<36.0.0
Minimum Integer bits32
PHP>=8.1.0
Microsoft 365 integration 0.2.0
Release Details
UpdatedOct. 16, 2026, 7:36 a.m.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhRuMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYxMDE1MTk1ODQ0WhcNMzcwMTIwMTk1ODQ0WjAbMRkwFwYD
VQQDDBBpbnRlZ3JhdGlvbl9tMzY1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEApWBRPJ2upm8vSw86u9SfuJ8ts5Eof79s71iRrxWV/YQ4M1oc5ZIwQy+P
38QNAayun4ZnVBJZghI7oEeu9BEfTdPDfbdXg7VyZr7qfnP9VDGiN50Cqx/FEmK4
NzejcyJLVOHJdoESx+owQbnsmMV89L9RdzP2u/qbZm4hMpzbj+/JDaM1BTW0iucY
vId2Aw6bSD6wUn1mA+y6NVCqS8PQcO54BQNAzvy4t1liN1EtntKxIvnh6RvtAN+6
Fh8YyNAMxEFn0pIxGveQLNvcjux5lpJqqypAvoHCiI9uP3j/F/qR9HeVTLbDhZod
xf0c6Vj4foU8J6hWnsp21s3tpFAjFEJlVHwbmo42Dl+78O4tQCbvoX7FfZmy4iAK
P7mmPqTEMHJEVhROyVd9lt2q977azqDEzGqFORDCeMHQW6k2HQ7ab9A5uon316fP
zfzs1ObibScihSBFQ4p2LV3SiPhH/xZfo9pm/1lsbAn7+J6VG4+S050X91tUmP5t
Ao1CFp5/qBoKb2wNPUMUkqnvG705CtWAAa22RR+T/C3drgRQYJ5O1aZ8cVP0KWdH
aTXXYdMbGEPXoFPikNSwhxuJ3EDTUG0nRVD5Df7dlYnCNwHIShaQgP7AyiqDPoSw
9P4NU/uJqcst2X79hufywPQqMNHfy9Tv0pvGs0Lv8kFT8mhjjTsCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAjeoLWgiZcu4FzAv6hRhx4TQnGpmFC3cz+NscaJZP4iUr
xrhHBJ7HgSjYmqLf+Y+A5NVPKAUf7XJ6LovJQzeN2t8gmcTuhnPVQLrSAdX9lbUi
uX3zR/aoZH5PEQCwzOpHICnKVFsS0t6f31mGP3OCOlNh5SolMKSfGefpBCtkqHDP
sIVl8DrC5QL5RjbpJJb1Fk6FyUdXKeOZ8R6doXTfekxzFqkeECENw48k0TQwp4wP
XHczcaum+uy1/nOCrUWV0mE/g3CJIyWWrkHoNvKOD9q7Apn174qkknGEXEAmZaQK
Dlyaa48a0ekpnxDWJTzSx4PfjCtiayqEcy0d/0bskg==
-----END CERTIFICATE-----
SignatureQWxuiMN2+CUAW40ir1J/1BCwWvWxYyzwR8uFrtCr82a4ate8vrpf9D3RFrVe/EM3QaS40eE0mtEGJmfiCw5+G1TGm8hP/lHay+Ze21saaEswpZnR6NGxJutZfiWZYfNBPZQXArx5HNdfJLMFCGDCRmfswCXHS2AVDJnqct/zuz1X7QLaEbA4mEYMu7AY5LzMF2kh5YD702v/g+ra+jswvqcPbLXa0ClhMqYH4e8Jh0XQVN5cRwTUygVBXoLQGA/3+Vj0MSK5hmJ11GOPV8P6eiol8bFQSuoFWnAe93rHkPAS0wjRtlzggYUGA9038BoM/XYhIlv965lTjo91n/msA4SI77HSlEVMF3+yLQWCTRSisGxBlAuNJzOuG7rEjY2wDiyd977PAl3Ja913rWzFSAzRSKCS1mqxLT5Vb+6lv72gNJA5hQMkhhtxAq/oyoxqWhvKvJkOhK0+aejZi+J8yehoOoFf3mIRxUufwXyZAfaLDYr+2pvYygnP1qQn5WyjVKczY7mt6mfscKpHOzYpAAzI/AfcQcI7aedS3BRSfLHchHb4mx6H8FnvoB4V/taN5m+cH2jt4HuYwKqpCWRnehAvn4iOS/URHH8c5E9pLUvvN9kMLxDDQ2PlVpIWAFnKPDC+YtMcRzfdScErTt5PXwrd6J7E+UxBUKJ1IpWrTZo=
Signature digestsha512
Dependencies
Required Nextcloud versions >=32.0.0,<36.0.0
Minimum Integer bits32
PHP>=8.1.0

Nextcloud 34

Microsoft 365 integration 1.0.1
Release Details
UpdatedOct. 16, 2026, 1:56 p.m.
Changelog

Added

  • Admin setting Sync interval (60–3600 s, default 300) for the background job; Nextcloud's cron must run at least that often (documented in the admin guide).
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhRuMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYxMDE1MTk1ODQ0WhcNMzcwMTIwMTk1ODQ0WjAbMRkwFwYD
VQQDDBBpbnRlZ3JhdGlvbl9tMzY1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEApWBRPJ2upm8vSw86u9SfuJ8ts5Eof79s71iRrxWV/YQ4M1oc5ZIwQy+P
38QNAayun4ZnVBJZghI7oEeu9BEfTdPDfbdXg7VyZr7qfnP9VDGiN50Cqx/FEmK4
NzejcyJLVOHJdoESx+owQbnsmMV89L9RdzP2u/qbZm4hMpzbj+/JDaM1BTW0iucY
vId2Aw6bSD6wUn1mA+y6NVCqS8PQcO54BQNAzvy4t1liN1EtntKxIvnh6RvtAN+6
Fh8YyNAMxEFn0pIxGveQLNvcjux5lpJqqypAvoHCiI9uP3j/F/qR9HeVTLbDhZod
xf0c6Vj4foU8J6hWnsp21s3tpFAjFEJlVHwbmo42Dl+78O4tQCbvoX7FfZmy4iAK
P7mmPqTEMHJEVhROyVd9lt2q977azqDEzGqFORDCeMHQW6k2HQ7ab9A5uon316fP
zfzs1ObibScihSBFQ4p2LV3SiPhH/xZfo9pm/1lsbAn7+J6VG4+S050X91tUmP5t
Ao1CFp5/qBoKb2wNPUMUkqnvG705CtWAAa22RR+T/C3drgRQYJ5O1aZ8cVP0KWdH
aTXXYdMbGEPXoFPikNSwhxuJ3EDTUG0nRVD5Df7dlYnCNwHIShaQgP7AyiqDPoSw
9P4NU/uJqcst2X79hufywPQqMNHfy9Tv0pvGs0Lv8kFT8mhjjTsCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAjeoLWgiZcu4FzAv6hRhx4TQnGpmFC3cz+NscaJZP4iUr
xrhHBJ7HgSjYmqLf+Y+A5NVPKAUf7XJ6LovJQzeN2t8gmcTuhnPVQLrSAdX9lbUi
uX3zR/aoZH5PEQCwzOpHICnKVFsS0t6f31mGP3OCOlNh5SolMKSfGefpBCtkqHDP
sIVl8DrC5QL5RjbpJJb1Fk6FyUdXKeOZ8R6doXTfekxzFqkeECENw48k0TQwp4wP
XHczcaum+uy1/nOCrUWV0mE/g3CJIyWWrkHoNvKOD9q7Apn174qkknGEXEAmZaQK
Dlyaa48a0ekpnxDWJTzSx4PfjCtiayqEcy0d/0bskg==
-----END CERTIFICATE-----
Signatureinv2Ikv2Cm00nt4BqLa8KwDqMxMjXoZJ8oiLh/a/3K5ZMwTQjjjbUqew+9LDRb+Rf/+Nkk++8vkQ0jNZ1CRM6IIfG3TCyQ9XGZ1xPJd+Lw69YMDyQxqW3Ybprc+g2xgub0Yl4bp4Heu26eJLFNKRqgZx0BTh4tFeN02iC8rmpWif4zSXQuQdGWeaFI+6dhs4Cuh8kj+ab2nrE1V51gLTFFv29R0P1FKLmgeRKt7WXqXyQ8hDW3yw3S1sh0T5G+qLDhS3IcHRqOOU7eXKBb20WgNRMWOv3je+UUgRe+73fiJ0kZUCW4ZYNT2l7lrjijATAuCyK1BEQSVU/UUMJVg4oZscW/kafdPTX9VscSo7WrGe1C9H6oYQYzFUkzEGVP4fSMCvEXhiVSCLtKSly2TxUIh6c4/au7mYu3G9Yq6LsJVz+NStdcbp7oOddjJFjcOiu3RakNNOpV2kHlWSwooTykJXyfKZNWzgGqmIyHKfJe0DuYmko+ntc5Sc00FooBkJO4zx1ngfVWIUl5rsEhqungtecNX2E8T0NlgL/am5WAEkkoDAk8cMiAuL31BFAW+GyMH2CMxBfVdPulyDYXHoG0sJZO/McaVbbXc36cAO7pYSy8KoMHHHREXWSPQNlbKzIezU10edhaGdFOWsGKxldJ8Xe1LvVghKWKbgDLKe4n8=
Signature digestsha512
Dependencies
Required Nextcloud versions >=32.0.0,<36.0.0
Minimum Integer bits32
PHP>=8.1.0
Microsoft 365 integration 1.0.0
Release Details
UpdatedOct. 16, 2026, 1:10 p.m.
Changelog

Documentation

  • README split into a short overview plus docs/admin.md (Entra ID registration step by step, permissions and why, account types, secret rotation, occ commands, troubleshooting by AADSTS code, scaling, uninstall), docs/user.md and docs/privacy.md (data flow, storage, retention, logging and deletion for data protection officers). Wrong menu paths fixed: the settings live under Connected accounts.
  • SECURITY.md (private reporting, scope, design notes) and CONTRIBUTING.md (setup, checks, conventions, fixture rules, release steps).
  • Known limitations extended (own mailbox only, 1 MB cap, failed objects retried on change, write-cap rounds).
  • Changelog switched to the Keep a Changelog format.

Lifecycle and data hygiene

  • Deleting a Nextcloud user now removes their tokens, pairs, correlations, queued jobs and notifications (UserDeletedEvent). Before, the background job kept recreating an orphaned calendar for the deleted principal every 5 minutes.
  • Disconnecting removes the queued sync job and, with purge, the correlations as well (they were left behind). Without purge the pairs are only disabled and resume on reconnect.
  • Connecting a different Microsoft account resets the pairs: remote ids and delta links of the old mailbox are meaningless for the new one.
  • Changing client id or tenant in the admin settings invalidates every user's tokens and notifies them to connect again; changing only the secret keeps them valid.
  • A bad secret, unknown client id or wrong tenant (invalid_client, unauthorized_client) is now reported as an admin configuration error (config_error) instead of asking every user to reconnect.
  • If a user deletes (or trashes) the local calendar or address book of a pair, the pair is disabled with local_missing instead of silently recreating the collection and replaying old cursors against it, which would have deleted everything on the Microsoft side. Re-enabling the pair starts fresh and re-pairs existing objects by UID.
  • Users flagged for reconnect are skipped by the background job without touching Graph.
  • app:disable / app:remove run an uninstall step that removes the background jobs and open notifications; tables, tokens and pairs stay so that re-enabling resumes.
  • New occ integration_m365:reset --pair ID | --user UID | --all: forget cursors and correlations of one pair (next run re-pairs by UID), purge one user, or wipe everything before app:remove. Local calendars and address books are never touched.
  • last_error now holds machine-readable codes (reauth_required, config_error, local_missing, items_failed:N) so the UI can translate them.

App Store listing

  • App icon (neutral two-way sync glyph, img/app.svg / img/app-dark.svg), used for the settings sections and the notification instead of the generic core icon.
  • info.xml: screenshots (placeholders in screenshots/, to be replaced by real captures), user and admin documentation links, repository, requirements (cron, Entra ID registration) in the description.

Admin and user experience

  • Admin settings: "Test connection" verifies client ID, secret and tenant against Entra ID without a user (client-credentials grant; multi-tenant settings can only be verified by a user login), copy button for the redirect URI, optional client-secret expiry date with a warning 30 days ahead, link to the admin guide, and a notice when a registration change asked users to reconnect.
  • Entra ID errors during login and in the connection test are mapped to actionable messages (redirect URI mismatch, missing consent, wrong client ID or tenant, wrong or expired secret, account type not allowed, Conditional Access, revoked login) with the AADSTS number kept for reference; the error no longer stays in the address bar.
  • Personal settings: disconnect asks whether to keep the collection settings or forget the synchronisation state; "Sync now" reports failures (reconnect needed, admin configuration, server error) instead of pretending the job was queued; error codes in the tables are shown as translated text; dates follow the Nextcloud locale.
  • Fixed: buttons used the nextcloud/vue 8 type prop and therefore all rendered as secondary buttons; variant is the nextcloud/vue 9 prop.
  • Fixed: the redirect after connecting pointed at a non-existent anchor.
  • Accessibility: checkboxes, name fields and conflict selects carry labels naming the collection, tables are labelled by their heading, column headers have a scope, decorative icons are hidden from screen readers.

Translations

  • German translation (de informal, de_DE formal) for every string in the settings pages, notifications and server-side messages; maintained in tools/l10n-de.py until the app is on Transifex (.tx/config and .l10nignore are in place). A unit test checks that every source string is translated and that placeholders survive.
  • Server-side messages that reach the user (login errors, "not configured", "not connected", the default "Contacts" folder name) now go through the Nextcloud translation system.

Tests

  • Unit tests for OAuthService (PKCE/state, refresh, invalid_grant → one notification, invalid_client → admin error, redirect, registration test), GraphClient (paging, host allow-list, delta expiry, throttling and back-off, retry rules per method, 401 refresh, error mapping, $batch sub-request retries), LifecycleService, UserDeletedListener, Notifier, EntraErrors, UserSyncService (locking, reauth skip, missing local collection, --full), background jobs and both controllers; SyncEngine now also covers both-deleted, delete-versus-change in both directions and policies, identical concurrent edits, the write cap, per-item failures, deferred photos and To Do lists. 133 tests.
  • time() and sleep() go through ITimeFactory / an overridable pause so that tests do not wait.

Compatibility and CI

  • Test matrix now covers what info.xml claims: PHP 8.1 with OCP stable32, 8.2 with stable33, 8.3 and 8.4 with stable35 (lint, psalm, PHPUnit on every entry).
  • New install job: the packaged app is installed into a real Nextcloud 32 (PHP 8.1) and 35 (PHP 8.4) server, enabled (migrations), its commands, settings pages, background job and uninstall step are exercised and the server log must stay clean.
  • Conformance fixtures are diffed against the vdirsyncer-graph repository on every run.
  • ESLint (@nextcloud/eslint-config) and stylelint (@nextcloud/stylelint-config) for the frontend; sources reformatted accordingly. .nvmrc pins Node 22.
  • Release workflow: runs the full test workflow first, checks tag, info.xml, package.json and CHANGELOG against each other, installs the signed build into a server and runs integrity:check-app, fails loudly when signing secrets are missing and warns when the App Store token is absent. Server checkout pinned to a tag.
  • Code made acceptable to the older psalm that resolves on PHP 8.1; psr/http-message declared as the dev dependency it is.

Robustness

  • Fixed: a throttled or failed photo fetch inside a $batch was taken as "contact has no photo"; the content hash changed and the local contact was rewritten without its picture. Photos that could not be fetched now defer the contact to the next run; throttled sub-requests are retried with their Retry-After.
  • Graph client: retries 429/503/504 for every request and 500/502 plus network errors for idempotent ones, honours Retry-After in seconds and HTTP-date form, backs off exponentially with full jitter, and gives up immediately when Graph asks for more than 20 s (the next run tries again). Connect timeout of 10 s.
  • The pair lock is taken with one conditional UPDATE: cron and "Sync now" can no longer both pass a read-then-write check. --full resets the cursors under the lock.
  • Background job is now time sensitive (instances with a maintenance window only synced during that window), spends at most 240 s per run and visits users least recently synced first, so nobody starves when a run is cut short. One failing user no longer aborts the others.
  • A pair skipped because another run holds its lock no longer makes the "Sync now" job re-queue itself every tick.
  • Deferred (documented limitation): a run cut short by the write cap re-lists the whole remote collection next time; initial imports of very large collections therefore cost more Graph pages than strictly necessary.

Security

  • nextLink/deltaLink (stored and replayed) and every other absolute URL are only followed on https://graph.microsoft.com; anything else is refused before a bearer token is attached.
  • Authorization code, token responses, token request parameters and raw upload bodies carry #[\SensitiveParameter] so they never appear in logged stack traces.
  • Collection updates validate the lengths of remote id and names (HTTP 400 instead of a database error) and report Graph/token failures of the read-only probe as 502/400 instead of 500.
  • Calendars and address books are only used when they belong to the user's principal and are not in the trash bin.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhRuMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYxMDE1MTk1ODQ0WhcNMzcwMTIwMTk1ODQ0WjAbMRkwFwYD
VQQDDBBpbnRlZ3JhdGlvbl9tMzY1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEApWBRPJ2upm8vSw86u9SfuJ8ts5Eof79s71iRrxWV/YQ4M1oc5ZIwQy+P
38QNAayun4ZnVBJZghI7oEeu9BEfTdPDfbdXg7VyZr7qfnP9VDGiN50Cqx/FEmK4
NzejcyJLVOHJdoESx+owQbnsmMV89L9RdzP2u/qbZm4hMpzbj+/JDaM1BTW0iucY
vId2Aw6bSD6wUn1mA+y6NVCqS8PQcO54BQNAzvy4t1liN1EtntKxIvnh6RvtAN+6
Fh8YyNAMxEFn0pIxGveQLNvcjux5lpJqqypAvoHCiI9uP3j/F/qR9HeVTLbDhZod
xf0c6Vj4foU8J6hWnsp21s3tpFAjFEJlVHwbmo42Dl+78O4tQCbvoX7FfZmy4iAK
P7mmPqTEMHJEVhROyVd9lt2q977azqDEzGqFORDCeMHQW6k2HQ7ab9A5uon316fP
zfzs1ObibScihSBFQ4p2LV3SiPhH/xZfo9pm/1lsbAn7+J6VG4+S050X91tUmP5t
Ao1CFp5/qBoKb2wNPUMUkqnvG705CtWAAa22RR+T/C3drgRQYJ5O1aZ8cVP0KWdH
aTXXYdMbGEPXoFPikNSwhxuJ3EDTUG0nRVD5Df7dlYnCNwHIShaQgP7AyiqDPoSw
9P4NU/uJqcst2X79hufywPQqMNHfy9Tv0pvGs0Lv8kFT8mhjjTsCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAjeoLWgiZcu4FzAv6hRhx4TQnGpmFC3cz+NscaJZP4iUr
xrhHBJ7HgSjYmqLf+Y+A5NVPKAUf7XJ6LovJQzeN2t8gmcTuhnPVQLrSAdX9lbUi
uX3zR/aoZH5PEQCwzOpHICnKVFsS0t6f31mGP3OCOlNh5SolMKSfGefpBCtkqHDP
sIVl8DrC5QL5RjbpJJb1Fk6FyUdXKeOZ8R6doXTfekxzFqkeECENw48k0TQwp4wP
XHczcaum+uy1/nOCrUWV0mE/g3CJIyWWrkHoNvKOD9q7Apn174qkknGEXEAmZaQK
Dlyaa48a0ekpnxDWJTzSx4PfjCtiayqEcy0d/0bskg==
-----END CERTIFICATE-----
SignaturenkGATOR6zcwDPXIvxgSfpdybK+oT2n3+F0/jxi4368Z42KOn0MUz/hStMW3pdKQBxDW66OuSI9ehV16vNjnHZtd1+243aW1dyPpl/f5xGQq6aMBWjEtWD+uzInX38vQMebW2KOlExA8oPeW62God33LgI/f/mcej5PFUq8ieZuKC8QtuX/KpQ0fVDML9I7IFD3J28E95r87+SNPpbx4IOOdE38/YRmhM5BgEWMYG2gMDWUUpgQK46NgdE2GCq9zW3C4DzaMnclflgozETWR/sKERZePp4TnEDcacZ/Kz82lgtvr6f1FnEOQNxnXLJwInp/IS+z+paexuNVOYmkKX2ZKFFUx0wyFgIOyu4xIUHLT2IELlE7iyUuOnH+tTbwEfw7axdLJpAWvWF439pr2vUQec9XJyOfvfj1fnJm2O04VOJuSMezGdSNb96a7G8CWefW93SYfAaacV58d4HGO0u2WYXMdryXkStK5M+kmaRhrq+IDyFhm5t5DKKtAuN+thtTeimqrWV4qryoPyF1mWNc1lYGfLPhdP3x9MhbQFomIwgjs6xwEY/FALZNGKTkBRRXK5WhtkkDLN4S4UHyQTsofJwUfpAHJLlznco52nQyp/mwcULWaOF9D8gDOryMI2RQ4DhZhw5WRcGKZ4K1dOnhaPbvjvteGyfHALbWuVdok=
Signature digestsha512
Dependencies
Required Nextcloud versions >=32.0.0,<36.0.0
Minimum Integer bits32
PHP>=8.1.0
Microsoft 365 integration 0.2.2
Release Details
UpdatedOct. 16, 2026, 8:48 a.m.
Changelog
  • Fixed: the reconnect notification linked to a non-existent settings section (blank page); it now opens Connected accounts.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhRuMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYxMDE1MTk1ODQ0WhcNMzcwMTIwMTk1ODQ0WjAbMRkwFwYD
VQQDDBBpbnRlZ3JhdGlvbl9tMzY1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEApWBRPJ2upm8vSw86u9SfuJ8ts5Eof79s71iRrxWV/YQ4M1oc5ZIwQy+P
38QNAayun4ZnVBJZghI7oEeu9BEfTdPDfbdXg7VyZr7qfnP9VDGiN50Cqx/FEmK4
NzejcyJLVOHJdoESx+owQbnsmMV89L9RdzP2u/qbZm4hMpzbj+/JDaM1BTW0iucY
vId2Aw6bSD6wUn1mA+y6NVCqS8PQcO54BQNAzvy4t1liN1EtntKxIvnh6RvtAN+6
Fh8YyNAMxEFn0pIxGveQLNvcjux5lpJqqypAvoHCiI9uP3j/F/qR9HeVTLbDhZod
xf0c6Vj4foU8J6hWnsp21s3tpFAjFEJlVHwbmo42Dl+78O4tQCbvoX7FfZmy4iAK
P7mmPqTEMHJEVhROyVd9lt2q977azqDEzGqFORDCeMHQW6k2HQ7ab9A5uon316fP
zfzs1ObibScihSBFQ4p2LV3SiPhH/xZfo9pm/1lsbAn7+J6VG4+S050X91tUmP5t
Ao1CFp5/qBoKb2wNPUMUkqnvG705CtWAAa22RR+T/C3drgRQYJ5O1aZ8cVP0KWdH
aTXXYdMbGEPXoFPikNSwhxuJ3EDTUG0nRVD5Df7dlYnCNwHIShaQgP7AyiqDPoSw
9P4NU/uJqcst2X79hufywPQqMNHfy9Tv0pvGs0Lv8kFT8mhjjTsCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAjeoLWgiZcu4FzAv6hRhx4TQnGpmFC3cz+NscaJZP4iUr
xrhHBJ7HgSjYmqLf+Y+A5NVPKAUf7XJ6LovJQzeN2t8gmcTuhnPVQLrSAdX9lbUi
uX3zR/aoZH5PEQCwzOpHICnKVFsS0t6f31mGP3OCOlNh5SolMKSfGefpBCtkqHDP
sIVl8DrC5QL5RjbpJJb1Fk6FyUdXKeOZ8R6doXTfekxzFqkeECENw48k0TQwp4wP
XHczcaum+uy1/nOCrUWV0mE/g3CJIyWWrkHoNvKOD9q7Apn174qkknGEXEAmZaQK
Dlyaa48a0ekpnxDWJTzSx4PfjCtiayqEcy0d/0bskg==
-----END CERTIFICATE-----
SignatureZKwv0BMmPcHzxa0jZ39sRv7Gohm0iuJUHogNehq3dnWl9PxQJl64qIQHh3zCIl8hlGZuK5ERvbLFNs/DLGg8aqpbotVGO17lAzy136m4nAxYuscv2MKijcE8pBiaJSuPa0TwEIrR32JvHQwXMNMpk/qA2hc8JqIuB7gyNmp0nB+8Ltuq41v9TkntDeslFVJLuI/1/I+IZ/0TQqdyZEuV3Vlq/gt8kNgjvhw0p/vdONHPoq3uXSSnqIKxJMv6/KoYZvSvD3NLLYuJLhHUGpewP9x8jDvWeZoiOFEZvyRCqUMqtpUb4VPvba2zizF1gVID4RZ4G0jXbMrlpzyymCpac63oYJzmXmSWvaSoQl8qLAPfYaHYL4jJHBiHPr2fFNXNAOXkYxrHqEjYJwIQXy37vBlPIC+DYpcpMsZFRn7BW/qaPw9FNxJlaRtTRjZto2fhhz7onM8uzyA3tFNjVxL9yPHnqeWVQETk8E9zZuAI49+fJ4+35uVqb2v2n+2HRpHExswEu5tNCBeqQJRtuD1KIixhQqa4gRmYryRhEd/vS2WBjXJr6Gv2T2OK0prynolY0y9LH+WjAFoK811qy5idZCeZHZfFHam3qrEOZaru+dxSAdkCQFU/w5zJWdgCybm6dBaSp0CM1a5/FBNK/BvsnsChE+FhJAQ0HkLxM04dkbA=
Signature digestsha512
Dependencies
Required Nextcloud versions >=32.0.0,<36.0.0
Minimum Integer bits32
PHP>=8.1.0
Microsoft 365 integration 0.2.1
Release Details
UpdatedOct. 16, 2026, 7:43 a.m.
Changelog
  • When Microsoft rejects the refresh token (password change, revoked sessions, consent withdrawn) the user now gets a Nextcloud notification linking to the personal settings; it is cleared on reconnect. The Microsoft error (e.g. AADSTS50173) is written to the log.
  • README: setup guide for any tenant (Entra ID app registration, scopes, consent).
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhRuMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYxMDE1MTk1ODQ0WhcNMzcwMTIwMTk1ODQ0WjAbMRkwFwYD
VQQDDBBpbnRlZ3JhdGlvbl9tMzY1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEApWBRPJ2upm8vSw86u9SfuJ8ts5Eof79s71iRrxWV/YQ4M1oc5ZIwQy+P
38QNAayun4ZnVBJZghI7oEeu9BEfTdPDfbdXg7VyZr7qfnP9VDGiN50Cqx/FEmK4
NzejcyJLVOHJdoESx+owQbnsmMV89L9RdzP2u/qbZm4hMpzbj+/JDaM1BTW0iucY
vId2Aw6bSD6wUn1mA+y6NVCqS8PQcO54BQNAzvy4t1liN1EtntKxIvnh6RvtAN+6
Fh8YyNAMxEFn0pIxGveQLNvcjux5lpJqqypAvoHCiI9uP3j/F/qR9HeVTLbDhZod
xf0c6Vj4foU8J6hWnsp21s3tpFAjFEJlVHwbmo42Dl+78O4tQCbvoX7FfZmy4iAK
P7mmPqTEMHJEVhROyVd9lt2q977azqDEzGqFORDCeMHQW6k2HQ7ab9A5uon316fP
zfzs1ObibScihSBFQ4p2LV3SiPhH/xZfo9pm/1lsbAn7+J6VG4+S050X91tUmP5t
Ao1CFp5/qBoKb2wNPUMUkqnvG705CtWAAa22RR+T/C3drgRQYJ5O1aZ8cVP0KWdH
aTXXYdMbGEPXoFPikNSwhxuJ3EDTUG0nRVD5Df7dlYnCNwHIShaQgP7AyiqDPoSw
9P4NU/uJqcst2X79hufywPQqMNHfy9Tv0pvGs0Lv8kFT8mhjjTsCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAjeoLWgiZcu4FzAv6hRhx4TQnGpmFC3cz+NscaJZP4iUr
xrhHBJ7HgSjYmqLf+Y+A5NVPKAUf7XJ6LovJQzeN2t8gmcTuhnPVQLrSAdX9lbUi
uX3zR/aoZH5PEQCwzOpHICnKVFsS0t6f31mGP3OCOlNh5SolMKSfGefpBCtkqHDP
sIVl8DrC5QL5RjbpJJb1Fk6FyUdXKeOZ8R6doXTfekxzFqkeECENw48k0TQwp4wP
XHczcaum+uy1/nOCrUWV0mE/g3CJIyWWrkHoNvKOD9q7Apn174qkknGEXEAmZaQK
Dlyaa48a0ekpnxDWJTzSx4PfjCtiayqEcy0d/0bskg==
-----END CERTIFICATE-----
SignatureLznrfOO+tCgKsPCmgkRIDbziD6G/tORiyX5Nsc+UMVBDxz0aJ8IPQp/fYDQzKgvIqLMtmez9Qhzkf1JXUgsZ4w8vLJCv3QWggSnn7jVHXfiLwGH1MFlry91PK+PitVe8EcCjO76wSvYDajq4DgkIogkdMIEgbULhDHRA+/3QQO0b1sfd2HUJGVG3Vz58DV5bspvzG4enxNMgz142vNFQNmFDe3zxKHQtrmNagkWMYFg2n5r1nKW55IZD2RnwLmRqfmnWHRV7loYpl8BlZITCiV5p5H7teK/1h06rDxMwnWTamsPk5x7mSO9sfUTJyctivRZZYNqonw8S63EDSWlJlmXZ1GL8+hArDkoMXL13164GkCn1jggbSm8hQJTLMu34oz1T47Iuhh+mfRunw9ex8hCqLr6cnQzI9Da3Bt9DtAjf+s0euilY1YwQaWKVSrNICgnCZ0NQIfwZv1D3qEegs12T0axy6c2htTnm+k2kC1UA/5MBoXWF2loBACmZlqSnGfPlLhM4xnmNqEw7Wqk0kgnlV2Sq41TJAEO2DE3AOKqAQAeNbHBN4em06rft5xaveP6F9+qsowzm0uWBTl9AZ4voma4fmPghCbO9qFAqWfQiC0L2oGdNIoiOjF3vO2RH4DwhCYG5Jm2Jj45EPFfjSHYs1eDb7gRZPAKMM86f724=
Signature digestsha512
Dependencies
Required Nextcloud versions >=32.0.0,<36.0.0
Minimum Integer bits32
PHP>=8.1.0
Microsoft 365 integration 0.2.0
Release Details
UpdatedOct. 16, 2026, 7:36 a.m.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhRuMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYxMDE1MTk1ODQ0WhcNMzcwMTIwMTk1ODQ0WjAbMRkwFwYD
VQQDDBBpbnRlZ3JhdGlvbl9tMzY1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEApWBRPJ2upm8vSw86u9SfuJ8ts5Eof79s71iRrxWV/YQ4M1oc5ZIwQy+P
38QNAayun4ZnVBJZghI7oEeu9BEfTdPDfbdXg7VyZr7qfnP9VDGiN50Cqx/FEmK4
NzejcyJLVOHJdoESx+owQbnsmMV89L9RdzP2u/qbZm4hMpzbj+/JDaM1BTW0iucY
vId2Aw6bSD6wUn1mA+y6NVCqS8PQcO54BQNAzvy4t1liN1EtntKxIvnh6RvtAN+6
Fh8YyNAMxEFn0pIxGveQLNvcjux5lpJqqypAvoHCiI9uP3j/F/qR9HeVTLbDhZod
xf0c6Vj4foU8J6hWnsp21s3tpFAjFEJlVHwbmo42Dl+78O4tQCbvoX7FfZmy4iAK
P7mmPqTEMHJEVhROyVd9lt2q977azqDEzGqFORDCeMHQW6k2HQ7ab9A5uon316fP
zfzs1ObibScihSBFQ4p2LV3SiPhH/xZfo9pm/1lsbAn7+J6VG4+S050X91tUmP5t
Ao1CFp5/qBoKb2wNPUMUkqnvG705CtWAAa22RR+T/C3drgRQYJ5O1aZ8cVP0KWdH
aTXXYdMbGEPXoFPikNSwhxuJ3EDTUG0nRVD5Df7dlYnCNwHIShaQgP7AyiqDPoSw
9P4NU/uJqcst2X79hufywPQqMNHfy9Tv0pvGs0Lv8kFT8mhjjTsCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAjeoLWgiZcu4FzAv6hRhx4TQnGpmFC3cz+NscaJZP4iUr
xrhHBJ7HgSjYmqLf+Y+A5NVPKAUf7XJ6LovJQzeN2t8gmcTuhnPVQLrSAdX9lbUi
uX3zR/aoZH5PEQCwzOpHICnKVFsS0t6f31mGP3OCOlNh5SolMKSfGefpBCtkqHDP
sIVl8DrC5QL5RjbpJJb1Fk6FyUdXKeOZ8R6doXTfekxzFqkeECENw48k0TQwp4wP
XHczcaum+uy1/nOCrUWV0mE/g3CJIyWWrkHoNvKOD9q7Apn174qkknGEXEAmZaQK
Dlyaa48a0ekpnxDWJTzSx4PfjCtiayqEcy0d/0bskg==
-----END CERTIFICATE-----
SignatureQWxuiMN2+CUAW40ir1J/1BCwWvWxYyzwR8uFrtCr82a4ate8vrpf9D3RFrVe/EM3QaS40eE0mtEGJmfiCw5+G1TGm8hP/lHay+Ze21saaEswpZnR6NGxJutZfiWZYfNBPZQXArx5HNdfJLMFCGDCRmfswCXHS2AVDJnqct/zuz1X7QLaEbA4mEYMu7AY5LzMF2kh5YD702v/g+ra+jswvqcPbLXa0ClhMqYH4e8Jh0XQVN5cRwTUygVBXoLQGA/3+Vj0MSK5hmJ11GOPV8P6eiol8bFQSuoFWnAe93rHkPAS0wjRtlzggYUGA9038BoM/XYhIlv965lTjo91n/msA4SI77HSlEVMF3+yLQWCTRSisGxBlAuNJzOuG7rEjY2wDiyd977PAl3Ja913rWzFSAzRSKCS1mqxLT5Vb+6lv72gNJA5hQMkhhtxAq/oyoxqWhvKvJkOhK0+aejZi+J8yehoOoFf3mIRxUufwXyZAfaLDYr+2pvYygnP1qQn5WyjVKczY7mt6mfscKpHOzYpAAzI/AfcQcI7aedS3BRSfLHchHb4mx6H8FnvoB4V/taN5m+cH2jt4HuYwKqpCWRnehAvn4iOS/URHH8c5E9pLUvvN9kMLxDDQ2PlVpIWAFnKPDC+YtMcRzfdScErTt5PXwrd6J7E+UxBUKJ1IpWrTZo=
Signature digestsha512
Dependencies
Required Nextcloud versions >=32.0.0,<36.0.0
Minimum Integer bits32
PHP>=8.1.0

Nextcloud 33

Microsoft 365 integration 1.0.1
Release Details
UpdatedOct. 16, 2026, 1:56 p.m.
Changelog

Added

  • Admin setting Sync interval (60–3600 s, default 300) for the background job; Nextcloud's cron must run at least that often (documented in the admin guide).
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhRuMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYxMDE1MTk1ODQ0WhcNMzcwMTIwMTk1ODQ0WjAbMRkwFwYD
VQQDDBBpbnRlZ3JhdGlvbl9tMzY1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEApWBRPJ2upm8vSw86u9SfuJ8ts5Eof79s71iRrxWV/YQ4M1oc5ZIwQy+P
38QNAayun4ZnVBJZghI7oEeu9BEfTdPDfbdXg7VyZr7qfnP9VDGiN50Cqx/FEmK4
NzejcyJLVOHJdoESx+owQbnsmMV89L9RdzP2u/qbZm4hMpzbj+/JDaM1BTW0iucY
vId2Aw6bSD6wUn1mA+y6NVCqS8PQcO54BQNAzvy4t1liN1EtntKxIvnh6RvtAN+6
Fh8YyNAMxEFn0pIxGveQLNvcjux5lpJqqypAvoHCiI9uP3j/F/qR9HeVTLbDhZod
xf0c6Vj4foU8J6hWnsp21s3tpFAjFEJlVHwbmo42Dl+78O4tQCbvoX7FfZmy4iAK
P7mmPqTEMHJEVhROyVd9lt2q977azqDEzGqFORDCeMHQW6k2HQ7ab9A5uon316fP
zfzs1ObibScihSBFQ4p2LV3SiPhH/xZfo9pm/1lsbAn7+J6VG4+S050X91tUmP5t
Ao1CFp5/qBoKb2wNPUMUkqnvG705CtWAAa22RR+T/C3drgRQYJ5O1aZ8cVP0KWdH
aTXXYdMbGEPXoFPikNSwhxuJ3EDTUG0nRVD5Df7dlYnCNwHIShaQgP7AyiqDPoSw
9P4NU/uJqcst2X79hufywPQqMNHfy9Tv0pvGs0Lv8kFT8mhjjTsCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAjeoLWgiZcu4FzAv6hRhx4TQnGpmFC3cz+NscaJZP4iUr
xrhHBJ7HgSjYmqLf+Y+A5NVPKAUf7XJ6LovJQzeN2t8gmcTuhnPVQLrSAdX9lbUi
uX3zR/aoZH5PEQCwzOpHICnKVFsS0t6f31mGP3OCOlNh5SolMKSfGefpBCtkqHDP
sIVl8DrC5QL5RjbpJJb1Fk6FyUdXKeOZ8R6doXTfekxzFqkeECENw48k0TQwp4wP
XHczcaum+uy1/nOCrUWV0mE/g3CJIyWWrkHoNvKOD9q7Apn174qkknGEXEAmZaQK
Dlyaa48a0ekpnxDWJTzSx4PfjCtiayqEcy0d/0bskg==
-----END CERTIFICATE-----
Signatureinv2Ikv2Cm00nt4BqLa8KwDqMxMjXoZJ8oiLh/a/3K5ZMwTQjjjbUqew+9LDRb+Rf/+Nkk++8vkQ0jNZ1CRM6IIfG3TCyQ9XGZ1xPJd+Lw69YMDyQxqW3Ybprc+g2xgub0Yl4bp4Heu26eJLFNKRqgZx0BTh4tFeN02iC8rmpWif4zSXQuQdGWeaFI+6dhs4Cuh8kj+ab2nrE1V51gLTFFv29R0P1FKLmgeRKt7WXqXyQ8hDW3yw3S1sh0T5G+qLDhS3IcHRqOOU7eXKBb20WgNRMWOv3je+UUgRe+73fiJ0kZUCW4ZYNT2l7lrjijATAuCyK1BEQSVU/UUMJVg4oZscW/kafdPTX9VscSo7WrGe1C9H6oYQYzFUkzEGVP4fSMCvEXhiVSCLtKSly2TxUIh6c4/au7mYu3G9Yq6LsJVz+NStdcbp7oOddjJFjcOiu3RakNNOpV2kHlWSwooTykJXyfKZNWzgGqmIyHKfJe0DuYmko+ntc5Sc00FooBkJO4zx1ngfVWIUl5rsEhqungtecNX2E8T0NlgL/am5WAEkkoDAk8cMiAuL31BFAW+GyMH2CMxBfVdPulyDYXHoG0sJZO/McaVbbXc36cAO7pYSy8KoMHHHREXWSPQNlbKzIezU10edhaGdFOWsGKxldJ8Xe1LvVghKWKbgDLKe4n8=
Signature digestsha512
Dependencies
Required Nextcloud versions >=32.0.0,<36.0.0
Minimum Integer bits32
PHP>=8.1.0
Microsoft 365 integration 1.0.0
Release Details
UpdatedOct. 16, 2026, 1:10 p.m.
Changelog

Documentation

  • README split into a short overview plus docs/admin.md (Entra ID registration step by step, permissions and why, account types, secret rotation, occ commands, troubleshooting by AADSTS code, scaling, uninstall), docs/user.md and docs/privacy.md (data flow, storage, retention, logging and deletion for data protection officers). Wrong menu paths fixed: the settings live under Connected accounts.
  • SECURITY.md (private reporting, scope, design notes) and CONTRIBUTING.md (setup, checks, conventions, fixture rules, release steps).
  • Known limitations extended (own mailbox only, 1 MB cap, failed objects retried on change, write-cap rounds).
  • Changelog switched to the Keep a Changelog format.

Lifecycle and data hygiene

  • Deleting a Nextcloud user now removes their tokens, pairs, correlations, queued jobs and notifications (UserDeletedEvent). Before, the background job kept recreating an orphaned calendar for the deleted principal every 5 minutes.
  • Disconnecting removes the queued sync job and, with purge, the correlations as well (they were left behind). Without purge the pairs are only disabled and resume on reconnect.
  • Connecting a different Microsoft account resets the pairs: remote ids and delta links of the old mailbox are meaningless for the new one.
  • Changing client id or tenant in the admin settings invalidates every user's tokens and notifies them to connect again; changing only the secret keeps them valid.
  • A bad secret, unknown client id or wrong tenant (invalid_client, unauthorized_client) is now reported as an admin configuration error (config_error) instead of asking every user to reconnect.
  • If a user deletes (or trashes) the local calendar or address book of a pair, the pair is disabled with local_missing instead of silently recreating the collection and replaying old cursors against it, which would have deleted everything on the Microsoft side. Re-enabling the pair starts fresh and re-pairs existing objects by UID.
  • Users flagged for reconnect are skipped by the background job without touching Graph.
  • app:disable / app:remove run an uninstall step that removes the background jobs and open notifications; tables, tokens and pairs stay so that re-enabling resumes.
  • New occ integration_m365:reset --pair ID | --user UID | --all: forget cursors and correlations of one pair (next run re-pairs by UID), purge one user, or wipe everything before app:remove. Local calendars and address books are never touched.
  • last_error now holds machine-readable codes (reauth_required, config_error, local_missing, items_failed:N) so the UI can translate them.

App Store listing

  • App icon (neutral two-way sync glyph, img/app.svg / img/app-dark.svg), used for the settings sections and the notification instead of the generic core icon.
  • info.xml: screenshots (placeholders in screenshots/, to be replaced by real captures), user and admin documentation links, repository, requirements (cron, Entra ID registration) in the description.

Admin and user experience

  • Admin settings: "Test connection" verifies client ID, secret and tenant against Entra ID without a user (client-credentials grant; multi-tenant settings can only be verified by a user login), copy button for the redirect URI, optional client-secret expiry date with a warning 30 days ahead, link to the admin guide, and a notice when a registration change asked users to reconnect.
  • Entra ID errors during login and in the connection test are mapped to actionable messages (redirect URI mismatch, missing consent, wrong client ID or tenant, wrong or expired secret, account type not allowed, Conditional Access, revoked login) with the AADSTS number kept for reference; the error no longer stays in the address bar.
  • Personal settings: disconnect asks whether to keep the collection settings or forget the synchronisation state; "Sync now" reports failures (reconnect needed, admin configuration, server error) instead of pretending the job was queued; error codes in the tables are shown as translated text; dates follow the Nextcloud locale.
  • Fixed: buttons used the nextcloud/vue 8 type prop and therefore all rendered as secondary buttons; variant is the nextcloud/vue 9 prop.
  • Fixed: the redirect after connecting pointed at a non-existent anchor.
  • Accessibility: checkboxes, name fields and conflict selects carry labels naming the collection, tables are labelled by their heading, column headers have a scope, decorative icons are hidden from screen readers.

Translations

  • German translation (de informal, de_DE formal) for every string in the settings pages, notifications and server-side messages; maintained in tools/l10n-de.py until the app is on Transifex (.tx/config and .l10nignore are in place). A unit test checks that every source string is translated and that placeholders survive.
  • Server-side messages that reach the user (login errors, "not configured", "not connected", the default "Contacts" folder name) now go through the Nextcloud translation system.

Tests

  • Unit tests for OAuthService (PKCE/state, refresh, invalid_grant → one notification, invalid_client → admin error, redirect, registration test), GraphClient (paging, host allow-list, delta expiry, throttling and back-off, retry rules per method, 401 refresh, error mapping, $batch sub-request retries), LifecycleService, UserDeletedListener, Notifier, EntraErrors, UserSyncService (locking, reauth skip, missing local collection, --full), background jobs and both controllers; SyncEngine now also covers both-deleted, delete-versus-change in both directions and policies, identical concurrent edits, the write cap, per-item failures, deferred photos and To Do lists. 133 tests.
  • time() and sleep() go through ITimeFactory / an overridable pause so that tests do not wait.

Compatibility and CI

  • Test matrix now covers what info.xml claims: PHP 8.1 with OCP stable32, 8.2 with stable33, 8.3 and 8.4 with stable35 (lint, psalm, PHPUnit on every entry).
  • New install job: the packaged app is installed into a real Nextcloud 32 (PHP 8.1) and 35 (PHP 8.4) server, enabled (migrations), its commands, settings pages, background job and uninstall step are exercised and the server log must stay clean.
  • Conformance fixtures are diffed against the vdirsyncer-graph repository on every run.
  • ESLint (@nextcloud/eslint-config) and stylelint (@nextcloud/stylelint-config) for the frontend; sources reformatted accordingly. .nvmrc pins Node 22.
  • Release workflow: runs the full test workflow first, checks tag, info.xml, package.json and CHANGELOG against each other, installs the signed build into a server and runs integrity:check-app, fails loudly when signing secrets are missing and warns when the App Store token is absent. Server checkout pinned to a tag.
  • Code made acceptable to the older psalm that resolves on PHP 8.1; psr/http-message declared as the dev dependency it is.

Robustness

  • Fixed: a throttled or failed photo fetch inside a $batch was taken as "contact has no photo"; the content hash changed and the local contact was rewritten without its picture. Photos that could not be fetched now defer the contact to the next run; throttled sub-requests are retried with their Retry-After.
  • Graph client: retries 429/503/504 for every request and 500/502 plus network errors for idempotent ones, honours Retry-After in seconds and HTTP-date form, backs off exponentially with full jitter, and gives up immediately when Graph asks for more than 20 s (the next run tries again). Connect timeout of 10 s.
  • The pair lock is taken with one conditional UPDATE: cron and "Sync now" can no longer both pass a read-then-write check. --full resets the cursors under the lock.
  • Background job is now time sensitive (instances with a maintenance window only synced during that window), spends at most 240 s per run and visits users least recently synced first, so nobody starves when a run is cut short. One failing user no longer aborts the others.
  • A pair skipped because another run holds its lock no longer makes the "Sync now" job re-queue itself every tick.
  • Deferred (documented limitation): a run cut short by the write cap re-lists the whole remote collection next time; initial imports of very large collections therefore cost more Graph pages than strictly necessary.

Security

  • nextLink/deltaLink (stored and replayed) and every other absolute URL are only followed on https://graph.microsoft.com; anything else is refused before a bearer token is attached.
  • Authorization code, token responses, token request parameters and raw upload bodies carry #[\SensitiveParameter] so they never appear in logged stack traces.
  • Collection updates validate the lengths of remote id and names (HTTP 400 instead of a database error) and report Graph/token failures of the read-only probe as 502/400 instead of 500.
  • Calendars and address books are only used when they belong to the user's principal and are not in the trash bin.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhRuMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYxMDE1MTk1ODQ0WhcNMzcwMTIwMTk1ODQ0WjAbMRkwFwYD
VQQDDBBpbnRlZ3JhdGlvbl9tMzY1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEApWBRPJ2upm8vSw86u9SfuJ8ts5Eof79s71iRrxWV/YQ4M1oc5ZIwQy+P
38QNAayun4ZnVBJZghI7oEeu9BEfTdPDfbdXg7VyZr7qfnP9VDGiN50Cqx/FEmK4
NzejcyJLVOHJdoESx+owQbnsmMV89L9RdzP2u/qbZm4hMpzbj+/JDaM1BTW0iucY
vId2Aw6bSD6wUn1mA+y6NVCqS8PQcO54BQNAzvy4t1liN1EtntKxIvnh6RvtAN+6
Fh8YyNAMxEFn0pIxGveQLNvcjux5lpJqqypAvoHCiI9uP3j/F/qR9HeVTLbDhZod
xf0c6Vj4foU8J6hWnsp21s3tpFAjFEJlVHwbmo42Dl+78O4tQCbvoX7FfZmy4iAK
P7mmPqTEMHJEVhROyVd9lt2q977azqDEzGqFORDCeMHQW6k2HQ7ab9A5uon316fP
zfzs1ObibScihSBFQ4p2LV3SiPhH/xZfo9pm/1lsbAn7+J6VG4+S050X91tUmP5t
Ao1CFp5/qBoKb2wNPUMUkqnvG705CtWAAa22RR+T/C3drgRQYJ5O1aZ8cVP0KWdH
aTXXYdMbGEPXoFPikNSwhxuJ3EDTUG0nRVD5Df7dlYnCNwHIShaQgP7AyiqDPoSw
9P4NU/uJqcst2X79hufywPQqMNHfy9Tv0pvGs0Lv8kFT8mhjjTsCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAjeoLWgiZcu4FzAv6hRhx4TQnGpmFC3cz+NscaJZP4iUr
xrhHBJ7HgSjYmqLf+Y+A5NVPKAUf7XJ6LovJQzeN2t8gmcTuhnPVQLrSAdX9lbUi
uX3zR/aoZH5PEQCwzOpHICnKVFsS0t6f31mGP3OCOlNh5SolMKSfGefpBCtkqHDP
sIVl8DrC5QL5RjbpJJb1Fk6FyUdXKeOZ8R6doXTfekxzFqkeECENw48k0TQwp4wP
XHczcaum+uy1/nOCrUWV0mE/g3CJIyWWrkHoNvKOD9q7Apn174qkknGEXEAmZaQK
Dlyaa48a0ekpnxDWJTzSx4PfjCtiayqEcy0d/0bskg==
-----END CERTIFICATE-----
SignaturenkGATOR6zcwDPXIvxgSfpdybK+oT2n3+F0/jxi4368Z42KOn0MUz/hStMW3pdKQBxDW66OuSI9ehV16vNjnHZtd1+243aW1dyPpl/f5xGQq6aMBWjEtWD+uzInX38vQMebW2KOlExA8oPeW62God33LgI/f/mcej5PFUq8ieZuKC8QtuX/KpQ0fVDML9I7IFD3J28E95r87+SNPpbx4IOOdE38/YRmhM5BgEWMYG2gMDWUUpgQK46NgdE2GCq9zW3C4DzaMnclflgozETWR/sKERZePp4TnEDcacZ/Kz82lgtvr6f1FnEOQNxnXLJwInp/IS+z+paexuNVOYmkKX2ZKFFUx0wyFgIOyu4xIUHLT2IELlE7iyUuOnH+tTbwEfw7axdLJpAWvWF439pr2vUQec9XJyOfvfj1fnJm2O04VOJuSMezGdSNb96a7G8CWefW93SYfAaacV58d4HGO0u2WYXMdryXkStK5M+kmaRhrq+IDyFhm5t5DKKtAuN+thtTeimqrWV4qryoPyF1mWNc1lYGfLPhdP3x9MhbQFomIwgjs6xwEY/FALZNGKTkBRRXK5WhtkkDLN4S4UHyQTsofJwUfpAHJLlznco52nQyp/mwcULWaOF9D8gDOryMI2RQ4DhZhw5WRcGKZ4K1dOnhaPbvjvteGyfHALbWuVdok=
Signature digestsha512
Dependencies
Required Nextcloud versions >=32.0.0,<36.0.0
Minimum Integer bits32
PHP>=8.1.0
Microsoft 365 integration 0.2.2
Release Details
UpdatedOct. 16, 2026, 8:48 a.m.
Changelog
  • Fixed: the reconnect notification linked to a non-existent settings section (blank page); it now opens Connected accounts.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhRuMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYxMDE1MTk1ODQ0WhcNMzcwMTIwMTk1ODQ0WjAbMRkwFwYD
VQQDDBBpbnRlZ3JhdGlvbl9tMzY1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEApWBRPJ2upm8vSw86u9SfuJ8ts5Eof79s71iRrxWV/YQ4M1oc5ZIwQy+P
38QNAayun4ZnVBJZghI7oEeu9BEfTdPDfbdXg7VyZr7qfnP9VDGiN50Cqx/FEmK4
NzejcyJLVOHJdoESx+owQbnsmMV89L9RdzP2u/qbZm4hMpzbj+/JDaM1BTW0iucY
vId2Aw6bSD6wUn1mA+y6NVCqS8PQcO54BQNAzvy4t1liN1EtntKxIvnh6RvtAN+6
Fh8YyNAMxEFn0pIxGveQLNvcjux5lpJqqypAvoHCiI9uP3j/F/qR9HeVTLbDhZod
xf0c6Vj4foU8J6hWnsp21s3tpFAjFEJlVHwbmo42Dl+78O4tQCbvoX7FfZmy4iAK
P7mmPqTEMHJEVhROyVd9lt2q977azqDEzGqFORDCeMHQW6k2HQ7ab9A5uon316fP
zfzs1ObibScihSBFQ4p2LV3SiPhH/xZfo9pm/1lsbAn7+J6VG4+S050X91tUmP5t
Ao1CFp5/qBoKb2wNPUMUkqnvG705CtWAAa22RR+T/C3drgRQYJ5O1aZ8cVP0KWdH
aTXXYdMbGEPXoFPikNSwhxuJ3EDTUG0nRVD5Df7dlYnCNwHIShaQgP7AyiqDPoSw
9P4NU/uJqcst2X79hufywPQqMNHfy9Tv0pvGs0Lv8kFT8mhjjTsCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAjeoLWgiZcu4FzAv6hRhx4TQnGpmFC3cz+NscaJZP4iUr
xrhHBJ7HgSjYmqLf+Y+A5NVPKAUf7XJ6LovJQzeN2t8gmcTuhnPVQLrSAdX9lbUi
uX3zR/aoZH5PEQCwzOpHICnKVFsS0t6f31mGP3OCOlNh5SolMKSfGefpBCtkqHDP
sIVl8DrC5QL5RjbpJJb1Fk6FyUdXKeOZ8R6doXTfekxzFqkeECENw48k0TQwp4wP
XHczcaum+uy1/nOCrUWV0mE/g3CJIyWWrkHoNvKOD9q7Apn174qkknGEXEAmZaQK
Dlyaa48a0ekpnxDWJTzSx4PfjCtiayqEcy0d/0bskg==
-----END CERTIFICATE-----
SignatureZKwv0BMmPcHzxa0jZ39sRv7Gohm0iuJUHogNehq3dnWl9PxQJl64qIQHh3zCIl8hlGZuK5ERvbLFNs/DLGg8aqpbotVGO17lAzy136m4nAxYuscv2MKijcE8pBiaJSuPa0TwEIrR32JvHQwXMNMpk/qA2hc8JqIuB7gyNmp0nB+8Ltuq41v9TkntDeslFVJLuI/1/I+IZ/0TQqdyZEuV3Vlq/gt8kNgjvhw0p/vdONHPoq3uXSSnqIKxJMv6/KoYZvSvD3NLLYuJLhHUGpewP9x8jDvWeZoiOFEZvyRCqUMqtpUb4VPvba2zizF1gVID4RZ4G0jXbMrlpzyymCpac63oYJzmXmSWvaSoQl8qLAPfYaHYL4jJHBiHPr2fFNXNAOXkYxrHqEjYJwIQXy37vBlPIC+DYpcpMsZFRn7BW/qaPw9FNxJlaRtTRjZto2fhhz7onM8uzyA3tFNjVxL9yPHnqeWVQETk8E9zZuAI49+fJ4+35uVqb2v2n+2HRpHExswEu5tNCBeqQJRtuD1KIixhQqa4gRmYryRhEd/vS2WBjXJr6Gv2T2OK0prynolY0y9LH+WjAFoK811qy5idZCeZHZfFHam3qrEOZaru+dxSAdkCQFU/w5zJWdgCybm6dBaSp0CM1a5/FBNK/BvsnsChE+FhJAQ0HkLxM04dkbA=
Signature digestsha512
Dependencies
Required Nextcloud versions >=32.0.0,<36.0.0
Minimum Integer bits32
PHP>=8.1.0
Microsoft 365 integration 0.2.1
Release Details
UpdatedOct. 16, 2026, 7:43 a.m.
Changelog
  • When Microsoft rejects the refresh token (password change, revoked sessions, consent withdrawn) the user now gets a Nextcloud notification linking to the personal settings; it is cleared on reconnect. The Microsoft error (e.g. AADSTS50173) is written to the log.
  • README: setup guide for any tenant (Entra ID app registration, scopes, consent).
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhRuMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYxMDE1MTk1ODQ0WhcNMzcwMTIwMTk1ODQ0WjAbMRkwFwYD
VQQDDBBpbnRlZ3JhdGlvbl9tMzY1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEApWBRPJ2upm8vSw86u9SfuJ8ts5Eof79s71iRrxWV/YQ4M1oc5ZIwQy+P
38QNAayun4ZnVBJZghI7oEeu9BEfTdPDfbdXg7VyZr7qfnP9VDGiN50Cqx/FEmK4
NzejcyJLVOHJdoESx+owQbnsmMV89L9RdzP2u/qbZm4hMpzbj+/JDaM1BTW0iucY
vId2Aw6bSD6wUn1mA+y6NVCqS8PQcO54BQNAzvy4t1liN1EtntKxIvnh6RvtAN+6
Fh8YyNAMxEFn0pIxGveQLNvcjux5lpJqqypAvoHCiI9uP3j/F/qR9HeVTLbDhZod
xf0c6Vj4foU8J6hWnsp21s3tpFAjFEJlVHwbmo42Dl+78O4tQCbvoX7FfZmy4iAK
P7mmPqTEMHJEVhROyVd9lt2q977azqDEzGqFORDCeMHQW6k2HQ7ab9A5uon316fP
zfzs1ObibScihSBFQ4p2LV3SiPhH/xZfo9pm/1lsbAn7+J6VG4+S050X91tUmP5t
Ao1CFp5/qBoKb2wNPUMUkqnvG705CtWAAa22RR+T/C3drgRQYJ5O1aZ8cVP0KWdH
aTXXYdMbGEPXoFPikNSwhxuJ3EDTUG0nRVD5Df7dlYnCNwHIShaQgP7AyiqDPoSw
9P4NU/uJqcst2X79hufywPQqMNHfy9Tv0pvGs0Lv8kFT8mhjjTsCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAjeoLWgiZcu4FzAv6hRhx4TQnGpmFC3cz+NscaJZP4iUr
xrhHBJ7HgSjYmqLf+Y+A5NVPKAUf7XJ6LovJQzeN2t8gmcTuhnPVQLrSAdX9lbUi
uX3zR/aoZH5PEQCwzOpHICnKVFsS0t6f31mGP3OCOlNh5SolMKSfGefpBCtkqHDP
sIVl8DrC5QL5RjbpJJb1Fk6FyUdXKeOZ8R6doXTfekxzFqkeECENw48k0TQwp4wP
XHczcaum+uy1/nOCrUWV0mE/g3CJIyWWrkHoNvKOD9q7Apn174qkknGEXEAmZaQK
Dlyaa48a0ekpnxDWJTzSx4PfjCtiayqEcy0d/0bskg==
-----END CERTIFICATE-----
SignatureLznrfOO+tCgKsPCmgkRIDbziD6G/tORiyX5Nsc+UMVBDxz0aJ8IPQp/fYDQzKgvIqLMtmez9Qhzkf1JXUgsZ4w8vLJCv3QWggSnn7jVHXfiLwGH1MFlry91PK+PitVe8EcCjO76wSvYDajq4DgkIogkdMIEgbULhDHRA+/3QQO0b1sfd2HUJGVG3Vz58DV5bspvzG4enxNMgz142vNFQNmFDe3zxKHQtrmNagkWMYFg2n5r1nKW55IZD2RnwLmRqfmnWHRV7loYpl8BlZITCiV5p5H7teK/1h06rDxMwnWTamsPk5x7mSO9sfUTJyctivRZZYNqonw8S63EDSWlJlmXZ1GL8+hArDkoMXL13164GkCn1jggbSm8hQJTLMu34oz1T47Iuhh+mfRunw9ex8hCqLr6cnQzI9Da3Bt9DtAjf+s0euilY1YwQaWKVSrNICgnCZ0NQIfwZv1D3qEegs12T0axy6c2htTnm+k2kC1UA/5MBoXWF2loBACmZlqSnGfPlLhM4xnmNqEw7Wqk0kgnlV2Sq41TJAEO2DE3AOKqAQAeNbHBN4em06rft5xaveP6F9+qsowzm0uWBTl9AZ4voma4fmPghCbO9qFAqWfQiC0L2oGdNIoiOjF3vO2RH4DwhCYG5Jm2Jj45EPFfjSHYs1eDb7gRZPAKMM86f724=
Signature digestsha512
Dependencies
Required Nextcloud versions >=32.0.0,<36.0.0
Minimum Integer bits32
PHP>=8.1.0
Microsoft 365 integration 0.2.0
Release Details
UpdatedOct. 16, 2026, 7:36 a.m.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhRuMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYxMDE1MTk1ODQ0WhcNMzcwMTIwMTk1ODQ0WjAbMRkwFwYD
VQQDDBBpbnRlZ3JhdGlvbl9tMzY1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEApWBRPJ2upm8vSw86u9SfuJ8ts5Eof79s71iRrxWV/YQ4M1oc5ZIwQy+P
38QNAayun4ZnVBJZghI7oEeu9BEfTdPDfbdXg7VyZr7qfnP9VDGiN50Cqx/FEmK4
NzejcyJLVOHJdoESx+owQbnsmMV89L9RdzP2u/qbZm4hMpzbj+/JDaM1BTW0iucY
vId2Aw6bSD6wUn1mA+y6NVCqS8PQcO54BQNAzvy4t1liN1EtntKxIvnh6RvtAN+6
Fh8YyNAMxEFn0pIxGveQLNvcjux5lpJqqypAvoHCiI9uP3j/F/qR9HeVTLbDhZod
xf0c6Vj4foU8J6hWnsp21s3tpFAjFEJlVHwbmo42Dl+78O4tQCbvoX7FfZmy4iAK
P7mmPqTEMHJEVhROyVd9lt2q977azqDEzGqFORDCeMHQW6k2HQ7ab9A5uon316fP
zfzs1ObibScihSBFQ4p2LV3SiPhH/xZfo9pm/1lsbAn7+J6VG4+S050X91tUmP5t
Ao1CFp5/qBoKb2wNPUMUkqnvG705CtWAAa22RR+T/C3drgRQYJ5O1aZ8cVP0KWdH
aTXXYdMbGEPXoFPikNSwhxuJ3EDTUG0nRVD5Df7dlYnCNwHIShaQgP7AyiqDPoSw
9P4NU/uJqcst2X79hufywPQqMNHfy9Tv0pvGs0Lv8kFT8mhjjTsCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAjeoLWgiZcu4FzAv6hRhx4TQnGpmFC3cz+NscaJZP4iUr
xrhHBJ7HgSjYmqLf+Y+A5NVPKAUf7XJ6LovJQzeN2t8gmcTuhnPVQLrSAdX9lbUi
uX3zR/aoZH5PEQCwzOpHICnKVFsS0t6f31mGP3OCOlNh5SolMKSfGefpBCtkqHDP
sIVl8DrC5QL5RjbpJJb1Fk6FyUdXKeOZ8R6doXTfekxzFqkeECENw48k0TQwp4wP
XHczcaum+uy1/nOCrUWV0mE/g3CJIyWWrkHoNvKOD9q7Apn174qkknGEXEAmZaQK
Dlyaa48a0ekpnxDWJTzSx4PfjCtiayqEcy0d/0bskg==
-----END CERTIFICATE-----
SignatureQWxuiMN2+CUAW40ir1J/1BCwWvWxYyzwR8uFrtCr82a4ate8vrpf9D3RFrVe/EM3QaS40eE0mtEGJmfiCw5+G1TGm8hP/lHay+Ze21saaEswpZnR6NGxJutZfiWZYfNBPZQXArx5HNdfJLMFCGDCRmfswCXHS2AVDJnqct/zuz1X7QLaEbA4mEYMu7AY5LzMF2kh5YD702v/g+ra+jswvqcPbLXa0ClhMqYH4e8Jh0XQVN5cRwTUygVBXoLQGA/3+Vj0MSK5hmJ11GOPV8P6eiol8bFQSuoFWnAe93rHkPAS0wjRtlzggYUGA9038BoM/XYhIlv965lTjo91n/msA4SI77HSlEVMF3+yLQWCTRSisGxBlAuNJzOuG7rEjY2wDiyd977PAl3Ja913rWzFSAzRSKCS1mqxLT5Vb+6lv72gNJA5hQMkhhtxAq/oyoxqWhvKvJkOhK0+aejZi+J8yehoOoFf3mIRxUufwXyZAfaLDYr+2pvYygnP1qQn5WyjVKczY7mt6mfscKpHOzYpAAzI/AfcQcI7aedS3BRSfLHchHb4mx6H8FnvoB4V/taN5m+cH2jt4HuYwKqpCWRnehAvn4iOS/URHH8c5E9pLUvvN9kMLxDDQ2PlVpIWAFnKPDC+YtMcRzfdScErTt5PXwrd6J7E+UxBUKJ1IpWrTZo=
Signature digestsha512
Dependencies
Required Nextcloud versions >=32.0.0,<36.0.0
Minimum Integer bits32
PHP>=8.1.0

Nextcloud 32

Microsoft 365 integration 1.0.1
Release Details
UpdatedOct. 16, 2026, 1:56 p.m.
Changelog

Added

  • Admin setting Sync interval (60–3600 s, default 300) for the background job; Nextcloud's cron must run at least that often (documented in the admin guide).
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhRuMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYxMDE1MTk1ODQ0WhcNMzcwMTIwMTk1ODQ0WjAbMRkwFwYD
VQQDDBBpbnRlZ3JhdGlvbl9tMzY1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEApWBRPJ2upm8vSw86u9SfuJ8ts5Eof79s71iRrxWV/YQ4M1oc5ZIwQy+P
38QNAayun4ZnVBJZghI7oEeu9BEfTdPDfbdXg7VyZr7qfnP9VDGiN50Cqx/FEmK4
NzejcyJLVOHJdoESx+owQbnsmMV89L9RdzP2u/qbZm4hMpzbj+/JDaM1BTW0iucY
vId2Aw6bSD6wUn1mA+y6NVCqS8PQcO54BQNAzvy4t1liN1EtntKxIvnh6RvtAN+6
Fh8YyNAMxEFn0pIxGveQLNvcjux5lpJqqypAvoHCiI9uP3j/F/qR9HeVTLbDhZod
xf0c6Vj4foU8J6hWnsp21s3tpFAjFEJlVHwbmo42Dl+78O4tQCbvoX7FfZmy4iAK
P7mmPqTEMHJEVhROyVd9lt2q977azqDEzGqFORDCeMHQW6k2HQ7ab9A5uon316fP
zfzs1ObibScihSBFQ4p2LV3SiPhH/xZfo9pm/1lsbAn7+J6VG4+S050X91tUmP5t
Ao1CFp5/qBoKb2wNPUMUkqnvG705CtWAAa22RR+T/C3drgRQYJ5O1aZ8cVP0KWdH
aTXXYdMbGEPXoFPikNSwhxuJ3EDTUG0nRVD5Df7dlYnCNwHIShaQgP7AyiqDPoSw
9P4NU/uJqcst2X79hufywPQqMNHfy9Tv0pvGs0Lv8kFT8mhjjTsCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAjeoLWgiZcu4FzAv6hRhx4TQnGpmFC3cz+NscaJZP4iUr
xrhHBJ7HgSjYmqLf+Y+A5NVPKAUf7XJ6LovJQzeN2t8gmcTuhnPVQLrSAdX9lbUi
uX3zR/aoZH5PEQCwzOpHICnKVFsS0t6f31mGP3OCOlNh5SolMKSfGefpBCtkqHDP
sIVl8DrC5QL5RjbpJJb1Fk6FyUdXKeOZ8R6doXTfekxzFqkeECENw48k0TQwp4wP
XHczcaum+uy1/nOCrUWV0mE/g3CJIyWWrkHoNvKOD9q7Apn174qkknGEXEAmZaQK
Dlyaa48a0ekpnxDWJTzSx4PfjCtiayqEcy0d/0bskg==
-----END CERTIFICATE-----
Signatureinv2Ikv2Cm00nt4BqLa8KwDqMxMjXoZJ8oiLh/a/3K5ZMwTQjjjbUqew+9LDRb+Rf/+Nkk++8vkQ0jNZ1CRM6IIfG3TCyQ9XGZ1xPJd+Lw69YMDyQxqW3Ybprc+g2xgub0Yl4bp4Heu26eJLFNKRqgZx0BTh4tFeN02iC8rmpWif4zSXQuQdGWeaFI+6dhs4Cuh8kj+ab2nrE1V51gLTFFv29R0P1FKLmgeRKt7WXqXyQ8hDW3yw3S1sh0T5G+qLDhS3IcHRqOOU7eXKBb20WgNRMWOv3je+UUgRe+73fiJ0kZUCW4ZYNT2l7lrjijATAuCyK1BEQSVU/UUMJVg4oZscW/kafdPTX9VscSo7WrGe1C9H6oYQYzFUkzEGVP4fSMCvEXhiVSCLtKSly2TxUIh6c4/au7mYu3G9Yq6LsJVz+NStdcbp7oOddjJFjcOiu3RakNNOpV2kHlWSwooTykJXyfKZNWzgGqmIyHKfJe0DuYmko+ntc5Sc00FooBkJO4zx1ngfVWIUl5rsEhqungtecNX2E8T0NlgL/am5WAEkkoDAk8cMiAuL31BFAW+GyMH2CMxBfVdPulyDYXHoG0sJZO/McaVbbXc36cAO7pYSy8KoMHHHREXWSPQNlbKzIezU10edhaGdFOWsGKxldJ8Xe1LvVghKWKbgDLKe4n8=
Signature digestsha512
Dependencies
Required Nextcloud versions >=32.0.0,<36.0.0
Minimum Integer bits32
PHP>=8.1.0
Microsoft 365 integration 1.0.0
Release Details
UpdatedOct. 16, 2026, 1:10 p.m.
Changelog

Documentation

  • README split into a short overview plus docs/admin.md (Entra ID registration step by step, permissions and why, account types, secret rotation, occ commands, troubleshooting by AADSTS code, scaling, uninstall), docs/user.md and docs/privacy.md (data flow, storage, retention, logging and deletion for data protection officers). Wrong menu paths fixed: the settings live under Connected accounts.
  • SECURITY.md (private reporting, scope, design notes) and CONTRIBUTING.md (setup, checks, conventions, fixture rules, release steps).
  • Known limitations extended (own mailbox only, 1 MB cap, failed objects retried on change, write-cap rounds).
  • Changelog switched to the Keep a Changelog format.

Lifecycle and data hygiene

  • Deleting a Nextcloud user now removes their tokens, pairs, correlations, queued jobs and notifications (UserDeletedEvent). Before, the background job kept recreating an orphaned calendar for the deleted principal every 5 minutes.
  • Disconnecting removes the queued sync job and, with purge, the correlations as well (they were left behind). Without purge the pairs are only disabled and resume on reconnect.
  • Connecting a different Microsoft account resets the pairs: remote ids and delta links of the old mailbox are meaningless for the new one.
  • Changing client id or tenant in the admin settings invalidates every user's tokens and notifies them to connect again; changing only the secret keeps them valid.
  • A bad secret, unknown client id or wrong tenant (invalid_client, unauthorized_client) is now reported as an admin configuration error (config_error) instead of asking every user to reconnect.
  • If a user deletes (or trashes) the local calendar or address book of a pair, the pair is disabled with local_missing instead of silently recreating the collection and replaying old cursors against it, which would have deleted everything on the Microsoft side. Re-enabling the pair starts fresh and re-pairs existing objects by UID.
  • Users flagged for reconnect are skipped by the background job without touching Graph.
  • app:disable / app:remove run an uninstall step that removes the background jobs and open notifications; tables, tokens and pairs stay so that re-enabling resumes.
  • New occ integration_m365:reset --pair ID | --user UID | --all: forget cursors and correlations of one pair (next run re-pairs by UID), purge one user, or wipe everything before app:remove. Local calendars and address books are never touched.
  • last_error now holds machine-readable codes (reauth_required, config_error, local_missing, items_failed:N) so the UI can translate them.

App Store listing

  • App icon (neutral two-way sync glyph, img/app.svg / img/app-dark.svg), used for the settings sections and the notification instead of the generic core icon.
  • info.xml: screenshots (placeholders in screenshots/, to be replaced by real captures), user and admin documentation links, repository, requirements (cron, Entra ID registration) in the description.

Admin and user experience

  • Admin settings: "Test connection" verifies client ID, secret and tenant against Entra ID without a user (client-credentials grant; multi-tenant settings can only be verified by a user login), copy button for the redirect URI, optional client-secret expiry date with a warning 30 days ahead, link to the admin guide, and a notice when a registration change asked users to reconnect.
  • Entra ID errors during login and in the connection test are mapped to actionable messages (redirect URI mismatch, missing consent, wrong client ID or tenant, wrong or expired secret, account type not allowed, Conditional Access, revoked login) with the AADSTS number kept for reference; the error no longer stays in the address bar.
  • Personal settings: disconnect asks whether to keep the collection settings or forget the synchronisation state; "Sync now" reports failures (reconnect needed, admin configuration, server error) instead of pretending the job was queued; error codes in the tables are shown as translated text; dates follow the Nextcloud locale.
  • Fixed: buttons used the nextcloud/vue 8 type prop and therefore all rendered as secondary buttons; variant is the nextcloud/vue 9 prop.
  • Fixed: the redirect after connecting pointed at a non-existent anchor.
  • Accessibility: checkboxes, name fields and conflict selects carry labels naming the collection, tables are labelled by their heading, column headers have a scope, decorative icons are hidden from screen readers.

Translations

  • German translation (de informal, de_DE formal) for every string in the settings pages, notifications and server-side messages; maintained in tools/l10n-de.py until the app is on Transifex (.tx/config and .l10nignore are in place). A unit test checks that every source string is translated and that placeholders survive.
  • Server-side messages that reach the user (login errors, "not configured", "not connected", the default "Contacts" folder name) now go through the Nextcloud translation system.

Tests

  • Unit tests for OAuthService (PKCE/state, refresh, invalid_grant → one notification, invalid_client → admin error, redirect, registration test), GraphClient (paging, host allow-list, delta expiry, throttling and back-off, retry rules per method, 401 refresh, error mapping, $batch sub-request retries), LifecycleService, UserDeletedListener, Notifier, EntraErrors, UserSyncService (locking, reauth skip, missing local collection, --full), background jobs and both controllers; SyncEngine now also covers both-deleted, delete-versus-change in both directions and policies, identical concurrent edits, the write cap, per-item failures, deferred photos and To Do lists. 133 tests.
  • time() and sleep() go through ITimeFactory / an overridable pause so that tests do not wait.

Compatibility and CI

  • Test matrix now covers what info.xml claims: PHP 8.1 with OCP stable32, 8.2 with stable33, 8.3 and 8.4 with stable35 (lint, psalm, PHPUnit on every entry).
  • New install job: the packaged app is installed into a real Nextcloud 32 (PHP 8.1) and 35 (PHP 8.4) server, enabled (migrations), its commands, settings pages, background job and uninstall step are exercised and the server log must stay clean.
  • Conformance fixtures are diffed against the vdirsyncer-graph repository on every run.
  • ESLint (@nextcloud/eslint-config) and stylelint (@nextcloud/stylelint-config) for the frontend; sources reformatted accordingly. .nvmrc pins Node 22.
  • Release workflow: runs the full test workflow first, checks tag, info.xml, package.json and CHANGELOG against each other, installs the signed build into a server and runs integrity:check-app, fails loudly when signing secrets are missing and warns when the App Store token is absent. Server checkout pinned to a tag.
  • Code made acceptable to the older psalm that resolves on PHP 8.1; psr/http-message declared as the dev dependency it is.

Robustness

  • Fixed: a throttled or failed photo fetch inside a $batch was taken as "contact has no photo"; the content hash changed and the local contact was rewritten without its picture. Photos that could not be fetched now defer the contact to the next run; throttled sub-requests are retried with their Retry-After.
  • Graph client: retries 429/503/504 for every request and 500/502 plus network errors for idempotent ones, honours Retry-After in seconds and HTTP-date form, backs off exponentially with full jitter, and gives up immediately when Graph asks for more than 20 s (the next run tries again). Connect timeout of 10 s.
  • The pair lock is taken with one conditional UPDATE: cron and "Sync now" can no longer both pass a read-then-write check. --full resets the cursors under the lock.
  • Background job is now time sensitive (instances with a maintenance window only synced during that window), spends at most 240 s per run and visits users least recently synced first, so nobody starves when a run is cut short. One failing user no longer aborts the others.
  • A pair skipped because another run holds its lock no longer makes the "Sync now" job re-queue itself every tick.
  • Deferred (documented limitation): a run cut short by the write cap re-lists the whole remote collection next time; initial imports of very large collections therefore cost more Graph pages than strictly necessary.

Security

  • nextLink/deltaLink (stored and replayed) and every other absolute URL are only followed on https://graph.microsoft.com; anything else is refused before a bearer token is attached.
  • Authorization code, token responses, token request parameters and raw upload bodies carry #[\SensitiveParameter] so they never appear in logged stack traces.
  • Collection updates validate the lengths of remote id and names (HTTP 400 instead of a database error) and report Graph/token failures of the read-only probe as 502/400 instead of 500.
  • Calendars and address books are only used when they belong to the user's principal and are not in the trash bin.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhRuMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYxMDE1MTk1ODQ0WhcNMzcwMTIwMTk1ODQ0WjAbMRkwFwYD
VQQDDBBpbnRlZ3JhdGlvbl9tMzY1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEApWBRPJ2upm8vSw86u9SfuJ8ts5Eof79s71iRrxWV/YQ4M1oc5ZIwQy+P
38QNAayun4ZnVBJZghI7oEeu9BEfTdPDfbdXg7VyZr7qfnP9VDGiN50Cqx/FEmK4
NzejcyJLVOHJdoESx+owQbnsmMV89L9RdzP2u/qbZm4hMpzbj+/JDaM1BTW0iucY
vId2Aw6bSD6wUn1mA+y6NVCqS8PQcO54BQNAzvy4t1liN1EtntKxIvnh6RvtAN+6
Fh8YyNAMxEFn0pIxGveQLNvcjux5lpJqqypAvoHCiI9uP3j/F/qR9HeVTLbDhZod
xf0c6Vj4foU8J6hWnsp21s3tpFAjFEJlVHwbmo42Dl+78O4tQCbvoX7FfZmy4iAK
P7mmPqTEMHJEVhROyVd9lt2q977azqDEzGqFORDCeMHQW6k2HQ7ab9A5uon316fP
zfzs1ObibScihSBFQ4p2LV3SiPhH/xZfo9pm/1lsbAn7+J6VG4+S050X91tUmP5t
Ao1CFp5/qBoKb2wNPUMUkqnvG705CtWAAa22RR+T/C3drgRQYJ5O1aZ8cVP0KWdH
aTXXYdMbGEPXoFPikNSwhxuJ3EDTUG0nRVD5Df7dlYnCNwHIShaQgP7AyiqDPoSw
9P4NU/uJqcst2X79hufywPQqMNHfy9Tv0pvGs0Lv8kFT8mhjjTsCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAjeoLWgiZcu4FzAv6hRhx4TQnGpmFC3cz+NscaJZP4iUr
xrhHBJ7HgSjYmqLf+Y+A5NVPKAUf7XJ6LovJQzeN2t8gmcTuhnPVQLrSAdX9lbUi
uX3zR/aoZH5PEQCwzOpHICnKVFsS0t6f31mGP3OCOlNh5SolMKSfGefpBCtkqHDP
sIVl8DrC5QL5RjbpJJb1Fk6FyUdXKeOZ8R6doXTfekxzFqkeECENw48k0TQwp4wP
XHczcaum+uy1/nOCrUWV0mE/g3CJIyWWrkHoNvKOD9q7Apn174qkknGEXEAmZaQK
Dlyaa48a0ekpnxDWJTzSx4PfjCtiayqEcy0d/0bskg==
-----END CERTIFICATE-----
SignaturenkGATOR6zcwDPXIvxgSfpdybK+oT2n3+F0/jxi4368Z42KOn0MUz/hStMW3pdKQBxDW66OuSI9ehV16vNjnHZtd1+243aW1dyPpl/f5xGQq6aMBWjEtWD+uzInX38vQMebW2KOlExA8oPeW62God33LgI/f/mcej5PFUq8ieZuKC8QtuX/KpQ0fVDML9I7IFD3J28E95r87+SNPpbx4IOOdE38/YRmhM5BgEWMYG2gMDWUUpgQK46NgdE2GCq9zW3C4DzaMnclflgozETWR/sKERZePp4TnEDcacZ/Kz82lgtvr6f1FnEOQNxnXLJwInp/IS+z+paexuNVOYmkKX2ZKFFUx0wyFgIOyu4xIUHLT2IELlE7iyUuOnH+tTbwEfw7axdLJpAWvWF439pr2vUQec9XJyOfvfj1fnJm2O04VOJuSMezGdSNb96a7G8CWefW93SYfAaacV58d4HGO0u2WYXMdryXkStK5M+kmaRhrq+IDyFhm5t5DKKtAuN+thtTeimqrWV4qryoPyF1mWNc1lYGfLPhdP3x9MhbQFomIwgjs6xwEY/FALZNGKTkBRRXK5WhtkkDLN4S4UHyQTsofJwUfpAHJLlznco52nQyp/mwcULWaOF9D8gDOryMI2RQ4DhZhw5WRcGKZ4K1dOnhaPbvjvteGyfHALbWuVdok=
Signature digestsha512
Dependencies
Required Nextcloud versions >=32.0.0,<36.0.0
Minimum Integer bits32
PHP>=8.1.0
Microsoft 365 integration 0.2.2
Release Details
UpdatedOct. 16, 2026, 8:48 a.m.
Changelog
  • Fixed: the reconnect notification linked to a non-existent settings section (blank page); it now opens Connected accounts.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhRuMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYxMDE1MTk1ODQ0WhcNMzcwMTIwMTk1ODQ0WjAbMRkwFwYD
VQQDDBBpbnRlZ3JhdGlvbl9tMzY1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEApWBRPJ2upm8vSw86u9SfuJ8ts5Eof79s71iRrxWV/YQ4M1oc5ZIwQy+P
38QNAayun4ZnVBJZghI7oEeu9BEfTdPDfbdXg7VyZr7qfnP9VDGiN50Cqx/FEmK4
NzejcyJLVOHJdoESx+owQbnsmMV89L9RdzP2u/qbZm4hMpzbj+/JDaM1BTW0iucY
vId2Aw6bSD6wUn1mA+y6NVCqS8PQcO54BQNAzvy4t1liN1EtntKxIvnh6RvtAN+6
Fh8YyNAMxEFn0pIxGveQLNvcjux5lpJqqypAvoHCiI9uP3j/F/qR9HeVTLbDhZod
xf0c6Vj4foU8J6hWnsp21s3tpFAjFEJlVHwbmo42Dl+78O4tQCbvoX7FfZmy4iAK
P7mmPqTEMHJEVhROyVd9lt2q977azqDEzGqFORDCeMHQW6k2HQ7ab9A5uon316fP
zfzs1ObibScihSBFQ4p2LV3SiPhH/xZfo9pm/1lsbAn7+J6VG4+S050X91tUmP5t
Ao1CFp5/qBoKb2wNPUMUkqnvG705CtWAAa22RR+T/C3drgRQYJ5O1aZ8cVP0KWdH
aTXXYdMbGEPXoFPikNSwhxuJ3EDTUG0nRVD5Df7dlYnCNwHIShaQgP7AyiqDPoSw
9P4NU/uJqcst2X79hufywPQqMNHfy9Tv0pvGs0Lv8kFT8mhjjTsCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAjeoLWgiZcu4FzAv6hRhx4TQnGpmFC3cz+NscaJZP4iUr
xrhHBJ7HgSjYmqLf+Y+A5NVPKAUf7XJ6LovJQzeN2t8gmcTuhnPVQLrSAdX9lbUi
uX3zR/aoZH5PEQCwzOpHICnKVFsS0t6f31mGP3OCOlNh5SolMKSfGefpBCtkqHDP
sIVl8DrC5QL5RjbpJJb1Fk6FyUdXKeOZ8R6doXTfekxzFqkeECENw48k0TQwp4wP
XHczcaum+uy1/nOCrUWV0mE/g3CJIyWWrkHoNvKOD9q7Apn174qkknGEXEAmZaQK
Dlyaa48a0ekpnxDWJTzSx4PfjCtiayqEcy0d/0bskg==
-----END CERTIFICATE-----
SignatureZKwv0BMmPcHzxa0jZ39sRv7Gohm0iuJUHogNehq3dnWl9PxQJl64qIQHh3zCIl8hlGZuK5ERvbLFNs/DLGg8aqpbotVGO17lAzy136m4nAxYuscv2MKijcE8pBiaJSuPa0TwEIrR32JvHQwXMNMpk/qA2hc8JqIuB7gyNmp0nB+8Ltuq41v9TkntDeslFVJLuI/1/I+IZ/0TQqdyZEuV3Vlq/gt8kNgjvhw0p/vdONHPoq3uXSSnqIKxJMv6/KoYZvSvD3NLLYuJLhHUGpewP9x8jDvWeZoiOFEZvyRCqUMqtpUb4VPvba2zizF1gVID4RZ4G0jXbMrlpzyymCpac63oYJzmXmSWvaSoQl8qLAPfYaHYL4jJHBiHPr2fFNXNAOXkYxrHqEjYJwIQXy37vBlPIC+DYpcpMsZFRn7BW/qaPw9FNxJlaRtTRjZto2fhhz7onM8uzyA3tFNjVxL9yPHnqeWVQETk8E9zZuAI49+fJ4+35uVqb2v2n+2HRpHExswEu5tNCBeqQJRtuD1KIixhQqa4gRmYryRhEd/vS2WBjXJr6Gv2T2OK0prynolY0y9LH+WjAFoK811qy5idZCeZHZfFHam3qrEOZaru+dxSAdkCQFU/w5zJWdgCybm6dBaSp0CM1a5/FBNK/BvsnsChE+FhJAQ0HkLxM04dkbA=
Signature digestsha512
Dependencies
Required Nextcloud versions >=32.0.0,<36.0.0
Minimum Integer bits32
PHP>=8.1.0
Microsoft 365 integration 0.2.1
Release Details
UpdatedOct. 16, 2026, 7:43 a.m.
Changelog
  • When Microsoft rejects the refresh token (password change, revoked sessions, consent withdrawn) the user now gets a Nextcloud notification linking to the personal settings; it is cleared on reconnect. The Microsoft error (e.g. AADSTS50173) is written to the log.
  • README: setup guide for any tenant (Entra ID app registration, scopes, consent).
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhRuMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYxMDE1MTk1ODQ0WhcNMzcwMTIwMTk1ODQ0WjAbMRkwFwYD
VQQDDBBpbnRlZ3JhdGlvbl9tMzY1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEApWBRPJ2upm8vSw86u9SfuJ8ts5Eof79s71iRrxWV/YQ4M1oc5ZIwQy+P
38QNAayun4ZnVBJZghI7oEeu9BEfTdPDfbdXg7VyZr7qfnP9VDGiN50Cqx/FEmK4
NzejcyJLVOHJdoESx+owQbnsmMV89L9RdzP2u/qbZm4hMpzbj+/JDaM1BTW0iucY
vId2Aw6bSD6wUn1mA+y6NVCqS8PQcO54BQNAzvy4t1liN1EtntKxIvnh6RvtAN+6
Fh8YyNAMxEFn0pIxGveQLNvcjux5lpJqqypAvoHCiI9uP3j/F/qR9HeVTLbDhZod
xf0c6Vj4foU8J6hWnsp21s3tpFAjFEJlVHwbmo42Dl+78O4tQCbvoX7FfZmy4iAK
P7mmPqTEMHJEVhROyVd9lt2q977azqDEzGqFORDCeMHQW6k2HQ7ab9A5uon316fP
zfzs1ObibScihSBFQ4p2LV3SiPhH/xZfo9pm/1lsbAn7+J6VG4+S050X91tUmP5t
Ao1CFp5/qBoKb2wNPUMUkqnvG705CtWAAa22RR+T/C3drgRQYJ5O1aZ8cVP0KWdH
aTXXYdMbGEPXoFPikNSwhxuJ3EDTUG0nRVD5Df7dlYnCNwHIShaQgP7AyiqDPoSw
9P4NU/uJqcst2X79hufywPQqMNHfy9Tv0pvGs0Lv8kFT8mhjjTsCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAjeoLWgiZcu4FzAv6hRhx4TQnGpmFC3cz+NscaJZP4iUr
xrhHBJ7HgSjYmqLf+Y+A5NVPKAUf7XJ6LovJQzeN2t8gmcTuhnPVQLrSAdX9lbUi
uX3zR/aoZH5PEQCwzOpHICnKVFsS0t6f31mGP3OCOlNh5SolMKSfGefpBCtkqHDP
sIVl8DrC5QL5RjbpJJb1Fk6FyUdXKeOZ8R6doXTfekxzFqkeECENw48k0TQwp4wP
XHczcaum+uy1/nOCrUWV0mE/g3CJIyWWrkHoNvKOD9q7Apn174qkknGEXEAmZaQK
Dlyaa48a0ekpnxDWJTzSx4PfjCtiayqEcy0d/0bskg==
-----END CERTIFICATE-----
SignatureLznrfOO+tCgKsPCmgkRIDbziD6G/tORiyX5Nsc+UMVBDxz0aJ8IPQp/fYDQzKgvIqLMtmez9Qhzkf1JXUgsZ4w8vLJCv3QWggSnn7jVHXfiLwGH1MFlry91PK+PitVe8EcCjO76wSvYDajq4DgkIogkdMIEgbULhDHRA+/3QQO0b1sfd2HUJGVG3Vz58DV5bspvzG4enxNMgz142vNFQNmFDe3zxKHQtrmNagkWMYFg2n5r1nKW55IZD2RnwLmRqfmnWHRV7loYpl8BlZITCiV5p5H7teK/1h06rDxMwnWTamsPk5x7mSO9sfUTJyctivRZZYNqonw8S63EDSWlJlmXZ1GL8+hArDkoMXL13164GkCn1jggbSm8hQJTLMu34oz1T47Iuhh+mfRunw9ex8hCqLr6cnQzI9Da3Bt9DtAjf+s0euilY1YwQaWKVSrNICgnCZ0NQIfwZv1D3qEegs12T0axy6c2htTnm+k2kC1UA/5MBoXWF2loBACmZlqSnGfPlLhM4xnmNqEw7Wqk0kgnlV2Sq41TJAEO2DE3AOKqAQAeNbHBN4em06rft5xaveP6F9+qsowzm0uWBTl9AZ4voma4fmPghCbO9qFAqWfQiC0L2oGdNIoiOjF3vO2RH4DwhCYG5Jm2Jj45EPFfjSHYs1eDb7gRZPAKMM86f724=
Signature digestsha512
Dependencies
Required Nextcloud versions >=32.0.0,<36.0.0
Minimum Integer bits32
PHP>=8.1.0
Microsoft 365 integration 0.2.0
Release Details
UpdatedOct. 16, 2026, 7:36 a.m.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhRuMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYxMDE1MTk1ODQ0WhcNMzcwMTIwMTk1ODQ0WjAbMRkwFwYD
VQQDDBBpbnRlZ3JhdGlvbl9tMzY1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEApWBRPJ2upm8vSw86u9SfuJ8ts5Eof79s71iRrxWV/YQ4M1oc5ZIwQy+P
38QNAayun4ZnVBJZghI7oEeu9BEfTdPDfbdXg7VyZr7qfnP9VDGiN50Cqx/FEmK4
NzejcyJLVOHJdoESx+owQbnsmMV89L9RdzP2u/qbZm4hMpzbj+/JDaM1BTW0iucY
vId2Aw6bSD6wUn1mA+y6NVCqS8PQcO54BQNAzvy4t1liN1EtntKxIvnh6RvtAN+6
Fh8YyNAMxEFn0pIxGveQLNvcjux5lpJqqypAvoHCiI9uP3j/F/qR9HeVTLbDhZod
xf0c6Vj4foU8J6hWnsp21s3tpFAjFEJlVHwbmo42Dl+78O4tQCbvoX7FfZmy4iAK
P7mmPqTEMHJEVhROyVd9lt2q977azqDEzGqFORDCeMHQW6k2HQ7ab9A5uon316fP
zfzs1ObibScihSBFQ4p2LV3SiPhH/xZfo9pm/1lsbAn7+J6VG4+S050X91tUmP5t
Ao1CFp5/qBoKb2wNPUMUkqnvG705CtWAAa22RR+T/C3drgRQYJ5O1aZ8cVP0KWdH
aTXXYdMbGEPXoFPikNSwhxuJ3EDTUG0nRVD5Df7dlYnCNwHIShaQgP7AyiqDPoSw
9P4NU/uJqcst2X79hufywPQqMNHfy9Tv0pvGs0Lv8kFT8mhjjTsCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAjeoLWgiZcu4FzAv6hRhx4TQnGpmFC3cz+NscaJZP4iUr
xrhHBJ7HgSjYmqLf+Y+A5NVPKAUf7XJ6LovJQzeN2t8gmcTuhnPVQLrSAdX9lbUi
uX3zR/aoZH5PEQCwzOpHICnKVFsS0t6f31mGP3OCOlNh5SolMKSfGefpBCtkqHDP
sIVl8DrC5QL5RjbpJJb1Fk6FyUdXKeOZ8R6doXTfekxzFqkeECENw48k0TQwp4wP
XHczcaum+uy1/nOCrUWV0mE/g3CJIyWWrkHoNvKOD9q7Apn174qkknGEXEAmZaQK
Dlyaa48a0ekpnxDWJTzSx4PfjCtiayqEcy0d/0bskg==
-----END CERTIFICATE-----
SignatureQWxuiMN2+CUAW40ir1J/1BCwWvWxYyzwR8uFrtCr82a4ate8vrpf9D3RFrVe/EM3QaS40eE0mtEGJmfiCw5+G1TGm8hP/lHay+Ze21saaEswpZnR6NGxJutZfiWZYfNBPZQXArx5HNdfJLMFCGDCRmfswCXHS2AVDJnqct/zuz1X7QLaEbA4mEYMu7AY5LzMF2kh5YD702v/g+ra+jswvqcPbLXa0ClhMqYH4e8Jh0XQVN5cRwTUygVBXoLQGA/3+Vj0MSK5hmJ11GOPV8P6eiol8bFQSuoFWnAe93rHkPAS0wjRtlzggYUGA9038BoM/XYhIlv965lTjo91n/msA4SI77HSlEVMF3+yLQWCTRSisGxBlAuNJzOuG7rEjY2wDiyd977PAl3Ja913rWzFSAzRSKCS1mqxLT5Vb+6lv72gNJA5hQMkhhtxAq/oyoxqWhvKvJkOhK0+aejZi+J8yehoOoFf3mIRxUufwXyZAfaLDYr+2pvYygnP1qQn5WyjVKczY7mt6mfscKpHOzYpAAzI/AfcQcI7aedS3BRSfLHchHb4mx6H8FnvoB4V/taN5m+cH2jt4HuYwKqpCWRnehAvn4iOS/URHH8c5E9pLUvvN9kMLxDDQ2PlVpIWAFnKPDC+YtMcRzfdScErTt5PXwrd6J7E+UxBUKJ1IpWrTZo=
Signature digestsha512
Dependencies
Required Nextcloud versions >=32.0.0,<36.0.0
Minimum Integer bits32
PHP>=8.1.0