Skip to content
This repository was archived by the owner on Jun 11, 2025. It is now read-only.

fix: prevent samples from leaking OAuth client ID + Secret to users #54

Merged
merged 2 commits into from
Jul 27, 2022
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
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ exact URL that the service will use when performing the OAuth flow:
* Logs the callback URL to register.
*/
function logCallbackUrl() {
var service = getService();
var service = getService_();
Logger.log(service.getCallbackUrl());
}
```
Expand All @@ -68,8 +68,12 @@ information is not persisted to any data store, so you'll need to create this
object each time you want to use it. The example below shows how to create a
service for the Twitter API.

Ensure the method is private (has an underscore at the end of the name) to
prevent clients from being able to call the method to read your client ID and
secret.

```js
function getTwitterService() {
function getTwitterService_() {
// Create a new service with the given name. The name will be used when
// persisting the authorized token, so ensure it is unique within the
// scope of the property store.
Expand Down Expand Up @@ -98,7 +102,7 @@ authorization URL.

```js
function showSidebar() {
var twitterService = getTwitterService();
var twitterService = getTwitterService_();
if (!twitterService.hasAccess()) {
var authorizationUrl = twitterService.authorize();
var template = HtmlService.createTemplate(
Expand All @@ -122,7 +126,7 @@ to the user.

```js
function authCallback(request) {
var twitterService = getTwitterService();
var twitterService = getTwitterService_();
var isAuthorized = twitterService.handleCallback(request);
if (isAuthorized) {
return HtmlService.createHtmlOutput('Success! You can close this tab.');
Expand All @@ -144,7 +148,7 @@ and automatically signs the requests using the OAuth1 token.

```js
function makeRequest() {
var twitterService = getTwitterService();
var twitterService = getTwitterService_();
var response = twitterService.fetch('https://api.twitter.com/1.1/statuses/user_timeline.json');
// ...
}
Expand Down
10 changes: 5 additions & 5 deletions samples/Etsy.gs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ var CONSUMER_SECRET = '...';
* Authorizes and makes a request to the Etsy API.
*/
function run() {
var service = getService();
var service = getService_();
if (service.hasAccess()) {
var url = 'https://openapi.etsy.com/v2/users/__SELF__/profile';
var response = service.fetch(url);
Expand All @@ -32,14 +32,14 @@ function run() {
* Reset the authorization state, so that it can be re-tested.
*/
function reset() {
var service = getService();
var service = getService_();
service.reset();
}

/**
* Configures the service.
*/
function getService() {
function getService_() {
var service = OAuth1.createService('Etsy')
// Set the endpoint URLs.
// Pass the desired scopes in the request token URL.
Expand All @@ -62,7 +62,7 @@ function getService() {

// Override the callback URL method to use the web app URL instead.
service.getCallbackUrl = function() {
return ScriptApp.getService().getUrl();
return ScriptApp.getService_().getUrl();
};

return service;
Expand All @@ -74,7 +74,7 @@ function getService() {
function doGet(request) {
// Determine if the request is part of an OAuth callback.
if (request.parameter.oauth_token) {
var service = getService();
var service = getService_();
var authorized = service.handleCallback(request);
if (authorized) {
return HtmlService.createHtmlOutput('Success!');
Expand Down
10 changes: 5 additions & 5 deletions samples/Goodreads.gs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ var CONSUMER_SECRET = '...';
* Authorizes and makes a request to the Goodreads API.
*/
function run() {
var service = getService();
var service = getService_();
if (service.hasAccess()) {
var url = 'https://www.goodreads.com/api/auth_user';
var response = service.fetch(url);
Expand All @@ -29,14 +29,14 @@ function run() {
* Reset the authorization state, so that it can be re-tested.
*/
function reset() {
var service = getService();
var service = getService_();
service.reset();
}

/**
* Configures the service.
*/
function getService() {
function getService_() {
var service = OAuth1.createService('Goodreads')
// Set the endpoint URLs.
.setAccessTokenUrl('https://www.goodreads.com/oauth/access_token')
Expand All @@ -59,7 +59,7 @@ function getService() {

// Override the callback URL method to use the web app URL instead.
service.getCallbackUrl = function() {
return ScriptApp.getService().getUrl();
return ScriptApp.getService_().getUrl();
};

return service;
Expand All @@ -71,7 +71,7 @@ function getService() {
function doGet(request) {
// Determine if the request is part of an OAuth callback.
if (request.parameter.oauth_token) {
var service = getService();
var service = getService_();
var authorized = service.handleCallback(request);
if (authorized) {
return HtmlService.createHtmlOutput('Success!');
Expand Down
8 changes: 4 additions & 4 deletions samples/Jira.gs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ var PRIVATE_KEY = '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n
* Authorizes and makes a request to the Xero API.
*/
function run() {
var service = getService();
var service = getService_();
if (service.hasAccess()) {
var url = SITE + '/rest/api/3/myself';
var response = service.fetch(url, {
Expand All @@ -33,13 +33,13 @@ function run() {
* Reset the authorization state, so that it can be re-tested.
*/
function reset() {
getService().reset();
getService_().reset();
}

/**
* Configures the service.
*/
function getService() {
function getService_() {
return OAuth1.createService('Jira')
// Set the endpoint URLs.
.setRequestTokenUrl(SITE + '/plugins/servlet/oauth/request-token')
Expand Down Expand Up @@ -68,7 +68,7 @@ function getService() {
* Handles the OAuth callback.
*/
function authCallback(request) {
var service = getService();
var service = getService_();
var authorized = service.handleCallback(request);
if (authorized) {
return HtmlService.createHtmlOutput('Success!');
Expand Down
8 changes: 4 additions & 4 deletions samples/KhanAcademy.gs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ var CONSUMER_SECRET = '...';
* Authorizes and makes a request to the TripIt API.
*/
function run() {
var service = getService();
var service = getService_();
if (service.hasAccess()) {
var url = 'https://api.khanacademy.org/api/v1/user';
var response = service.fetch(url);
Expand All @@ -22,14 +22,14 @@ function run() {
* Reset the authorization state, so that it can be re-tested.
*/
function reset() {
var service = getService();
var service = getService_();
service.reset();
}

/**
* Configures the service.
*/
function getService() {
function getService_() {
return OAuth1.createService('TripIt')
// Set the endpoint URLs.
.setRequestTokenUrl('https://www.khanacademy.org/api/auth2/request_token')
Expand All @@ -55,7 +55,7 @@ function getService() {
* Handles the OAuth2 callback.
*/
function authCallback(request) {
var service = getService();
var service = getService_();
var authorized = service.handleCallback(request);
if (authorized) {
return HtmlService.createHtmlOutput('Success!');
Expand Down
8 changes: 4 additions & 4 deletions samples/QuickBooks.gs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ var CONSUMER_SECRET = '...';
* sandbox company.
*/
function run() {
var service = getService();
var service = getService_();
if (service.hasAccess()) {
var companyId = PropertiesService.getUserProperties()
.getProperty('QuickBooks.companyId');
Expand All @@ -30,14 +30,14 @@ function run() {
* Reset the authorization state, so that it can be re-tested.
*/
function reset() {
var service = getService();
var service = getService_();
service.reset();
}

/**
* Configures the service.
*/
function getService() {
function getService_() {
return OAuth1.createService('QuickBooks')
// Set the endpoint URLs.
.setAccessTokenUrl('https://oauth.intuit.com/oauth/v1/get_access_token')
Expand All @@ -60,7 +60,7 @@ function getService() {
* Handles the OAuth callback.
*/
function authCallback(request) {
var service = getService();
var service = getService_();
var authorized = service.handleCallback(request);
if (authorized) {
PropertiesService.getUserProperties()
Expand Down
4 changes: 2 additions & 2 deletions samples/Semantics3.gs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ var API_SECRET = '...';
* Authorizes and makes a request to the Semantics3 API.
*/
function run() {
var service = getService();
var service = getService_();
var query = encodeURIComponent(JSON.stringify({
search: 'iPhone'
}));
Expand All @@ -18,7 +18,7 @@ function run() {
/**
* Configures the service.
*/
function getService() {
function getService_() {
return OAuth1.createService('Semantics3')
// Set the consumer key and secret.
.setConsumerKey(API_KEY)
Expand Down
8 changes: 4 additions & 4 deletions samples/Trello.gs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ var CONSUMER_SECRET = '...';
* Authorizes and makes a request to the Trello API.
*/
function run() {
var service = getService();
var service = getService_();
if (service.hasAccess()) {
var url = 'https://api.trello.com/1/members/me/boards';
var response = service.fetch(url);
Expand All @@ -22,14 +22,14 @@ function run() {
* Reset the authorization state, so that it can be re-tested.
*/
function reset() {
var service = getService();
var service = getService_();
service.reset();
}

/**
* Configures the service.
*/
function getService() {
function getService_() {
return OAuth1.createService('Trello')
// Set the endpoint URLs.
.setRequestTokenUrl('https://trello.com/1/OAuthGetRequestToken')
Expand All @@ -52,7 +52,7 @@ function getService() {
* Handles the OAuth2 callback.
*/
function authCallback(request) {
var service = getService();
var service = getService_();
var authorized = service.handleCallback(request);
if (authorized) {
return HtmlService.createHtmlOutput('Success!');
Expand Down
8 changes: 4 additions & 4 deletions samples/TripIt.gs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ var CONSUMER_SECRET = '...';
* Authorizes and makes a request to the TripIt API.
*/
function run() {
var service = getService();
var service = getService_();
if (service.hasAccess()) {
var url = 'https://api.tripit.com/v1/get/profile?format=json';
var response = service.fetch(url);
Expand All @@ -22,14 +22,14 @@ function run() {
* Reset the authorization state, so that it can be re-tested.
*/
function reset() {
var service = getService();
var service = getService_();
service.reset();
}

/**
* Configures the service.
*/
function getService() {
function getService_() {
return OAuth1.createService('TripIt')
// Set the endpoint URLs.
.setRequestTokenUrl('https://api.tripit.com/oauth/request_token')
Expand All @@ -55,7 +55,7 @@ function getService() {
* Handles the OAuth callback.
*/
function authCallback(request) {
var service = getService();
var service = getService_();
var authorized = service.handleCallback(request);
if (authorized) {
return HtmlService.createHtmlOutput('Success!');
Expand Down
8 changes: 4 additions & 4 deletions samples/Twitter.gs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ var CONSUMER_SECRET = '...';
* Authorizes and makes a request to the Twitter API.
*/
function run() {
var service = getService();
var service = getService_();
if (service.hasAccess()) {
var url = 'https://api.twitter.com/1.1/statuses/update.json';
var payload = {
Expand All @@ -28,14 +28,14 @@ function run() {
* Reset the authorization state, so that it can be re-tested.
*/
function reset() {
var service = getService();
var service = getService_();
service.reset();
}

/**
* Configures the service.
*/
function getService() {
function getService_() {
return OAuth1.createService('Twitter')
// Set the endpoint URLs.
.setAccessTokenUrl('https://api.twitter.com/oauth/access_token')
Expand All @@ -62,7 +62,7 @@ function getService() {
* Handles the OAuth callback.
*/
function authCallback(request) {
var service = getService();
var service = getService_();
var authorized = service.handleCallback(request);
if (authorized) {
return HtmlService.createHtmlOutput('Success!');
Expand Down
6 changes: 3 additions & 3 deletions samples/XeroPrivate.gs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ var PRIVATE_KEY = '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n
* Authorizes and makes a request to the Xero API.
*/
function run() {
var service = getService();
var service = getService_();
var url = 'https://api.xero.com/api.xro/2.0/Organisations';
var response = service.fetch(url, {
headers: {
Expand All @@ -34,13 +34,13 @@ function run() {
* Reset the authorization state, so that it can be re-tested.
*/
function reset() {
getService().reset();
getService_().reset();
}

/**
* Configures the service.
*/
function getService() {
function getService_() {
return OAuth1.createService('Xero')
// Set the consumer key and secret.
.setConsumerKey(CONSUMER_KEY)
Expand Down
Loading