OAuth Authorization in pipeDrive callback using express framework - node.js

I created an app on sandbox.pipedrive.com in Marketplace Manager and then I created a callback which asked user to install the app which I setup in pipedrive.
If user allow to install they get redirected to my callback url in controller, my controller the code is :-
app.get('/pipedrive-callback', function(req, res) {
console.log('Success')
});
Now in function I want to exchange the auth token. Can anyone help me to solve this.

Can you try this?
You need to send another post request to their server after user is redirected to your callback. After the redirection you will get the authorization_code from the request params. You have to send that code in this post request to get the actual tokens that will allow you to do magic.
app.get('/pipedrive-callback', function (req, res) {
console.log('Success');
const authorization_code_from_service = req.query.code; // This will extract the authorization_code from the call back url.
//Here goes your step 4 + 5. You need to make a post request to their server now. For this, there is a library aka "request" in npm.
// Here is the link for that https://www.npmjs.com/package/request
const request = require("request");
const formData = {
"grant_type": "authorization_code",
"redirect_uri": "rediect url that you have set for your app",
"code": authorization_code_from_service
}
request.post({
url: 'https://oauth.pipedrive.com/oauth/token',
form: formData
},
function (err, httpResponse, body) {
//This will be the data that you need for further steps. Actual token, expiry time etc
console.log(body);
}
);
});
Npm link : https://www.npmjs.com/package/request

Related

NodeJS keycloak get user Informations

I have a web app with Angular in Frontend, NodeJS in Backend and Keycloak as an identity management solution.
My Frontend stores the access- and id-token. All the NodeJS routes are protected by keycloak (bearer only). That's why I intercepted on each of my requests the access-token as bearer in the header:
setHeaders: { Authorization: 'Bearer ' + this.oauthService.getAccessToken() }
Now I'm able to authorize the requests, but how I can get the user Information in Backend?
At least only an ID is necessary to make user-dependent DB requests. Is it possible to get any information from the access token?
Or does the NodeJS connector (keycloak-connect) get this information itself so that I can save it in a session? What is the best way to do it?
if I am not wrong, Access token is JWT token and you will be able to decode is as bellow:
const jwt = require('jsonwebtoken');
var tokendetails = jwt.decode(token)
Alternatively in Keycloakconnect middleware, you can get details as below
app.get('/apis/me', keycloak.enforcer('user:profile', {response_mode: 'token'}), function (req, res) {
​let tokenDetails = req.kauth.grant
​})
I have not tested so I am not 100% sure but I think you should be able to get username this way:
req.kauth.grant.access_token.content.preferred_username
Another way you could to something like this:
const request = require('request');
const options = {
url: `${authServerUrl}/realms/${encodeURIComponent(realm)}/account`;,
headers: {
'Authorization':'bearer '+token
}
};
request(options,function(error, response, body){
if(!error) {
let userProfile = body
}
})
Below resources might help you :
https://www.keycloak.org/docs/latest/securing_apps/index.html#_nodejs_adapter
https://github.com/v-ladynev/keycloak-nodejs-example/blob/master/lib/keyCloakService.js

How to post to salesforce web to lead using express.router()

I'm new to node.js, I have a salesforce web to lead form. I want to use express.Router() to post the form to salesforce. How do i format the
router.post( '/Contact', function(req,res,next) {
var body = req.body;
});
body? The form action = 'https://webto.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8'
and for example the OID = '1111111' ** I will use process.env.ORG_ID to get the real org ID.
Express isn't used for making a request but rather is a library for making Web APIs/Apps. If you need to make a request then you could use request which is very popular and wraps the Node Core API HTTP Library function, http.request().
Using request you can make your POST request to salesforce as such
let orgId = process.env.ORG_ID
request({
method: 'POST',
url: `https://webto.saleforce.com/servlet/servlet.WebToLead?encoding=UTF-8&OID=${orgid}`
}, (err, res, body) => {
if (err) {
return err
}
// Handle res/body per needs
})

node-oauth Yahoo API oAuth2 issue

I'm building an app with node.js and express.js. I'm using the node-oauth module to connect to yahoo so I can make get requests to the api. I keep getting the error below
{ statusCode: 401,
data: '{"error":{"#lang":"en-US",
"#uri":"http://yahoo.com",
"description":"Not Authorized - Either YT cookies or a valid OAuth token must be passed for authorization","detail":"Not Authorized - Either YT cookies or a valid OAuth token must be passed for authorization"}}' }
After trying for a while to figure out my problem, I'm asking the community to check out my code and see what I am doing wrong. Code included below.
"use strict";
// declare libraries
var express = require('express');
var router = express.Router();
var OAuth = require('OAuth');
// set yahoo key and secret
var yahooKey = '*****************************************************';
var yahooSecret = '*********************************';
var oauth2 = new OAuth.OAuth2(
yahooKey,
yahooSecret,
'https://api.login.yahoo.com/',
'oauth2/request_auth',
'oauth2/get_token',
null
);
router.get('/', function(req, res, next) {
var access_token = oauth2.getOAuthAccessToken(
'',
{'grant_type':'authorization_code', 'redirect_uri':'http://www.domain.com'},
function (e, access_token, refresh_token, results) {
// console.log(e);
// done();
});
// console.log(oauth);
oauth2.get(
'https://social.yahooapis.com/v1/user/circuitjump/profile?format=json',
access_token,
function (error, data, response){
if (error) {
console.error(error);
}
// data = JSON.parse(data);
// console.log(JSON.stringify(data, 0, 2));
// console.log(response);
});
res.render('index', { title: 'Express' });
});
// export route
module.exports = router;
Any help is greatly appreciated. My brain is fried ...
You seem to be missing some steps. I would direct you first to this guide:
https://developer.yahoo.com/oauth2/guide/flows_authcode/
First, from your starting path at '/', you need to redirect (302) the user to an authorization page (Step 2 of yahoo's guide). The oauth lib has a helper for you to generate the correct URL:
var location = oauth2.getAuthorizeUrl({
client_id: yahooKey,
redirect_uri: 'https://yourservice.com/oauth2/yahoo/callback',
response_type: 'code'
});
res.redirect(location);
What you just did there is you redirected the user's browser to yahoo's authorization page, where the user gets a dialog asking if they want to allow your service XYZ access to do stuff on the user's behalf. Upon clicking "Allow", yahoo will redirect the browser to your callback url (Step 3 of yahoo's guide), providing you with an authorization code in the query params. In this example you have hooked up at /oauth2/yahoo/callback
You can set that up like so (Step 4 of yahoo's guide):
router.get('/oauth2/yahoo/callback', function(req, res) {
// Aha now I have an authorization code!
var code = req.query.code;
oauth2.getOAuthAccessToken(
code,
{
'grant_type': 'authorization_code',
'redirect_uri': 'oob'
},
function(e, access_token, refresh_token, results) {
console.log('Now I have a token', access_token, 'that I can use to call Yahoo APIs!');
res.end();
});
});
I hope all of that makes some sense. I'll leave it as an exercise for you to figure out the refresh token (step 5). If you make it this far, that part should be easy :)
Edit
It looks like Yahoo also requires you to send your key and secret in a Authorization Basic header. You can generate this header and tell the oauth2 module to include it like so:
var encoded = new Buffer(yahooKey+":"+yahooSecret).toString('base64')
var authHeader = "Basic " + encoded;
var oauth2 = new OAuth.OAuth2(
yahooKey,
yahooSecret,
'https://api.login.yahoo.com/',
'oauth2/request_auth',
'oauth2/get_token',
{ Authorization: "Basic " + authHeader}
);

express passport-linkedin, making api requests

I'm using express and passport-linkedin. The authentication flow works fine, I can get the user's basic profile, and now I want to make an API request. /v1/people/~/connections, for example.
I've done some reading and trial and error, but all I get is Wrong Authentication Scheme or Internal Server Error.
I have the token and tokenSecret given to the verify callback of the LinkedInStrategy instance. How do I go from those to an authorized API request?
I use a 'isLegit' function running as middleware.
Example :
app.get('/api/mysecuredpage',isLegit,function(req,res){
res.render('mysecurepage');
});
function isLegit(req, res, next) {
// if user is authenticated in the session, next
if (req.isAuthenticated())
return next();
// if they aren't send an error
res.json({error:'You must be logged in to view information'});
}
EDIT :
To make a request to the linkedIn api, just set up your request with the following options :
var options = {
url: 'https://api.linkedin.com/v1/people/~/connections',
headers: { 'x-li-format': 'json' },
qs: { oauth2_access_token: user.access_token }
};
request(options,function(err,res,body){
console.log(body);
});
access_token is the name of the variable in your passport strategy, it could be different depending how you've set it up. basically, it's one of the fields of your authenticated user ;-)

nodejs copy cookies for internal app request

I am using Express 3.x and connect-mongo and the request module
My App has some middleware that ensures the external request has an access_token.
The access_token is checked and a some data is stored in the session.
I then want to make an internal call to a url within the application, but the internal call gets issued a new session (as its a separate request from the users browser request).
What I want to do is somehow copy the Express signed cookies across into the internal request() so that the middleware performs actions based on the original external session id.
I have tried passing a cookie jar into the request object but it doesnt seem to support signed cookies very well. Any ideas how I can do this?
/* Middleware to check access tokens */
app.all("/*", requireAuth, function(req, res, next) {
next();
});
function requireAuth(req,res,next) {
if ( req.query.access_token && !req.session ) {
// Check the access token and popualte stuff in the session
req.session.somedata = 'test';
// Then call a url internall to do something
// My issue is that this INTERNAL request below gets a new session Id
// so it itself returns Not Authorised as its hits the same code
request({
url: 'someurlinside-this-node-app',
method: "GET"
}, function _callback(err, serviceres, body) {
next();
});
}else{
res.send('Not Authorised');
}
}
Cookies are just another header so if you want to pass it along you should be able to do this:
var cookies = req.header('Set-Cookie');
request({
url: 'someurlinside-this-node-app',
method: "GET",
headers: { 'Set-Cookie' : cookies}
}

Resources