Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,11 @@ gulp.task('lint', () => {
}
}));
});

gulp.task('fix', () => {
return gulp.src(['src/*.js', 'samples/*.gs', 'test/**/*.js', '!node_modules/**'])
.pipe(eslint({fix: true}))
.pipe(eslint.format())
.pipe(gulp.dest(file => file.base))
});

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"scripts": {
"dist": "gulp dist",
"lint": "gulp lint",
"lint:fix": "gulp fix",
"doc": "jsdoc -c jsdoc.json src/*.js README.md",
"push": "cd src; clasp push",
"test": "mocha"
Expand Down
24 changes: 12 additions & 12 deletions samples/StackOverflow.gs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function run() {
} else {
var authorizationUrl = service.getAuthorizationUrl();
Logger.log('Open the following URL and re-run the script: %s',
authorizationUrl);
authorizationUrl);
}
}

Expand All @@ -37,20 +37,20 @@ function reset() {
*/
function getService_() {
return OAuth2.createService('Stack Overflow')
// Set the endpoint URLs.
.setAuthorizationBaseUrl('https://stackoverflow.com/oauth')
.setTokenUrl('https://stackoverflow.com/oauth/access_token/json')
// Set the endpoint URLs.
.setAuthorizationBaseUrl('https://stackoverflow.com/oauth')
.setTokenUrl('https://stackoverflow.com/oauth/access_token/json')

// Set the client ID and secret.
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)
// Set the client ID and secret.
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)

// Set the name of the callback function that should be invoked to
// complete the OAuth flow.
.setCallbackFunction('authCallback')
// Set the name of the callback function that should be invoked to
// complete the OAuth flow.
.setCallbackFunction('authCallback')

// Set the property store where authorized tokens should be persisted.
.setPropertyStore(PropertiesService.getUserProperties());
// Set the property store where authorized tokens should be persisted.
.setPropertyStore(PropertiesService.getUserProperties());
}

/**
Expand Down
66 changes: 33 additions & 33 deletions samples/Twitter.gs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function run() {
} else {
var authorizationUrl = service.getAuthorizationUrl();
Logger.log('Open the following URL and re-run the script: %s',
authorizationUrl);
authorizationUrl);
}
}

Expand All @@ -42,34 +42,34 @@ function getService_() {
pkceChallengeVerifier();
var userProps = PropertiesService.getUserProperties();
return OAuth2.createService('Twitter')
// Set the endpoint URLs.
.setAuthorizationBaseUrl('https://twitter.com/i/oauth2/authorize')
.setTokenUrl(
'https://api.twitter.com/2/oauth2/token?code_verifier=' + userProps.getProperty("code_verifier"))
// Set the endpoint URLs.
.setAuthorizationBaseUrl('https://twitter.com/i/oauth2/authorize')
.setTokenUrl(
'https://api.twitter.com/2/oauth2/token?code_verifier=' + userProps.getProperty('code_verifier'))

// Set the client ID and secret.
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)
// Set the client ID and secret.
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)

// Set the name of the callback function that should be invoked to
// complete the OAuth flow.
.setCallbackFunction('authCallback')
// Set the name of the callback function that should be invoked to
// complete the OAuth flow.
.setCallbackFunction('authCallback')

// Set the property store where authorized tokens should be persisted.
.setPropertyStore(userProps)
// Set the property store where authorized tokens should be persisted.
.setPropertyStore(userProps)

// Set the scopes to request (space-separated for Twitter services).
.setScope('users.read tweet.read offline.access')

// Add parameters in the authorization url
.setParam('response_type', 'code')
.setParam('code_challenge_method', 'S256')
.setParam('code_challenge', userProps.getProperty("code_challenge"))
// Set the scopes to request (space-separated for Twitter services).
.setScope('users.read tweet.read offline.access')

.setTokenHeaders({
'Authorization': 'Basic ' + Utilities.base64Encode(CLIENT_ID + ':' + CLIENT_SECRET),
'Content-Type': 'application/x-www-form-urlencoded'
})
// Add parameters in the authorization url
.setParam('response_type', 'code')
.setParam('code_challenge_method', 'S256')
.setParam('code_challenge', userProps.getProperty('code_challenge'))

.setTokenHeaders({
'Authorization': 'Basic ' + Utilities.base64Encode(CLIENT_ID + ':' + CLIENT_SECRET),
'Content-Type': 'application/x-www-form-urlencoded'
});
}

/**
Expand Down Expand Up @@ -97,21 +97,21 @@ function logRedirectUri() {
*/
function pkceChallengeVerifier() {
var userProps = PropertiesService.getUserProperties();
if (!userProps.getProperty("code_verifier")) {
var verifier = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";
if (!userProps.getProperty('code_verifier')) {
var verifier = '';
var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';

for (var i = 0; i < 128; i++) {
verifier += possible.charAt(Math.floor(Math.random() * possible.length));
}

var sha256Hash = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, verifier)
var sha256Hash = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, verifier);

var challenge = Utilities.base64Encode(sha256Hash)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '')
userProps.setProperty("code_verifier", verifier)
userProps.setProperty("code_challenge", challenge)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
userProps.setProperty('code_verifier', verifier);
userProps.setProperty('code_challenge', challenge);
}
}
6 changes: 3 additions & 3 deletions src/OAuth2.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,12 @@ function getRedirectUri(optScriptId) {
*/
function getServiceNames(propertyStore) {
var props = propertyStore.getProperties();
return Object.keys(props).filter(function (key) {
return Object.keys(props).filter(function(key) {
var parts = key.split('.');
return key.indexOf(STORAGE_PREFIX_) == 0 && parts.length > 1 && parts[1];
}).map(function (key) {
}).map(function(key) {
return key.split('.')[1];
}).reduce(function (result, key) {
}).reduce(function(result, key) {
if (result.indexOf(key) < 0) {
result.push(key);
}
Expand Down
11 changes: 5 additions & 6 deletions test/mocks/lock.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,14 @@
*/

/**
* @file Mocks out Apps Script's LockService.Lock. Does not implement correct lock
* semantics at the moment. Previous versions relied on node-fibers which is now
* obsolete. It's possible to recreate apps script multi-threaded environment
* via worker threads and implement proper locking and that may be considered
* in the future.
* @file Mocks out Apps Script's LockService.Lock. Does not implement
* correct lock semantics at the moment. Previous versions relied on
* node-fibers which is now obsolete. It's possible to recreate apps
* script multi-threaded environment via worker threads and implement
* proper locking and that may be considered in the future.
*/

var locked = false;
var waitingFibers = [];

var MockLock = function() {
this.hasLock_ = false;
Expand Down
20 changes: 10 additions & 10 deletions test/mocks/utilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ var MockUtilities = function(optCache) {
this.store = optCache || {};
this.counter = 0;
};

MockUtilities.prototype.base64Encode = function(data) {
return Buffer.from(data).toString('base64');
return Buffer.from(data).toString('base64');
};

MockUtilities.prototype.base64EncodeWebSafe = function(data) {
return URLSafeBase64.encode(Buffer.from(data));
}
};

MockUtilities.prototype.base64DecodeWebSafe = function(data) {
return URLSafeBase64.decode(data);
Expand All @@ -44,17 +44,17 @@ MockUtilities.prototype.newBlob = function(data) {
};

MockUtilities.prototype.DigestAlgorithm = {
SHA_256: 'sha256'
SHA_256: 'sha256'
};

MockUtilities.prototype.Charset = {
US_ASCII: 'us_ascii'
US_ASCII: 'us_ascii'
};

MockUtilities.prototype.computeDigest = function(algorithm, data, charSet) {
const hash = crypto.createHash(algorithm);
hash.update(data);
return hash.digest('utf8');
}
const hash = crypto.createHash(algorithm);
hash.update(data);
return hash.digest('utf8');
};

module.exports = MockUtilities;
module.exports = MockUtilities;
24 changes: 12 additions & 12 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,11 +308,11 @@ describe('Service', () => {
});

var service = OAuth2.createService('test')
.setClientId('abc')
.setClientSecret('def')
.setTokenUrl('http://www.example.com')
.setPropertyStore(properties)
.setLock(lock);
.setClientId('abc')
.setClientSecret('def')
.setTokenUrl('http://www.example.com')
.setPropertyStore(properties)
.setLock(lock);
service.hasAccess();
assert.equal(lock.counter, 1);
done();
Expand Down Expand Up @@ -376,12 +376,12 @@ describe('Service', () => {
access_token: Math.random().toString(36)
});
OAuth2.createService('test')
.setClientId('abc')
.setClientSecret('def')
.setTokenUrl('http://www.example.com')
.setPropertyStore(properties)
.setLock(lock)
.refresh();
.setClientId('abc')
.setClientSecret('def')
.setTokenUrl('http://www.example.com')
.setPropertyStore(properties)
.setLock(lock)
.refresh();
assert.equal(lock.counter, 1);
done();
});
Expand Down Expand Up @@ -597,7 +597,7 @@ describe('Service', () => {
expiresAt: ONE_HOUR_LATER_SECONDS,
refreshTokenExpiresAt: ONE_HOUR_LATER_SECONDS
};
console.log('test')
console.log('test');
assert.isTrue(service.canRefresh_(token));
});

Expand Down