Skip to content

Commit a0730fc

Browse files
committed
feat(outlook): add Calendars.ReadWrite.Shared for shared calendars
The calendar picker lists /me/calendars, which can include calendars other users have shared with or delegated to the account. Calendars.ReadWrite covers only the user's own calendars, so selecting a shared team calendar would 403 on both read and write. Calendars.ReadWrite is kept alongside it, not replaced: Graph documents it as the sole accepted permission for creating and updating events and for accept/tentativelyAccept/decline (all list "Higher: Not available"), so the .Shared scope does not subsume it. Added now rather than later because this PR already forces existing Outlook users to re-consent for Calendars.ReadWrite; deferring would cost them a second reconnect.
1 parent 801f442 commit a0730fc

3 files changed

Lines changed: 17 additions & 2 deletions

File tree

apps/sim/lib/oauth/oauth.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,10 +397,21 @@ export const OAUTH_PROVIDERS: Record<string, OAuthProviderConfig> = {
397397
icon: OutlookIcon,
398398
baseProviderIcon: MicrosoftIcon,
399399
/**
400-
* Calendars.ReadWrite was added to support the Outlook calendar operations.
400+
* Calendar scopes back the Outlook calendar operations. Both are required, and
401+
* neither subsumes the other:
402+
* - `Calendars.ReadWrite` is the only permission Graph accepts for creating and
403+
* updating events and for accept / tentativelyAccept / decline, which document
404+
* it as least-privileged with "Higher: Not available".
405+
* - `Calendars.ReadWrite.Shared` additionally covers calendars other users have
406+
* shared with (or delegated to) the account. The calendar picker lists
407+
* `/me/calendars`, which can include those, so without it selecting a shared
408+
* team calendar would 403 on read and write.
409+
*
401410
* Microsoft only grants newly-added scopes on a fresh authorization, so users who
402-
* connected Outlook before this scope existed must reconnect (re-consent) their
411+
* connected Outlook before these scopes existed must reconnect (re-consent) their
403412
* account before the calendar operations will work.
413+
*
414+
* @see https://learn.microsoft.com/en-us/graph/permissions-reference
404415
*/
405416
scopes: [
406417
'openid',
@@ -411,6 +422,7 @@ export const OAUTH_PROVIDERS: Record<string, OAuthProviderConfig> = {
411422
'Mail.Read',
412423
'Mail.Send',
413424
'Calendars.ReadWrite',
425+
'Calendars.ReadWrite.Shared',
414426
'offline_access',
415427
],
416428
},

apps/sim/lib/oauth/utils.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ describe('getCanonicalScopesForProvider', () => {
336336
expect(outlookScopes.length).toBeGreaterThan(0)
337337
expect(outlookScopes).toContain('Mail.ReadWrite')
338338
expect(outlookScopes).toContain('Calendars.ReadWrite')
339+
expect(outlookScopes).toContain('Calendars.ReadWrite.Shared')
339340

340341
const excelScopes = getCanonicalScopesForProvider('microsoft-excel')
341342

@@ -620,6 +621,7 @@ describe('getScopesForService', () => {
620621
expect(scopes.length).toBeGreaterThan(0)
621622
expect(scopes).toContain('Mail.ReadWrite')
622623
expect(scopes).toContain('Calendars.ReadWrite')
624+
expect(scopes).toContain('Calendars.ReadWrite.Shared')
623625
})
624626

625627
it.concurrent('should return empty array for empty string', () => {

apps/sim/lib/oauth/utils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ export const SCOPE_DESCRIPTIONS: Record<string, string> = {
238238
'Mail.Read': 'Read Microsoft emails',
239239
'Mail.Send': 'Send emails',
240240
'Calendars.ReadWrite': 'Read and manage Outlook calendar events',
241+
'Calendars.ReadWrite.Shared': 'Read and manage shared Outlook calendars',
241242
'Files.Read': 'Read OneDrive files',
242243
'Files.ReadWrite': 'Read and write OneDrive files',
243244
'Tasks.ReadWrite': 'Read and manage Planner tasks',

0 commit comments

Comments
 (0)