0

I'm writing an Outlook add-in and I'm having an issue with permissions. When the manifest.xml has ReadWriteItem permissions I can use the token to retrieve the message using a c# backend service. When I change the entry to ReadWriteMailbox I get a Unauthorised response and an associated error message Access is denied. Check credentials and try again.

I need the additional permission to be able to try to locate an email once it has been sent. The docs I have read indicate that ReadWriteMailbox is the highest permission level and includes the permissions afforded by ReadWriteItem. Is there something I'm missing here?

Clientside typescript to retrieve the token:

Office.context.mailbox.getCallbackTokenAsync({isRest: true}, async (result:Office.AsyncResult<string>) => {
    if (result.status === Office.AsyncResultStatus.Succeeded) {
        const request = {
            bearerToken : result.value,
            restUrl : Office.context.mailbox.restUrl,
            itemId : Office.context.mailbox.convertToRestId(itemId, Office.MailboxEnums.RestVersion.v2_0)
        }
        await axios.post(MAIL_SERVICE_POLL_URL, request);
     }
});

C# backend:

var outlookClient = _httpClientFactory.CreateClient();
outlookClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", item.BearerToken);
using (var response = await outlookClient.GetAsync($"{item.RestUrl}/v2.0/me/messages/{item.ItemId}?$select=isDraft" ))
{
    if (response.IsSuccessStatusCode &&
        JsonConvert.DeserializeObject<IsDraftModel>(await response.Content.ReadAsStringAsync()).IsDraft)
    {
        // response.StatusCode is Forbidden when ReadWriteMailbox
    }
}
David Clarke
  • 12,888
  • 9
  • 86
  • 116

1 Answers1

0

In case anyone else stumbles into this issue, this SO answer helped resolve it for me. Basically when changing to <Permissions>ReadWriteMailbox</Permissions> more specific urls are required when querying the Outlook rest api. Querying draft emails with ReadWriteMailbox permissions the url should be /v2.0/me/mailFolders/Drafts/messages/, not /v2.0/me/messages/ (which works with ReadWriteItem permissions):

using (var response = await outlookClient.GetAsync($"{item.RestUrl}/v2.0/me/mailFolders/Drafts/messages/{item.ItemId}?$select=isDraft" ))
{
    if (response.IsSuccessStatusCode &&
        JsonConvert.DeserializeObject<IsDraftModel>(await response.Content.ReadAsStringAsync()).IsDraft)
    {
        // response.StatusCode is now Ok when ReadWriteMailbox
    }
}

Similarly, when filtering on the SentItems folder, the filter url is:

var filterUrl = $"{item.RestUrl}/v2.0/me/mailFolders/SentItems/messages?{filter}";
David Clarke
  • 12,888
  • 9
  • 86
  • 116