-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathauth.js
More file actions
119 lines (109 loc) · 4 KB
/
auth.js
File metadata and controls
119 lines (109 loc) · 4 KB
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
const express = require('express'),
config = require('./config.json'),
qs = require('querystring'),
smarclient = require('smartsheet'),
app = express(),
fs = require('fs');
// instantiating the Smartsheet client
const smartsheet = smarclient.createClient({
// a blank token provides access to Smartsheet token endpoints
accessToken: ''
});
// starting an express server
app.listen(3000, () => {
console.log('Ports listening on 3000...');
});
// setting up home route containing basic page content
app.get('/', (req, res) => {
res.send('<h1>Sample oAuth flow for Smartsheet</h1><a href="/auth">Login to Smartsheet</a></br><a href="/refresh">Refresh Token</a>')
});
// route redirecting to authorization page
app.get('/auth', (req, res) => {
console.log('Your authorization url: ', authorizationUri);
res.redirect(authorizationUri);
});
// helper function to assemble authorization url
function authorizeURL(params) {
const authURL = 'https://app.smartsheet.com/b/authorize';
return `${authURL}?${qs.stringify(params)}`;
}
const authorizationUri = authorizeURL({
response_type: 'code',
client_id: config.APP_CLIENT_ID,
scope: config.ACCESS_SCOPE
});
// callback service parses the authorization code, requests access token, and saves it
app.get('/callback', (req, res) => {
console.log(req.query);
const authCode = req.query.code;
const generated_hash = require('crypto')
.createHash('sha256')
.update(config.APP_SECRET + "|" + authCode)
.digest('hex');
const options = {
queryParameters: {
client_id: config.APP_CLIENT_ID,
code: authCode,
hash: generated_hash
}
};
smartsheet.tokens.getAccessToken(options, processToken)
.then((token) => {
return res
.status(200)
.json(token);
});
});
// Sample for REFERENCE ONLY. A production app should not be structured this way.
app.get('/refresh', (req, res) => {
fs.access('token_priv.json', (err) => {
// redirect to normal oauth flow if no existing token
if (err && err.code === 'ENOENT') {
console.log(err);
res.redirect(authorizationUri);
}
console.log('...Refreshing Expired Token...')
const old_token = require('./token_priv.json');
// if current date is past expiration date...
if (Date.now() > old_token.EXPIRES_IN) {
const generated_hash = require('crypto')
.createHash('sha256')
.update(config.APP_SECRET + "|" + old_token.REFRESH_TOKEN)
.digest('hex');
const options = {
queryParameters: {
client_id: config.APP_CLIENT_ID,
refresh_token: old_token.REFRESH_TOKEN,
hash: generated_hash
}
};
smartsheet.tokens.refreshAccessToken(options, processToken)
.then((token) => {
return res
.status(200)
.json(token);
});
} else {
// token still valid. If attempting to force token refresh, change expires_in in priv_token.json
console.log('token still valid')
return res
.send('<h1>No refresh. Access token still valid</h1>');
}
})
})
function processToken(error, token) {
if (error) {
console.error('Access Token Error:', error.message);
return error;
}
console.log('The resulting token: ', token);
// IMPORTANT: token saved to local JSON as EXAMPLE ONLY.
// You should save access_token, refresh_token, and expires_in to database for use in application.
let returned_token = {
"ACCESS_TOKEN": token.access_token,
"EXPIRES_IN": (Date.now() + (token.expires_in * 1000)),
"REFRESH_TOKEN": token.refresh_token
}
fs.writeFileSync('token_priv.json', JSON.stringify(returned_token));
return token;
}