How to get userId from access token for Gmail OAuth2.0 - oauth-2.0

What I'm trying to do
I'm trying to create a web app that would fetch emails from a user's Gmail. I understand that I would require authentication via Google OAuth 2.0.
What I'm trying to do is setting a watch() request on an inbox. Then, when the watched inbox gets an email, I want to get notified. I'm using Google's PubSub API.
What I've done
I followed the steps given in the Gmail OAuth documentation, but am confused as to how to store multiple access tokens for multiple users.
So when the user first logs in using their Gmail account, I generate a code which I exchange for an access token. Then I store this in a database. However, when I get notified about an email, I only receive from the API the user's email address. I would like to do some further API calls for this user. So now I would need to retrieve the token for the specific user. But...
The problem
... How do I store access tokens by email? I only have access to their token once they login/authorize. Is there any way of retrieving the email address from an access token? I could then store the access tokens as key-value pairs of <email address>-><access token>.

You can do a Users: getProfile-request immediataly as they log in for the first time, like so:
GET https://www.googleapis.com/gmail/v1/users/me/profile?access_token=<ACCESS_TOKEN_OF_THE_LOGGED_IN_USER>
Response:
{
"emailAddress": "example#gmail.com", // Here is the user's email address.
"messagesTotal": 6446,
"threadsTotal": 4495,
"historyId": "570232" // Here is the current historyId of his account.
}
Then, when you get a push request via watch(), you can use the historyId in the response above to see what has happened.

Related

Send mail via Microsoft Graph as Application (Any User)

We recently migrated from on premise exchange to Microsoft 365 and I'm wanting to turn on 2FA for all users (Enable security defaults). However this disables SMTP authentication which we have been using for sending mail from a distribution group address. (Not achievable via EWS as it doesn't have a physical mailbox)
From what I can see, the only method would be to set up a SMTP relay or send via Microsoft Graph.
I've tried going down the Microsoft Graph route, and here's what I've got so far.
Create application in Azure Active Directory > App Registrations
Add Mail.Send and User.Read.All (Application, not delegated) API Permissions and have granted Admin Consent.
Request token using the following
Generate auth code via https://login.microsoftonline.com/{AzureApi.TenantId}/oauth2/v2.0/authorize?response_type=code&client_id={AzureApi.ClientId}&redirect_uri={WebUtility.UrlEncode(RedirectUrl)}&scope=offline_access%20Mail.Send%20User.Read.All [using admin credentials]
Post request to https://login.microsoftonline.com/{AzureApi.TenantId}/oauth2/v2.0/token with the following request body.
{ "grant_type": "authorization_code", "client_id": "AzureApi.ClientId", "client_secret": "AzureApi.ClientSecret", "code": "insert auth code", "redirect_uri": "insert redirect URL" } to get the bearer token
Once I have the token, Now I perform a request to send some mail
https://graph.microsoft.com/v1.0/users/{fromAddress}/sendMail
This works when fromAddress is the email address of the user that requested the token, however when I try to send from a different address it gives this error {"error":{"code":"ErrorAccessDenied","message":"Access is denied. Check credentials and try again."}}
I even tried adding the SendAs permission to the token user for the mailbox I was trying to send as, but this didn't make any difference. Regardless - I want to be able to send as any user without delegating permissions to each mailbox.
Glad of any help. Thanks!!
The behavior you are getting is expected because you are using delegated permissions - authorization code flow. This flow will not allow your app to send email as any user except the user that is signed in/"requested the token".
In your case you can add the permissions as application permissions and then use Client Credentials flow with either secret or certificate(more secure). Your token request will look like the Get Access Token Section. Note that this means two things:
Your app will need to be secured on server side to protect the credentials.
An admin will need to consent to the permissions on Azure AD
Your app will be able to send emails as any user in your tenant so it is very sensitive.
With application permissions you only need Mail.Send

chat.postMessage xoxb token that works to post messages to all users in all workspaces

I use: https://www.npmjs.com/package/#slack/interactive-messages and https://www.npmjs.com/package/#slack/events-api for my Slack/Node.js bot. I catch any interaction to the bot using:
slackEvents.on(‘message’, (message: any, body: any) => …);
Before Slack users can chat with the bot they must integrate it into their workspace using: https://api.slack.com/docs/sign-in-with-slack which is available in my website for logged on users. On successful response I get two different access tokens:
xoxb based auth tokens from bot_access_token (if im correct this is workspace based access token)
xoxp based auth tokens from access_token (if im correct this is user based access token)
I store above tokens in the users record in my database. I use the xoxb token to execute methods from my bot engine which also has access to the database, methods such as: https://api.slack.com/methods/chat.postMessage
However, once the bot is integrated the bot is exposed to many users. Users that did not do the 'Sign in with slack'-process and does not have any xoxp or xoxb tokens in their user record in the database. What xoxb token can I use to chat.postMessage to them?
I see there is an OAuth Access Token (xoxp) and Bot User OAuth Access Token (xoxb) in the Slack API Bot Dashboard under ‘OAuth & Permission’ link. Is this a master xoxb token that can be used to chat.postMessage to all users in Slack in any workspace that integrated my app?
Tokens are always bound to one workspace and one user. There is no "master" token that would work for multiple workspaces.
However, an app usually only needs one token per workspace, which it receives during the on-time installation process (as you described). You obviously want to store that token (bot user token and access token if you have a bot user) in your app database.
Provided your app has the necessary scopes it can use that token for all API calls involving that workspace. e.g. you can send messages to any user with the same token. For this to work with different workspaces all you need to do is match the team ID from the incoming request to the right token for your response.
To send a direct message to any user just use the ID of the user as channel with chat.postMessage. You get that ID in the message event.
Since you have a bot user I would recommend you to use the bot token whenever possible and the access token only in cases where the bot token does not work (not all API methods work with bot token).
A detailed description of the differences between those tokens can be found here.
See also How to get a workspace agnostic Slack bot token?

Firebase HTTP function accessing userID?

Couple of questions about firebase functions.
I have a function that needs to verify that the current user is authenticated, and then use their userId to store some data and associate it to them.
How do i access userId and validate auth in the functions?
Where can i get the token that needs to be sent to server through http header?
To get started, look at the official sample code available in GitHub that shows how to protect an endpoint. You'll see that it takes a token from Firebase Authentication for the currently authenticated user using getIdTokenWithCompletion. The function uses the Firebase Admin SDK to verify the token. The result of verification is a DecodedIdToken object, which contains various properties, including the user's uid.

Getting Video Analytic Information without Credentials

I need to access several YouTube channels for my job to pull analytical data and export it to a database. The problem, is that this requires using OAuth, which would be fine except I don't know the controlling person's username/password. She probably won't give me her credentials since it's personal.
Is there a way to do this without explicitly using her username/pass? Like, she tried making me a content owner, but I still can't authorize this level of information.
This is exactly the reason why OAuth was created, to make requests on behalf of a user without their username and password.
Have that user generate an access token. Here are the Google Docs. In a nutshell:
Have your user send a post request to https://accounts.google.com/o/oauth2/token with your app key. The response should look something like:
{
type: "oauth",
token: "XXXXXXX"
}
Then, make an API request on behalf of that user with their token by passing in the token returned from the previous step as value for the Bearer filed for any web request to the YouTube API. This will allow you to perform an authenticated request without explicitly knowing the user's username and password.

Twitter aouth API: Do I have to authenticate user every time?

So after a user has logged in with his twitter account on my website, and I got the token and secret, when he moves to other page, do I have to generate the new token and secret in order to do something e.g. get his twitter username or I can just make a simple request to api.twitter.com/1/account/verify_credentials.json appending all the data I got on the page before, and it will work?
When you got the token and secret of the user, you can make requests to twitter on behalf of that user.
So to use these token and secret for future use you should save it in some datastore along with the user's credentials. As long as you append these information to the request header you will able to make requests on behalf of twitter user without asking anymore permission from the user itself.
Reference: https://dev.twitter.com/docs/auth/authorizing-request
Cheers

Resources