Unable to request click.manage or click.send scopes in Docusign click API - docusignapi

I'm attempting to authenticate a call to Docusign's Click API using the Node SDK. I'm importing the ApiClient through the docusign-click as import { ApiClient } from 'docusign-click';.
My API setup looks like this:
this.apiClient = new ApiClient({
basePath: this.configService.get('DOCUSIGN_CLICKWRAP_BASE_PATH'),
oAuthBasePath: '',
});
and I'm requesting a JWT like this:
const response = await this.apiClient.requestJWTUserToken(
this.configService.get('DOCUSIGN_INTEGRATOR_KEY'),
this.configService.get('DOCUSIGN_USER_ID'),
['click.manage'],
Buffer.from(
this.configService
.get<string>('DOCUSIGN_PRIVATE_KEY')
.replace(/\\n/g, '\n'),
),
30,
);
When I try to request a JWT this way, I get Error: Bad Request. However, when I replace ['click.manage'] with ['signature'] the JWT is generated, so I know the rest of the call is fine.
Is there something else I need to do to allow me to request a click API scope and call to the click API?

Your consent request should also include click.manage and click.send. These are two separate things.
To get consent you need to build a URL that looks like this:
https://account-d.docusign.com/oauth/auth?redirect_uri=[Redirect URL in IK]&scope=click.manage%20click.send&client_id=[YOUR IK]&response_type=code
And simply go to this URL in the browser.
Then make the request for JWT again and it should work.

Related

Docusign run code grant steps programmatically in node?

New to docusign and have been reading the docs, and I can't seem to get around these problems.
Per the docs it says that gets a code getAuthorizationUri() which can then be used by generateAccessToken() to get a token. After that, the token can be used to explore the API with other methods.
I'm stuck in two places: First I configured my get Authorization like this (typescript)
import { ApiClient } from 'docusign-esign'
const apiClient = new ApiClient()
const url: string = apiClient.getAuthorizationUri(
config.docusign.INTERGRATION_KEY,
['signature'],
'http://localhost/',
'code',
'ready'
)
console.log(url)
I get the url fine, but it is always starts with acccounts.docusign as opposed to the required account-d.docusign that's required because my app is in dev.
Secondly, I can't figure out how to transition that URL into a code programtically. Yes, I can copy and paste it from the browser URL (as in the instruction videos), but obviously my next step is to run something like:
async getToken(authCode){
const token = await apiClient.generateAccessToken(
INTERGRATION_KEY,
SECRET_KEY,
authCode
)
console.log(token)
return token
}
To change authentication from prod to demo, you need to make this call:
apiClient.setOAuthBasePath("account-d.docusign.com");
You may also want to change the URL for API calls if you use this later like this:
apiClient.setBasePath("https://demo.docusign.net/restapi");
I suggest using an OAuth npm package and not doing this yourself.
See how it's done in the quickstart (Pick Node.js and Auth Code Grant)

How do I get the access token without using the browser

When I go to the following URL in the browser with my own client_id:
https://account-d.docusign.com/oauth/auth?response_type=token&scope=signature&client_id=6d1a8594-xxxx-xxxx-xxxx-878e593de049&state=a39fh23hnf23&redirect_uri=http://localhost:8888/auth
I need to login and afterwards I get redirected to:
http://localhost:8888/auth#access_token=myAccessToken&expires_in=28800&token_type=bearer&state=a39fh23hnf23
Now I have a node.js application where I want to make API calls using my access token, until now I did the above manually every time to get my access token, of course, this isn't optimal. My question, therefore, is: how do I get my access token without using the browser?
Right now I have the following
sendRequestAccessToken(): Promise<any> {
const scope = 'signature';
const clientId = '*my client id*';
const state = 'a39fh23hnf23';
const url = `https://account-d.docusign.com/oauth/auth?
response_type=token
&scope=${scope}
&client_id=${clientId}
&state=${state}
&redirect_uri=http://localhost:8888/auth
`;
return this.httpService.get(url).toPromise(); }
The response from this function contains a lot of data, but no access token.
Please review the SDK examples we have here: https://github.com/docusign/code-examples-node
In those samples, we have examples on how to use the tokens using the apis.

get json from electron BrowserWindow

I am trying to create a login for my app using discord's Oauth2 currently I am displaying a separate BrowserWindow for the API call since discords Oauth2 requires that the user clicks authorize. my API call returns the raw JSON of the acess_tokens. In my app's current state the separate window only displays the JSON. I need a way to get the JSON from within the window or from the request in a variable. I can't seem to find any way to access the raw content.
function createAuthWindow(){
var authWindow = new BrowserWindow({
width: 400,
height: 600,
show: false,
'node-integration': false,
'web-security': false,
icon: getFile('f','/src/asset/instance.png'),
});
// This is just an example url - follow the guide for whatever service you are using
var authUrl = 'http://localhost:3001/api/discord/login'
authWindow.loadURL(authUrl, (res) => {
console.log(res)
console.log(authWindow);
});
authWindow.show();
// 'will-navigate' is an event emitted when the window.location changes
// newUrl should contain the tokens you need
authWindow.webContents.on('will-navigate', function (event, newUrl) {
// More complex code to handle tokens goes here
console.log(event.code);
authWindow.webContents.session.webRequest.onCompleted({ urls: [newUrl] }, (details) => {
// Access request headers via details.requestHeaders
// Access response headers via details.responseHeaders
console.log(authWindow.webContents.code)
});
});
Sounds like your auth URL is not correct, and that you should be sending an Authorization Code Flow message, so that you can get tokens back to your app.
The usual technique for a desktop app is to:
Format the Authorization Redirect URL
Open this URL in the System Browser, which will handle redirects for you
Receive the response via a Private URI Scheme or Loopback Notification
Swap the authorization code for tokens, which your app can then use to call APIs
The redirect URL will be a value something like this, though I have not used Discord as a provider, so this may not be 100% right:
https://login.discord.com/oauth2/v2.0/authorize?
client_id=y792f434f
&response_type=code
&redirect_uri=com.mycompany.myapp:/callback
&scope=...
&state=...
&code_challenge=...
&code_challenge_method=S256
If it helps I have a couple of blog posts on OAuth for Electron Desktop Apps. It is a tricky flow to implement though ...
Initial Desktop Code Sample
Final Desktop Code Sample

shopify - nodejs - get permanent token fails

I have written an application that talks with the shopify API. I manage to get the temporary code from shopify and redirect back to my app where I store the code to later exchange for the permanent token.
According to the docs all I need to do is then send a POST request to https://{shop}.myshopify.com/admin/oauth/access_token with the client_id, client_secret and code is the body of the request.
I am using the request module to send the request and have it set up to send the request as such:
var options = {
method: POST,
url: https://my-develop-shop.myshopify.com/admin/oauth/access_token,
json: true
};
var _body = {
"client_id": config.get('SHOP_ID'),
"client_secret": config.get('SHOP_SECRET'),
"code": tempCode
}
_body = JSON.stringify(_body);
options.body = _body;
request(options, callback);
However when I send the request it always returns with : error_description: 'Could not find Shopify API application with api_key ' }
The app is installed successfully on the client's shop, so why would this error be returned?
Is there a special header that shopify expects? The docs are so vague.
Why does it not authenticate?
Well I cheated and used the shopify-node-api package. There I just use the exchange_temporary_token method. This api also handles throttling so it's a decent investment in the time you might spend incorporating it.

redirect to another app with session token (jwt) in AngularJS and NodeJS

I have a startup module in angularjs. This module is just to login and have public information (login, prices, newsletter...). I have many roles and for each role, i have an app (angular module). I made this architecture because i have complex module for each role and it was impossible to put all roles in one module.
So, for login, i use jsonwebtoken in node like this :
var token = jwt.sign(user, config.secureToken, { expiresInMinutes: 20*5});
res.json({ token: token, user: user });
It works perfectly. I can login into my app. After that, i have to propose a list of roles to redirect to the right module.
In angular, I have AuthHttp service that adds security headers (with token) to call rest service with $http.
How can i redirect to 'mydomain:port/anotherModule' with $location or $http ?
With this code in nodejs :
app.get('/secondModule', expressJwt({secret: config.secureToken}), function (req, res) {
res.render('restricted/secondModule/index.html');
});
NodeJs sends an html code in response and does'nt redirect...
And if i do this in my angular controller :
location.href = route;
i have this result on nodejs console :
Error: No Authorization header was found
I am not sure about the libraries you are using, but issue seems that you are loosing the token because you navigate to a altogether new page.
Based on your auth library you need to pass the token that you get after auth from one page to another.
The options here are to either use browser sessionStorage or querystring to pass the token along and at it back to the http header collection on the new page (module)
This is an old post but I recently took a long time to figure this out. I may be wrong but I believe nodeJS/expressJS can't read the token from the session storage. I believe you will need to pass the token via the request header using AngularJS.
This depends on the front end that you are using. For me, I am using AngularJS and I have to do something like this.
angular.module('AngularApp').factory('authFactory',
function($window){ //the window object will be able to access the token
var auth = {};
auth.saveToken = function(token){
$window.localStorage['token_name'] = token; //saving the token
}
auth.getToken = function(){
return $window.localStorage['token_name']; //retrieving the token
}
return auth;
}
.service('authInterceptor, function(authFactory){
return { headers: {Authorization: 'Bearer "+ authFactory.getToken()}
} //the last line gets the retrieved token and put it in req.header
Then, you just need to include 'authInterceptor' in all the http methods when you communicate with the backend. This way, nodeJS will be able to pick up the token.
You can see the Authorization field in req.header if you use the chrome developer tool and look at the Network tab. Hope this helps.

Resources