Monday, January 13, 2020

Salesforce oAuth 2.0 flows with Node Js Integration.

Tried to wrap all the oAuth flows in one place and able to complete it. Sharing it to help to accelearte
the progress of your poc/project. Please tweak below code to use any flow with node
Js integration.



var sf = require('node-salesforce');
var http = require('http');
var url = require('url');
var fs = require('fs');
request = require('request');
path = require("path"),
https = require('https'), 
fs = require('fs'),  
base64url = require('base64-url'), 
nJwt = require('njwt')
const jsdom = require("jsdom");
const { JSDOM } = jsdom;

let client_Id ='3MVG9d8..z.hDcPKuO0qkcUX0IqWf.AIAsDF_dkcBYL80RvSIKADdH0svSMV_gKhpJAh1HwI4tRNfimBeuwrO';
let client_Secret='67D3847C8AC12050F369457935933CD1205A120C70E69E370B169BFC8CC3AE27';
let  sfdcURL = 'https://login.salesforce.com/services/oauth2/authorize' ;
let  tokenurl = 'https://login.salesforce.com/services/oauth2/token' ;
  
//
// OAuth2 client information can be shared with multiple connections.
//
var express = require('express');
var app = express();
var oauth2 = new sf.OAuth2({
    loginUrl : 'https://login.salesforce.com',
    clientId:client_Id,
    clientSecret:client_Secret,
    redirectUri : 'http://localhost:8000/oauth2/code'
});
//
// Get authz url and redirect to it.

//
app.get('/oauth2/auth', function(req, res) {
  res.redirect(oauth2.getAuthorizationUrl());
});

app.get('/', function (req, res) {
    res.send(`<html>
    <head>
    <style>
    ul {
      list-style-type: none;
      margin: 0;
      padding: 0;
      overflow: hidden;
      background-color: #333333;
    }
    li {
      float: left;
    }
    
    li a {
      display: block;
      color: white;
      text-align: center;
      padding: 16px;
      text-decoration: none;
    }
    
    li a:hover {
      background-color: #111111;
    }
    </style>
    </head>
    <body>
    
    <ul>
      <li><a href="http://localhost:8000/jwt">JWT Flow</a></li>
      <li><a href="http://localhost:8000/oauth2/auth">Web server</a></li>
      <li><a href="http://localhost:8000/username_password">User name and Password</a></li>
      <li><a href="http://localhost:8000/useragent">User agent</a></li>
      <li><a href="http://localhost:8000/refresh">Refresh token flow</a></li>
      <li><a href="http://localhost:8000/samlassertionaccesstoken">SAML Assertion</a></li>
      <li><a href="http://localhost:8000/device">Device flow</a></li>
      <li><a href="https://asset-tokens.herokuapp.com/">Asset token flow</a></li>
    </ul>
    
    </body>
    </html>`);
    
});
app.get('/oauth2/code', function(req, res) {
  var q = url.parse(req.url, true);
  request({   url : tokenurl+'?client_id='+
  client_Id
    +'&redirect_uri='+
          'http://localhost:8000/'+'&grant_type=authorization_code&code='+
          q.query.code+'&client_secret='+client_Secret,  
         method:'POST' 
       },
       function(err, remoteResponse, remoteBody) {
       
         res.send(remoteBody);
       } 
     );

  
});

app.get('/useragent', function (req,res){  
request({   url : sfdcURL+'?client_id='+client_Id+'&redirect_uri='+'http://localhost:8000/'+'&response_type=token',  
        method:'GET' 
      }).pipe(res); 
   
} );

/**
*  Username Password oAuth Flow
*/
app.get('/username_password', function (req,res){  

  var sfdcURL = 'https://login.salesforce.com/services/oauth2/token' ;

 let uname='David@abc.com';
 let pwd='passwordonly'

  var upurl = sfdcURL+
  '?client_id='+ client_Id+
   '&grant_type=password'+
   '&client_secret='+client_Secret+
   '&username='+uname+
   '&password='+pwd ;
 

   request({  url : upurl,  
        method:'POST' 
      },
      function(err, remoteResponse, remoteBody) {
        var sfdcResponse = JSON.parse(remoteBody); 
        res.send(sfdcResponse);
      } 
    );  
} );


function encryptUsingPrivateKey_nJWTLib (claims) {
  var absolutePath = path.resolve("pykey.pem");   
    var cert = fs.readFileSync(absolutePath );  
  var jwt_token = nJwt.create(claims,cert,'RS256'); 
  console.log(jwt_token); 
  var jwt_token_b64 = jwt_token.compact();
  console.log(jwt_token_b64);
 
  return jwt_token_b64;     
};

function getJWTSignedToken_nJWTLib(){ 

  var claims = {
    iss: '3MVG9d8..z.hDcPKuO0qkcUX0IncIWJdRX90Yc5BHsYUmbsHh8eeRweKXys8392v5gcuiK1_WHF3_zSS9rfoX',   
    sub: 'david@lightning601.com',     
    aud: 'https://login.salesforce.com',
    exp: (Math.floor(Date.now() / 1000) + (60*3))
   
  }

  return encryptUsingPrivateKey_nJWTLib(claims);
}
app.get('/jwt', function (req,res){  
  
  var sfdcURL = 'https://login.salesforce.com/services/oauth2/token' ;
  
  var sfdcUserName = 'david@lightning601.com';
  var token = getJWTSignedToken_nJWTLib(); 
    
  var paramBody = 'grant_type='+base64url.escape('urn:ietf:params:oauth:grant-type:jwt-bearer')+'&assertion='+token ; 
  var req_sfdcOpts = {  url : sfdcURL,  
              method:'POST', 
              headers: { 'Content-Type' : 'application/x-www-form-urlencoded'} ,
              body:paramBody 
            };
        
  request(req_sfdcOpts, 
    function(err, remoteResponse, remoteBody) {
      res.send(remoteBody);
    } 
  ); 
} );

/**
 * Device Authentication Flow
 */
app.get('/device', function (req,res){  


  let deviceurl = tokenurl+
  '?client_id='+ client_Id+
   '&response_type=device_code&redirect_uri=http://localhost:8000/' ;
 

   request({  url : deviceurl,  
        method:'POST' 
      },
      function(err, remoteResponse, remoteBody) {
        
        console.log(remoteBody) ;
        var sfdcResponse = JSON.parse(remoteBody); 
        var jsondata={
          "verification_uri" : sfdcResponse.verification_uri,
          "user_code" : sfdcResponse.user_code,
          "device_code" : sfdcResponse.device_code
        
        };
        console.log('@@@@@@@',jsondata) ;
        var hrefs=`http://localhost:8000/devicePol?device_code=${sfdcResponse.device_code}`;
        var step2redirect=`<html><head>${JSON.stringify(jsondata)} </head><body><a href=${hrefs}> Post authorizing in different browser/device click here: Device flow step 2 </a> </body></html>`;
        console.log(step2redirect) ;
        //res.send(JSON.parse(JSON.stringify(step2redirect)));
//${jsondata}
        res.send(step2redirect);
      } 
    );  
} ); 

/**
 *  Keep polling till device is verified using code
 */

app.get('/devicePol', function (req,res){ 
  var device_code = req.query.device_code;
  console.log('@@@@@@@@@device code@@@@@@@@@@@@',device_code);
  var devicePolurl = tokenurl+'?client_id='+ client_Id+'&code='+device_code+'&grant_type=device';
 //console.log('@@@@@@devicePolurl@@@@@@@',devicePolurl)
   request({  url : devicePolurl,  
      method:'POST' 
    },
    function(err, remoteResponse, remoteBody) {
      
      //console.log(remoteBody) ;
      var sfdcResponse = JSON.parse(remoteBody); 
      res.send(sfdcResponse);   
    } 
  );  
} ); 

 

  app.get('/samlassertionaccesstoken', function (req,res){ 
   
    let assertionvalue='PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c2FtbDJwOlJlc3BvbnNlIHhtbG5zOnNhbWwycD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIiB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIERlc3RpbmF0aW9uPSJodHRwczovL2xpZ2h0NjAxZGVwLWRldi1lZC5teS5zYWxlc2ZvcmNlLmNvbT9zbz0wMEQ3RjAwMDAwNEIxRXYiIElEPSJfNzAyNjBhYzItMjg0MTI0MmMiIElzc3VlSW5zdGFudD0iMjAxOS0xMi0yNlQxOToyMDozMy4xODdaIiBWZXJzaW9uPSIyLjAiPjxzYW1sMjpJc3N1ZXIgeG1sbnM6c2FtbDI9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iPkF4aW9tPC9zYW1sMjpJc3N1ZXI';   tokenurl='https://light601dep-dev-ed.my.salesforce.com/services/oauth2/token';
    var samlurl = tokenurl+'?grant_type=assertion&assertion_type=urn:oasis:names:tc:SAML:2.0:profiles:SSO:browser&assertion='+assertionvalue;
    console.log(samlurl);
      request({   url : samlurl,  
         method:'POST' 
       },
       function(err, remoteResponse, remoteBody) {
         
         //console.log(remoteBody) ;
         var sfdcResponse = JSON.parse(remoteBody); 
         console.log(sfdcResponse)
         res.send(sfdcResponse);    
       } );
      });
      app.get('/refresh', function(req, res) {
       
        let refresh_token = '5Aep8613hy0tHCYdhyHUIj3Fev55mM_VcyWVY6uxHslAKE.FvcRJitylwr4jQhZcx9Hwo7SA6lbd6f.AWbyKtfE';
        var q = url.parse(req.url, true);
        request({   url : tokenurl+'?client_id='+client_Id+'&redirect_uri='+
                'http://localhost:8000/'+'&grant_type=refresh_token&refresh_token='+
                refresh_token,  
               method:'POST' 
             },
             function(err, remoteResponse, remoteBody) {
             
               res.send(remoteBody);
             } 
           );
      
  
    
  });
   
var server = app.listen(8000, function () {
  
});

No comments:

Post a Comment