SP.Utilities.Utility.SendEmail access denied - sharepoint-online

I am using CSOM("SP.Utilities.Utility.SendEmail") to send email to the members of my site collection.
var deferred = $q.defer();
$http({
url: webUrl + "SP.Utilities.Utility.SendEmail",
method: "POST",
data: data,
headers: {
"Accept": "application/json;odata=verbose",
"X-RequestDigest": xdigestdata.d.GetContextWebInformation.FormDigestValue,
"content-Type": "application/json;odata=verbose"
}
}).then(function(result, status) {
console.log("Email Sent!");
deferred.resolve(result);
}, function(result, status) {
console.log("sendEmails: " + JSON.stringify(result2))
deferred.reject(result);
});
I got no problem using it, I wass able to send and receive the email I am sending but I got problem when the application I created was being used by a user that only has "Members" permission. I am getting the following error. Note when I switch back my test account as Site Owner I was able send again my email. Is there any specific permission that I need to give to members group to send email or is there any specific list that members group should have access to, to send email?
"-2147024891, System.UnauthorizedAccessException"
message
:
lang
:
"en-US"
value
:
"Access denied. You do not have permission to perform this action or acc

Users need to have the Manage Alerts - Manage alerts for all users of the Web site Permission on the site level to send emails. See this and this for more details on the Manage Alerts permission.
You will need to enable this for the group or users in Permission Levels : Edit Permission Level

Related

Microsoft Graph API, DELETE request response Error code 403 ""Access is denied. Check credentials and try again."

I am working on a Microsoft Graph API app where i want to delete email messages from the inbox.
I do that by first getting the emails, putting the id from each email in an array and for each id in that array making a delete request to remove it from the inbox.
When I try and run my code i get the error
Error: Server responded to *request link* with status code 403:
{
"error": {
"code": "ErrorAccessDenied",
"message": "Access is denied. Check credentials and try again.",
"innerError": {
"request-id": "*request id*",
"date": "2020-06-03T09:12:06"
}
}
}
When making the delete request I pass in the same Access Token that i use to make the get request for getting the email data.
Here is my code:
// This is only the code for the delete request, passing the Access Token works aswell as passing the IDList array. It loops trough all the id's and tries to make a request. But the request fails
removeEmail(IDList, AccessToken);
function removeEmail(idList, accessToken) {
idList.forEach(ID => {
var deleteEmails = request('DELETE', `https://graph.microsoft.com/v1.0/me/messages/${ID}`, {
headers: {
'Authorization': `Bearer ${accessToken}`
}
});
deletedEmails = JSON.parse(deleteEmails.getBody('utf8'));
console.log(deleteEmails);
});
}
How can this be fixed so that it removes the messages from the inbox without any problems?
Thanks in advance!
What permissions have you added to your Microsoft Graph API app?
Deleting an email requires Mail.ReadWrite - https://learn.microsoft.com/en-us/graph/api/message-delete?view=graph-rest-1.0&tabs=http
On the other hand, getting a list of messages works with the following permissions - Mail.ReadBasic, Mail.Read, Mail.ReadWrite - https://learn.microsoft.com/en-us/graph/api/user-list-messages?view=graph-rest-1.0&tabs=http#permissions
To be able to both read and delete email messages, you need Mail.ReadWrite added to your app.

Change from address while sending email via gmail API

I want to send a mail via the gmail API. I have a function that works so far, but my problem is that I don't know how to change the from address. My mails are always send as the user I authorized the API access with.
So I want my mails sent from from.mail#example.com in the following code:
function sendSampleMail(auth, cb) {
let gmailClass = google.gmail('v1');
let emailLines = [];
emailLines.push('From: from.mail#example.vom');
emailLines.push('To: to.mail#example.com');
emailLines.push('Content-type: text/html;charset=iso-8859-1');
emailLines.push('MIME-Version: 1.0');
emailLines.push('Subject: this would be the subject');
emailLines.push('');
emailLines.push('And this would be the content.<br/>');
emailLines.push('The body is in HTML so <b>we could even use bold</b>');
const email = emailLines.join('\r\n').trim();
let base64EncodedEmail = new Buffer.from(email).toString('base64');
base64EncodedEmail = base64EncodedEmail.replace(/\+/g, '-').replace(/\//g, '_');
gmailClass.users.messages.send(
{
auth: auth,
userId: 'me',
resource: {
raw: email
}
},
cb
);
}
I don't know if it's even possible to send with different from-mails via the google API. I could not find any information about that and no solutions.
You can't send emails (or make any request) as a different user from the authenticated user because you don't have any permissions to impersonate it.
If you're a G Suite administrator, you can use a service account [1][2] with domain wide delegation [3], which will grant you access to impersonate any gmail account from your domain. You can create a service account on Cloud Platform after selecting a project, from where you'll be able to download the credentials JSON file. And use the JSON Web Tokens methods [4] to authorize your application using the service account JSON.
[1] https://cloud.google.com/iam/docs/service-accounts
[2] https://cloud.google.com/iam/docs/understanding-service-accounts
[3] https://developers.google.com/admin-sdk/directory/v1/guides/delegation
[4] https://github.com/googleapis/google-auth-library-nodejs#json-web-tokens

ServerError: AADSTS50058: A silent sign-in request was sent but none of the currently signed in user(s) match the requested login hint"

SSO fails "ServerError: AADSTS50058: A silent sign-in request was sent but none of the currently signed in user(s) match the requested login hint"
when I use same account for both work and personal azure account.
I have 2 AAD accounts (one is with my work account and the other one is personal account but both attached with same email and both are using same credentials). When I use msal.js library for single sign on application. It takes me to my work account where it asks me to validate the credentials (using standard pop up dialog) by giving full email address and does not authenticate properly even if give right credentials. As I need to login using my personal account
I expect this should validate using my ad alias#company.com credentials. I tried with different account option in the dialog, but it fails and shows up same full email account.
How can I use my adalias#company.com as a default user id?
Here are the piece of the code I am trying to use.
var msalConfig = {
auth: {
clientId: 'xxxxxxxxxx', // This is your client ID
authority: "https://login.microsoftonline.com/{tenantid}" // This is tenant info
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: true
}
};
var graphConfig = {
graphMeEndpoint: "https://graph.microsoft.com/v1.0/me"
};
var requestObj = {scopes: ["user.read", "email"]};
// Is there a way to change here to get the required user id?
var myMSALObj = new Msal.UserAgentApplication(msalConfig);
// Register Callbacks for redirect flow
myMSALObj.handleRedirectCallbacks(acquireTokenRedirectCallBack,
acquireTokenErrorRedirectCallBack);
myMSALObj.handleRedirectCallback(authRedirectCallBack);
function signIn() {
myMSALObj.loginRedirect(requestObj).then(function (loginResponse) {
// Successful login
acquireTokenPopupAndCallMSGraph();
}).catch(function (error) {
// Please check the console for errors
console.log(error);
});
}
Here is the error message I get:
ServerError: AADSTS50058: A silent sign-in request was sent but none of the
currently signed in user(s) match the requested login hint
The expected result is seamless login to other application.
If you want to provide a login_hint to indicate the user you are trying to authenticate try:
var requestObj = {scopes: ["user.read", "email"], loginHint: "adalias#company.com"};
Reference https://github.com/AzureAD/microsoft-authentication-library-for-js/wiki/FAQs#q10-how-to-pass-custom-state-parameter-value-in-msaljs-authentication-request-for-example-when-you-want-to-pass-the-page-the-user-is-on-or-custom-info-to-your-redirect-uri

Get permissions on user's Google Calendar to use them from server

The requirement:
I have to develop the following feature: user clicks a button on my site and then a Google's dialog is popping-up asking for permissions on his calendar for my application. If the user accepts that - my server application (let's say NodeJS) should be able to read his events any time (not only for 30 days).
Here is what I've tried:
I was following these tutorials (both NodeJS and Browser) https://developers.google.com/calendar/quickstart/nodejs
NodeJS tutorial gives me permissions on my account (while I need the users to give permissions on their accounts).
Browser tutorial pop-ups the dialog and asks for permissions. If user accepts the request, then it ends up with permission on the calendar only for 1 hour (so even if I can use the token from my server it doesn't solve the problem). To check it just try to print the Promise's result from handleAuthClick by modifying it a bit
gapi.auth2.getAuthInstance().signIn().then(res => {console.log(res)});
Look at the expires_in (or expires_at) in the printed result:
{
"El": "117770076845340691060",
"Zi": {
"token_type": "Bearer",
"access_token": "ya29.Glb...zr8Yx",
"scope": "https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/userinfo.email openid email profile",
"login_hint": "AJDLj...WlQ",
"expires_in": 3600,
"id_token": "eyJhvGciO...sHxw6HcA",
"session_state": {
"extraQueryParams": {
"authuser": "1"
}
},
"first_issued_at": 1528384733411,
"expires_at": 1528388333411,
"idpId": "google"
},
"w3": {
"Eea": "117770076845340691060",
"ig": "Bryan Gray",
"ofa": "Bryan",
"wea": "Gray",
"Paa": "https://lh3.googleusercontent.com/-zQ8KN1XZtJI/AAAAAAAAAAI/AAAAAAAAAAA/AB...e/s96-c/photo.jpg",
"U3": "alex#khealth.ai"
}
}
Access tokens are only usable for an hour you need a refresh token which will allow you to request a new access token when ever you need one. To do that you need to request offline access.
gapi.signin2.render('glogin', {
'class': 'g-signin',
redirect_uri: 'postmessage',
onsuccess: signInCallback,
cookiepolicy: 'single_host_origin',
accesstype: 'offline',
theme: 'dark'
});
Code from this sample Google oauth2

GitHub REST API to create Issues with creator parameter

NodeJS APP:
I try to create github issues from my nodeJS application using Github REST API "https://github.com/api/v3/repos/{owner}/{repo}/issues" with the following parameter and Token. I am passing the parameter "creator" to display who created/commented this issue. But it is displaying the owner of the gitHub Access token as the creator of the issue. How to fix this
request.post({
url: githubApiEndpoint + "/repos/" + options.orgName + "/" + options.repoName + "/issues",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + options.accessToken
},
body: JSON.stringify({
title: "creating issue",
body: "description of issue",
creator: "username",
labels: ["question"]
})
}, callback);
As per the documentation you cannot. creator is no valid parameter. Besides that your example is syntactically incorrect.
You can't. OAuth protocol aims to provide a way to do actions in the name of a specific user, the user who owns the token you get.
So, if you create an issue, the author/creator will be the token owner. You cannot do actions in behalf of another person if you don't have his token

Resources