/
native_flow.js
105 lines (97 loc) · 3.2 KB
/
native_flow.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
var Bluebird = require('bluebird');
var oauthUtil = require('./oauth_util');
/**
* Default function to return instructions for the user to authorize the app.
* Written to stdout during `run`.
* @param {String} url The authorization URL
* @returns {String} Instructions for the user
*/
function defaultInstructions(url) {
return [
'* * * * * * * * * * * * * * * * * * * * * * * * * * *',
'Please open a browser to the url:',
'',
url,
'',
'and follow the prompts to authorize this application.',
'* * * * * * * * * * * * * * * * * * * * * * * * * * *'
].join('\n');
}
/**
* Default function to return the prompt for the user to enter the
* authorization code. Written to stdout immediately preceding keyboard input
* during `run`.
* @returns {String} A message to prompt the user to enter the code.
*/
function defaultPrompt() {
return 'Enter the code here: ';
}
/**
* An Oauth flow that can be run from the console or an app that does
* not have the ability to open and manage a browser on its own.
* @param {Object} options
* @option {App} app App to authenticate for
* @option {String function(String)} [instructions] Function returning the
* instructions to output to the user. Passed the authorize url.
* @option {String function()} [prompt] String to output immediately before
* waiting for a line from stdin.
* @constructor
*/
function NativeFlow(options) {
this.app = options.app;
this.instructions = options.instructions || defaultInstructions;
this.prompt = options.prompt || defaultPrompt;
this.redirectUri = oauthUtil.NATIVE_REDIRECT_URI;
}
/**
* Run the Oauth flow, prompting the user to go to the authorization URL
* and enter the code it displays when finished.
*
* @return {Promise<Object>} The access token object, which will include
* `access_token` and `refresh_token`.
*/
NativeFlow.prototype.run = function() {
var me = this;
return me.promptForCode(me.authorizeUrl()).then(function(code) {
return me.accessToken(code);
});
};
/**
* @returns {String} The URL used to authorize the user for the app.
*/
NativeFlow.prototype.authorizeUrl = function() {
return this.app.asanaAuthorizeUrl({
redirectUri: this.redirectUri
});
};
/**
* @param {String} code An authorization code obtained via `asanaAuthorizeUrl`.
* @return {Promise<Object>} The token, which will include the `access_token`
* used for API access, as well as a `refresh_token` which can be stored
* to get a new access token without going through the flow again.
*/
NativeFlow.prototype.accessToken = function(code) {
return this.app.accessTokenFromCode(code, {
redirectUri: this.redirectUri
});
};
/**
* @return {Promise} The access token, which will include a refresh token
* that can be stored in the future to create a client without going
* through the Oauth flow.
*/
NativeFlow.prototype.promptForCode = function(url) {
var me = this;
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
return new Bluebird(function(resolve) {
console.log(me.instructions(url));
rl.question(me.prompt(), function(code) {
rl.close();
return resolve(code);
});
});
};
module.exports = NativeFlow;