POST Ajax call to Outlook API - Access is denied - javascript

I'm having a hard time sending a POST request to the Outlook API.
I'm working on my local machine and defined the redirectUrl to my localhost:port
My GET requests works:
var apiUrl = "https://outlook.office.com/api/v2.0/me/calendarview?startdatetime=" + startDateTime + "&enddatetime=" + endDateTime + "&$top=" + 10;
$.ajax({
type: 'GET',
url: apiUrl,
headers: {
"Authorization": "Bearer " + token
}
}).done(function (data) {
processResults(data);
}).fail(function (response) {
handleFailure();
});
but when I try to send a POST, I get this message :
Access is denied. Check credentials and try again.
and my code is:
var apiUrl = "https://outlook.office.com/api/v2.0/me/events";
var postData = {
"Subject": "Plan summer company picnic",
"Body": {
"ContentType": "HTML",
"Content": "Let's kick-start this event planning!"
},
"Start": {
"DateTime": "2019-01-15T11:00:00",
"TimeZone": "Pacific Standard Time"
},
"End": {
"DateTime": "2019-01-15T12:00:00",
"TimeZone": "Pacific Standard Time"
},
"Attendees": [
{
"EmailAddress": {
"Address": "myMail#gmail.com",
"Name": "Name Here"
},
"Type": "Required"
}
]
};
$.ajax({
type: 'POST',
url: apiUrl,
headers: {
"Authorization": "Bearer " + token
},
contentType: 'application/json',
data: JSON.stringify(postData)
}).done(function (data) {
processResults(data);
}).fail(function (response) {
handleFailure();
});
In both cases I use the same token, so it's probably not a login problem. I also allowed Calendars.ReadWrite in the app.
UPDATE
I cleared the cache, logged in, made a GET call, then made a POST call, then made a GET call again. Both GET calls works, so the problem is not the token or a cache problem.

The problem was on the authentication process, apparently on each request I have to specify the scope and it should include multiple permissions.
In the headers I found this:
x-ms-diagnostics: 2000008;reason="Access to this API requires the following permissions: 'Calendars.Read.All,Calendars.Read.Shared,Calendars.ReadWrite.All,Calendars.ReadWrite.Shared'. However, the application only has the following permissions granted: 'Calendars.Read,Calendars.ReadWrite'.";error_category="invalid_grant"
Even this is wrong, since Calendars.Read.All and Calendars.ReadWrite.All doesn't exist, it should be Calendars.Read and Calendars.ReadWrite.
The authentication request should look like this:
var authUrl = authServer +
"response_type=" + encodeURI(token) +
"&client_id=" + encodeURI(clientId) +
"&scope=" + encodeURI("https://outlook.office.com/Calendars.Read https://outlook.office.com/Calendars.Read.Shared https://outlook.office.com/Calendars.ReadWrite https://outlook.office.com/Calendars.ReadWrite.Shared") +
"&redirect_uri=" + redirectUrl +
"&state=" + stateParam;

Related

How to fix error in SharePoint while adding users in multi person or group field(people only)

I am trying to add multiple users in a multi person or group field(people only) in a Sharepoint list, But I am getting below error message
"An unexpected 'PrimitiveValue' node was found when reading from the JSON reader. A 'StartObject' node was expected."
I have used REST call to add items in Sharepoint list, items are being added properly when I remove multi people column in the rest call.
$scope.formData = { Title: $scope.codeNumber, SBMTestId:{ "results": [17,15] } }
var data = JSON.stringify($scope.formData);
var listName = "Test";
data = data.replace(/[{}]/g, '');
var datavalue = "{__metadata:{'type':'SP.Data.TestListItem'}," + data + "}";
$http({
url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/GetByTitle('" + listName + "')/items",
method: "POST",
headers: {
"Accept": "application/json;odata=verbose",
"Content-Type": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
"X-HTTP-Method": "POST"
},
data: datavalue
}).then(function (response) {
alert("Go on!");
}, function (response) {
alert("Something is wrong. Please try after sometimes");
});
The error message is below:
data:
error:
code:"-1, Microsoft.SharePoint.Client.InvalidClientQueryException"
message:
lang:"en-US"
value:"An unexpected 'PrimitiveValue' node was found when reading from the JSON reader. A 'StartObject' node was expected."
Try below JSON data format.
{
"__metadata": { "type": "SP.Data.MyList2ListItem" },
"Title": "RestApiCreated",
"MultiUsersId": { "results": ["12", "23"] }
}

How to get Microsoft Graph API Access token using ajax call

I am using Microsoft Graph API on a SharePoint Online page to get user's events from outlook calendar. I am using ADAL.JS. When I go to that page, the page redirected to MS login to get access token from Azure AD and come to page again.
I tried to get access token using ajax call, but token does not working. I tried to call that page in iFrame on another page, but it is not getting work in iFrame.
Can you anyone suggest if I can get access token in background so that page does not redirected to Microsoft login.
We tried below code, but it is giving error as "No mailbox was found that includes the specified identity: xxxxxxx"
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
requestToken();
});
var token;
function requestToken() {
$.ajax({
"async": true,
"crossDomain": true,
"url": "https://cors-anywhere.herokuapp.com/https://login.microsoftonline.com/tenantname.onmicrosoft.com/oauth2/v2.0/token", // Pass your tenant name instead of tenantname
"method": "POST",
"headers": {
"content-type": "application/x-www-form-urlencoded"
},
"data": {
"grant_type": "client_credentials",
"client_id": "****************************", //Provide your app id
"client_secret": "******************", //Provide your client secret
"scope": "https://graph.microsoft.com/.default"
},
success: function(response) {
console.log(response);
token = response.access_token;
document.getElementById('content').innerHTML = token;
}
})
}
</script>
<p id="content"></p>
Thanks,
When I test this in my online environment follow this thread, the request fail as it require user consent(official guideline).
So I grant the app Application Permissions and approve it by admin with admin consent url(https://login.microsoftonline.com/common/adminconsent?client_id=appid&state=12345)
Now, I could access the calendar view by below endpoint:
https://graph.microsoft.com/v1.0/users/userid/calendarView/delta?startdatetime=2018-12-04T12:11:08Z&enddatetime=2019-01-04T12:11:08Z
My test code:
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script type="text/javascript">
$(document).ready(function () {
requestToken();
});
var token;
function requestToken() {
$.ajax({
"async": true,
"crossDomain": true,
"url": "https://cors-anywhere.herokuapp.com/https://login.microsoftonline.com/tenant.onmicrosoft.com/oauth2/v2.0/token", // Pass your tenant name instead of sharepointtechie
"method": "POST",
"headers": {
"content-type": "application/x-www-form-urlencoded"
},
"data": {
"grant_type": "client_credentials",
"client_id ": "xxx", //Provide your app id
"client_secret": "xxx", //Provide your client secret genereated from your app
"scope ": "https://graph.microsoft.com/.default"
},
success: function (response) {
console.log(response);
token = response.access_token;
document.getElementById('content').innerHTML = token;
$.ajax({
url: 'https://graph.microsoft.com/v1.0/users/userid/calendarView/delta?startdatetime=2018-12-04T12:11:08Z&enddatetime=2019-01-04T12:11:08Z',
type: 'GET',
dataType: 'json',
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'Bearer '+token+'');
},
data: {},
success: function (results) {
console.log(response);
debugger;
},
error: function (error) {
console.log("Error in getting data: " + error);
}
});
}
})
}
</script>
Thanks for the solution. I am able to get it now.
Can you please let me know if I can get outlook tasks using same bearer token.
I tried same by below URL.
https://graph.microsoft.com/beta/me/outlook/tasks
But getting access denied error.
I also tried
https://graph.microsoft.com/v1.0/users/userid/outlook/tasks
but it says "Bad request"

Sendgrid integration with SAPUI5 app returns '400 Bad Request' on POST but works on Postman

I'm developing a cordova hybrid app that utilizes UI5 library. I need to be able to send as Email from the app so I decided to use Sendgrid API and, since I had issues with the NodeJS module, I'm creating an AJAX request. I've previously tested the request with Postman, being able to successfully send emails. But, as I tried to do the same request from the app, I've stumbled upon a status '400 Bad Request' without further information. Here goes the code snippet:
var settings = {
"async": true,
"crossDomain": true,
"url": "https://api.sendgrid.com/v3/mail/send",
"method": "POST",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer [REDACTED]",
"cache-control": "no-cache"
},
"processData": false,
"data": {
"personalizations": [
{
"to": [
{
"email": "myemail#gmail.com"
}
],
"subject": "Contato do app"
}
],
"from": {
"email": "anotheremail#gmail.com"
},
"content": [
{
"type": "text/plain",
"value": formatEmail //variable with the email text
}
]
}
}
$.ajax(settings).then(
function success(response, status) {
dialog.close();
if (status == 202){
MessageBox.confirm('Mensagem enviada com sucesso', {
actions: [sap.m.MessageBox.Action.OK],
onClose: function(sAction){
that.onNavBack()
}
});
} else {
MessageBox.error('Erro!');
}
},
function fail(data, status){
dialog.close();
MessageBox.error('Request failed. Returned status of ' + status + ' DEBUGDATA: ' + JSON.stringify(data));
}
);
I really can't figure out the reason as to why this happens because the snippet generated by Postman is very similar to my code. Any help would be highly appreciated!
Thanks in advance
usually HTTP 400 means bad request and it means that you're passing the wrong parameters to the HTTP POST request.

Calling Outlook API to Add event to outlook calendar using ajax call

I need to Add an event from my database to outlook calendar for which I have been trying to make an ajax call to the outlook auth API first which looks like this
$scope.authorizeOutlook = function () {
let redirect = 'http://localhost:51419';
let clientId = 'xxx';
var authData = 'client_id=' + clientId + '&response_type=code&redirect_uri=' + redirect + '&response_mode=query&scope=https%3A%2F%2Fgraph.microsoft.com%2Fcalendars.readwrite%20&state=12345';
debugger
$.ajax({
url: 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',
type: 'POST',
host: 'https://login.microsoftonline.com',
contentType: "application/x-www-form-urlencoded",
contentLength: "600",
data: authData,
success: function (response) {
debugger;
alert(response.status);
//alert("success");
},
error: function (response) {
alert(response.status);
//alert("fail");
}
});
}
But I am getting response status as 0. What does that mean? Where am I doing it wrong?
If you use Oauth2.0, you need to add " token-type: Bearer ".
Reference from:
Get access tokens to call Microsoft Graph

EWS - A token was not recognized in the JSON content

I try to send an email via EWS using Javascript and the REST API.
The OAuth is not the problem so far.
The problem is, if I try to send the email, the Server sends this response:
"{"error":{"code":"RequestBodyRead","message":"Invalid JSON. A token was not recognized in the JSON content."}" (taken from Chrome Debug Console).
Here my Javascript, where the error occurs:
function mailIsRaus(token) {
var gottenParam = JSON.stringify(token);
var jsonObj = JSON.parse(gottenParam);
var leToken = jsonObj['access_token'];
//This is the Token from Active Directory
leToken = "Bearer " + leToken;
var Message = {
"Message": {
"Subject": "TESTING REST API EWS",
"Body": {
"ContentType": "Text",
"Content": "IT WORKED. The EWS is working my friend."
},
"ToRecipients": [
{
"EmailAddress": {
"Address": "johndoe#something.com"
}
}
]
},
"SaveToSentItems": "true"
};
//eMailData = JSON.stringify(eMailData);
$.ajax({
type: 'POST',
beforeSend: function (request) {
request.setRequestHeader("Authorization", leToken);
request.setRequestHeader("Content-Type", "application/json");
},
data: Message,
url: 'https://outlook.office.com/api/v2.0/me/sendmail',
success: function (e) {
console.log('Email sent');
console.log(e);
},
error: function (message) {
console.log(message);
}
});
}
I strictly sticked to MSDN and now, I have no clue, why this error occurs.
If I comment out the "setRequestHeader" I get an error 401 unauthorized.
The token ist correct.
The scope is also correct.
Maybe I made an simple mistake in the "var Massage" or something...
I found the solution by myself.
I had to uncomment the following line of code to:
eMailData = JSON.stringify(eMailData);
Now it is working fine.

Categories

Resources