You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(calendar): Microsoft connection replaces existing account when ID token has no email claim #99
I've searched existing issues and this isn't a duplicate.
This is a reproducible bug in Calnode — not a configuration/setup question or a feature request.
What's the bug?
What happened
I connected one Microsoft 365 account to Calnode, then used “Connect another calendar” to connect a second Microsoft 365 account. The second connection replaced the first instead of appearing alongside it for conflict checking.
The Microsoft account picker let me select the second account, and the OAuth flow completed. Both accounts are in the same Entra tenant.
Workaround that resolved it
In the Entra app registration, I went to Token configuration → Add optional claim → ID token → email. After adding that claim and reconnecting the accounts, Calnode kept both connections.
I could not find this requirement in the deployment guide or .env.example.
Possible cause
The Microsoft calendar OAuth request asks for openid, offline_access, and Calendars.ReadWrite, but not profile or email. The connection code identifies accounts using preferred_username from the ID token, falling back to email. Microsoft requires the profile scope for preferred_username, and the email claim is not guaranteed to be present by default.
When both claims are absent, accountEmailFromIDToken returns an empty string. saveToken uses that value to find and delete an existing connection before inserting the new one, so a second account can replace the first.
Could the calendar OAuth flow request the identity claims it needs and avoid treating a missing account identifier as a valid deduplication key? A stable identifier such as tenant ID plus object ID would also avoid using a mutable email address as the account key.
Until the code handles this, documenting the ID token email optional claim would help other self-hosted operators connect multiple Microsoft 365 accounts.
Steps to reproduce
Connect one Microsoft 365 account to Calnode
Connect a second Microsoft 365 account.
The second connection replaced the first instead of appearing alongside it for conflict checking.
Calnode version / commit
edge (since 0.9 doesn't pull canEdit properly from MS Graph)
@KitKat31337 excellent report - root cause, code pointers, and a verified workaround all in one. Fixed on main:
Calnode now requests the profile and email scopes, so preferred_username/email arrive without any Entra token-configuration changes. Your workaround is no longer needed for new connections.
If a tenant still sends neither, the account key falls back to the stable tid:oid pair instead of an empty string.
And if even that is absent, the connect is refused with an actionable error instead of wiping the other connection. An empty identifier can never be a dedup key again.
Your second account should survive connecting alongside the first now. Thanks for the precise diagnosis - it made this a small fix.
@KitKat31337 the fix is on main and live in production. I don't have a second Microsoft 365 account here to prove it end to end - but you have the exact setup this bit. Could you verify?
Either pull main on your Docker deploy and reconnect both accounts, or if you'd rather not touch your instance, say so and I'll find another way to prove it. What I'm looking for: both accounts listed side by side after connecting the second (previously it replaced the first), with no Entra token-configuration changes needed.
I have some other temp fixes not engineered for proper merging in my local deployment still so will need to spin up a test environment. But I will get it done.
@KitKat31337 the fix is on main and live in production. I don't have a second Microsoft 365 account here to prove it end to end - but you have the exact setup this bit. Could you verify?
Either pull main on your Docker deploy and reconnect both accounts, or if you'd rather not touch your instance, say so and I'll find another way to prove it. What I'm looking for: both accounts listed side by side after connecting the second (previously it replaced the first), with no Entra token-configuration changes needed.
Activity
pullfrog commentedon Sep 25, 2026
shockalotti commentedon Sep 26, 2026
@KitKat31337 excellent report - root cause, code pointers, and a verified workaround all in one. Fixed on main:
profileandemailscopes, sopreferred_username/email arrive without any Entra token-configuration changes. Your workaround is no longer needed for new connections.tid:oidpair instead of an empty string.Your second account should survive connecting alongside the first now. Thanks for the precise diagnosis - it made this a small fix.
fix(calendar): keep distinct Microsoft accounts distinct without tena…
shockalotti commentedon Sep 26, 2026
@KitKat31337 the fix is on main and live in production. I don't have a second Microsoft 365 account here to prove it end to end - but you have the exact setup this bit. Could you verify?
Either pull main on your Docker deploy and reconnect both accounts, or if you'd rather not touch your instance, say so and I'll find another way to prove it. What I'm looking for: both accounts listed side by side after connecting the second (previously it replaced the first), with no Entra token-configuration changes needed.
KitKat31337 commentedon Sep 26, 2026
I have some other temp fixes not engineered for proper merging in my local deployment still so will need to spin up a test environment. But I will get it done.
Merge pull request #38 from distronode-corporation/sync/upstream-2026…
KitKat31337 commentedon Oct 2, 2026
This is confirmed fixed on main