Access to Outlook RestAPI from an Outlook web Add-in - outlook-addin

I developed an Outlook Web Add-in that is working fine. It's a Taskpane that is available in compose mode of appointments and that collects event's data, adds a few ones and send that all to an API somewhere.
What I would like to do now is to subscribe the authenticated user to the Outlook Rest API in order to get notified when the event is deleted.
The subscription call should look like this one:
POST https://outlook.office.com/api/v2.0/me/subscriptions HTTP/1.1
Content-Type: application/json
{
#odata.type:"#Microsoft.OutlookServices.PushSubscription",
Resource: "https://outlook.office.com/api/v2.0/me/events",
NotificationURL: "https://myNotifAPI.azurewebsites.net/api/send/myNotifyClient",
ChangeType: "Deleted",
ClientState: "blabla"
}
I know I need to provide a valid Authentication Bearer Token when posting to the subscriptions URL so I tried to call this method in my Add-In:
_mailbox = Office.context.mailbox;
_mailbox.getUserIdentityTokenAsync(getUserIdentityTokenCallback);
In the function getUserIdentityTokenAsync, I call a WebApi Controller that validates my token and send it back to the Add-In:
AppIdentityToken token = (AppIdentityToken)AuthToken.Parse(rawToken);
token.Validate(new Uri(request.AudienceUrl));
return token;
I tried to use that token to Post to https://outlook.office.com/api/v2.0/me/subscriptions (using Postman) but I got a 401 saying:
reason="The audience claim value is invalid '<MyAddInURL>'.";error_category="invalid_resource"
Is it the right Token to use in that particular case or do I need to get another one? Any advices would be appreciated!
-- EDIT --
As suggested by #benoit-patra I tried to get a token using getCallbackTokenAsync instead of getUserIdentityTokenAsync but when I called https://outlook.office.com/api/v2.0/me/subscriptions I did receive a 403 :
"error": {
"code": "ErrorAccessDenied",
"message": "The api you are trying to access does not support item scoped OAuth."
}
As requested by #benoit-patra here's the Token content :
{
"nameid": "9d643d8c-b301-4fe1-83f7-bf41b1749379#57bcd3d9-685a-4c41-8c7d-xxxxxx",
"ver": "Exchange.Callback.V1",
"appctxsender": "https://localhost:44444/NewAppointment.html#57bcd3d9-685a-4c41-8c7d-xxxxxx",
"appctx": {
"oid": "3a8a4f92-a010-40bd-a093-xxxxxx",
"puid": "10033FFF9xxxxx",
"smtp": "max#xxxx.onmicrosoft.com",
"upn": "max#xxxx.onmicrosoft.com",
"scope": "ParentItemId:AAMkADE4NTk2MDNjLTI4NGEtNDZkNS1hMzg4LTE3MzI2NGJhZWRkZQBGAAAAAAD+YYA7CnMtRZsrwJ7l6m44BwCcSer9F+cXSrWNauuHQlZ7AAAAAAENAACcSer9F+cXSrWNaxxxxxxxx"
},
"iss": "00000002-0000-0ff1-ce00-000000000000#57bcd3d9-685a-4c41-8c7d-xxxxx",
"aud": "00000002-0000-0ff1-ce00-000000000000/outlook.office365.com#57bcd3d9-685a-4c41-8c7d-xxxx",
"exp": 1487087672,
"nbf": 1487087372
}

The previous answer is right, the error is because you are getting an item scoped token. Because previously Callback tokens only allowed a caller to call GetItem and GetItemAttachment REST APIs. We are making changes to the callback token so that clients can call REST of the APIs as well. The requirement is first you should have readWriteMailBox permission. Second get a REST callback token by providing isRest=true, like below
Office.context.mailbox.getCallbackTokenAsync({ isRest: true }, function (result))
The resulting token will have Mail.ReadWrite, Calendar.ReadWrite, Contacts.ReadWrite, and Mail.Send Scopes.
That said the isRest parameter is only supported for outlook mobile client right now. The work to support it on OWA and Outlook is in progress and we expect to release it by March.

You should use getCallbackTokenAsync() this is the JWT that will give you the AccessToken that will help you authenticating for the Outlook REST API
https://dev.office.com/docs/add-ins/outlook/use-rest-api
For your case, following the documentation, I think you will need ReadWriteMailbox to have sufficient permissions to register web hooks with Outlook REST API.
NOTE: I tried this on my add-in, I changed the add-in permission to ReadWriteMailbox but the JWT token when inspected with JWT.io still has for scope:ParentId=<itemid> which I think won't work. Tell me if you have the same problem here.

Related

Why does google-slides rest API ignore my api-key?

I'm trying to use the slides rest APIs to retrieve a presentation. I've tried to read my own simple presentation as well as the one in the samples. Right now I'm just trying to enter the following request.
https://slides.googleapis.com/v1/presentations/1EAYk18WDjIG-zp_0vLm3CsfQh_i8eXc67Jo2O9C6Vuc?fields=slides.objectId&key=*********
It doesn't matter if I pass my API key in or not, I consistently get the following issue
"code": 401,
"message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
I've done similar calls with the sheets API with no issues.
Any help explaining why my key is being ignored is greatly appreciated.
Thanks!
I will presume that your authentication access token has not expired. If it has, then you will need to refresh it using your refresh token.
If you do not have a refresh token, then you will have to go through the whole process of getting a new access token, and refresh token through OAuth2 authentication chain process.
Once all that is done, then you can make your slide download request.
I believe that your access token has expired, that is why you are getting the error message.
There are two main ways to authorize requests in Slides API : using API Keys or oAuth 2.0. Note that if you use an API Key the presentation must be public as explained in the documentation. If the presentation is not made public then you will not be able to use the API Key and instead you will need to use an oAuth 2.0 token.
Depending on your case scenario consider if you want to make your presentation public (in which case you can use API Keys) or not (in which case you will need to use oAuth 2.0).

Spotify API scopes not being recognized - not able to access user info

I am currently implementing a feature that you have the ability to save a song displayed on my iOS application (written with Swift) and this save button allows the song to be appended to the user's Spotify library. According to the Spotify Developer guide, the only scope required for this feature is user-library-modify when authorizing the app with the user. The url to be opened goes like this:
https://accounts.spotify.com/authorize/?client_id=my_client_id&response_type=code&scope=user-library-modify&redirect_uri=http://my_redirect_uri
This all works perfectly - the url is opened for the user to approve of the changes my app can make and the callback url with the required code is in the url is opened.
The next step in performing the required function is to get an exact token in order to use the api, which is done by calling the url:
https://accounts.spotify.com/api/token?grant_type=client_credentials&client_id=my_client_id&client_secret=my_client_secret&response_type=code&redirect_uri=http://my_redirect_uri&code=the_code_I_just_retrieved
With this url, a json file is returned with the new token and info with it, BUT when looking at the permitted scopes the token has, it is empty:
["scope": , "token_type": Bearer, "access_token": the_token_string, "expires_in": 3600]
Also, when I still try to perform the request it returns:
["error": {
message = "Insufficient client scope";
status = 403;
}]
In this lengthy process, what am I doing wrong? In case you are wondering, here are a few things I have tried without success:
1) Re-listing the scopes in the explicit token request
2)Adding utf-8 encoding to the redirect uri (not sure if this changes anything)
3)Adding many other scopes (although this clearly does not target the problem)
If anyone knows what I am doing wrong or has any suggestions as to what I should try, I am grateful for any helpful response!
I have found my mistake. The grant_type I have entered in my url set to client_credentials. However, this method of accessing the web API only permits the usage of publicly available data, not user info. Therefore, this method of authorization does not accept the parameter scope, forcing the spotify account service to ingnore this additional parameter. The other options DO allow accessing the user data, which are:
authorization_code, and refresh_token
The way this now has to be done is to:
1) Authorize the user regularly (with supplying the scopes) to retrieve the initial authorization code
2) Then, with this code, make the token request, but specifying the grant_type to be set as authorization_code
3) You have then received a valid access_token valid for one hour AND a refresh_token
4) Use the access_token when necessary and when this token expires, make another token request, but this time with the grant_type set as refresh_token and setting the code parameter to the previously gained refresh_token
5) You now have the next access_token and refresh_token
6) Repeat steps 4-5 until infinity

Issuing authenticated queries with Graphcool

I have successfully set up Graph.cool Auth0 authentication and created a User through Relay as described here.
Next I'd like to actually query graph.cool on behalf of this user. As a first step, I simply manually modified the Relay setup to specify the same auth token as was used to create the User in the first place (through the idToken on type AUTH_PROVIDER_AUTH0):
Relay.injectNetworkLayer(
new Relay.DefaultNetworkLayer(process.env.GRAPHQL_ENDPOINT, {
headers: {
Authorization: 'Bearer XXX.YYY.ZZZ',
},
})
);
However, the app stops rendering and I just get a console warning RelayPendingQueryTracker.js:153 Server response was missing for query Index. Any hints?
When calling the signinUser or createUser mutation, a Graphcool token is returned in the payload. https://www.graph.cool/docs/faq/graphcool-session-user-goij0cooqu
This is the token you need to use in the Authorization header instead of the Auth0 idToken.
Maybe it can also be a help to take a look at how we do it in the dashboard https://github.com/graphcool/dashboard/blob/master/src/views/LoginView/LoginView.tsx
Hope this helps!

API Authorization token error

I'm trying to use the Survey API.
When I try and use the form online to request an Authorization token I get a
error message.
Invalid or missing access token" error message.
The form to test the API calls also asks for a Client Secret code but yet it auto fills the box with the API Key.
Any help here would be nice.
I'm not sure if this is a bug on Survey Monkey's end either in the API or the form that tests the API.
You should have received a reply to this via email but I wanted to ensure this was answered here in case anyone else is having the same issue.
There was a bug on our API console preventing an access token being issued, this is now fixed.
The access token has to be copied into the "Authorization" parameter in the format "bearer ". e.g. if your access token is 'fdhjfu3cc8ss=', make sure the Authorization parameter has "bearer fdhjfu3cc8ss=" in it (with no quotes). Note that you need to use the Access Token returned, not the Authorization Code.

Tumblr API - OAuth issues: OAuth verifier and RESTConsole

Trying to obtain blog followers using Tumblr's API and RESTConsole in Chrome (not building an app, just want to check a request response).
I'm new to Tumblr's API and to RESTConsole, so two sources of possible error here.
I've already ...
Registered an app on Tumblr, receiving OAuth Consumer Key and Secret Key in the process.
Entered into REST Console my target: http://api.tumblr.com/v2/blog/{blogname}.tumblr.com/followers
Entered into REST Console's "Setup oAuth" window my OAuth Consumer Key and Secret Key, along with Tumblr's Request Token URL, Access Token URL and Authorize URL.
Approved read/write access to my application when prompted by Tumblr.
Entered the provided Token Key and Token Secret into REST Console's oAuth window.
When I attempt GET requests for follower counts (on my own blog or others'), Tumblr returns 401, "Not Authorized." My blog's preferences page lists the application I'm trying to use as having access.
I've tried this placing base-hostname:{blogname}.tumblr.com in REST Console's request parameters fields; I receive the same error. I tried running a different OAuth method from Tumblr's API (queued posts) and receive the same error.
Help?
Thanks. Let me know if this isn't clear.
Edit: Sorry, meant to add -- I think I may need Oauth Verifier. I haven't been able to find this token, or understand how to obtain it.
Edit (2): So, turns out Tumblr's API needs a comma separator from the REST Console. Thanks all.
''
Zack
$conskey = "CONSUMER KEY";
$conssec = "CONSUMER SECRET";
$tumblr_blog = "myblog.tumblr.com";
$to_be_posted = "This is the text to be posted";
$oauth = new OAuth($conskey,$conssec);
$oauth->fetch("http://api.tumblr.com/v2/user/following", array('offset'=>0) ,OAUTH_HTTP_METHOD_GET);
$result = json_decode($oauth->getLastResponse());
foreach($result->response->blogs as $key){
echo $key->url;
}
The code above will retrieve your followers list.
Hope this helps.