From df864526edc16ebe669e9f20475c75a077e04e70 Mon Sep 17 00:00:00 2001 From: Alnis Smidchens Date: Tue, 5 Jul 2022 16:04:02 -0700 Subject: [PATCH] fix: prevent samples from leaking OAuth client ID + Secret to users Previously, the getService method was public in most of the samples, letting any user of any sample application execute the method using google.script.run to exfiltrate the OAuth Client ID and Secret from the server. Now, these methods are made private by appending an _ to their names, preventing this issue. --- README.md | 34 +++++++++++++++++------------- docs/index.html | 30 +++++++++++++------------- samples/Add-on/Code.gs | 14 ++++++------ samples/AdobeSign.gs | 8 +++---- samples/Basecamp.gs | 8 +++---- samples/ChatWork.gs | 8 +++---- samples/CloudIAPServiceAccount.gs | 6 +++--- samples/CloudIdentityAwareProxy.gs | 8 +++---- samples/DocuSign.gs | 8 +++---- samples/Domo.gs | 6 +++--- samples/Dropbox.gs | 8 +++---- samples/Facebook.gs | 8 +++---- samples/FirebaseDB.gs | 6 +++--- samples/FitBit.gs | 8 +++---- samples/GitHub.gs | 8 +++---- samples/Google.gs | 8 +++---- samples/GoogleHangoutsChat.gs | 6 +++--- samples/GoogleServiceAccount.gs | 6 +++--- samples/Harvest.gs | 8 +++---- samples/HubSpot.gs | 8 +++---- samples/IdentityServer4.gs | 8 +++---- samples/Jira.gs | 8 +++---- samples/LINE.gs | 8 +++---- samples/LinkedIn.gs | 8 +++---- samples/Mailchimp.gs | 8 +++---- samples/Meetup.gs | 8 +++---- samples/Notion.gs | 8 +++---- samples/QuickBooks.gs | 10 ++++----- samples/RingCentral.gs | 8 +++---- samples/Salesforce.gs | 8 +++---- samples/Smartsheet.gs | 8 +++---- samples/Spotify.gs | 8 +++---- samples/StackOverflow.gs | 8 +++---- samples/Tink.gs | 8 +++---- samples/Twitter.gs | 8 +++---- samples/TwitterAppOnly.gs | 6 +++--- samples/UltraCart.gs | 8 +++---- samples/VK.gs | 8 +++---- samples/WebApp/Code.gs | 12 +++++------ samples/Wordpress.gs | 8 +++---- samples/Xero.gs | 8 +++---- samples/Yahoo.gs | 8 +++---- samples/Yandex.gs | 8 +++---- samples/Zendesk.gs | 8 +++---- samples/ZohoCRM.gs | 8 +++---- samples/Zoom.gs | 8 +++---- samples/eBay.gs | 8 +++---- 47 files changed, 214 insertions(+), 210 deletions(-) diff --git a/README.md b/README.md index 46022314..6db1c428 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ exact URL that the service will use when performing the OAuth flow: * Logs the redirect URI to register. */ function logRedirectUri() { - var service = getService(); + var service = getService_(); Logger.log(service.getRedirectUri()); } ``` @@ -95,8 +95,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 Google Drive 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 getDriveService() { +function getDriveService_() { // 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. @@ -143,7 +147,7 @@ The URL is generated by the service, using the function `getAuthorizationUrl()`. ```js function showSidebar() { - var driveService = getDriveService(); + var driveService = getDriveService_(); if (!driveService.hasAccess()) { var authorizationUrl = driveService.getAuthorizationUrl(); var template = HtmlService.createTemplate( @@ -167,7 +171,7 @@ to the user. ```js function authCallback(request) { - var driveService = getDriveService(); + var driveService = getDriveService_(); var isAuthorized = driveService.handleCallback(request); if (isAuthorized) { return HtmlService.createHtmlOutput('Success! You can close this tab.'); @@ -190,7 +194,7 @@ request in the "Authorization" header. ```js function makeRequest() { - var driveService = getDriveService(); + var driveService = getDriveService_(); var response = UrlFetchApp.fetch('https://www.googleapis.com/drive/v2/files?maxResults=10', { headers: { Authorization: 'Bearer ' + driveService.getAccessToken() @@ -208,7 +212,7 @@ different account, use the `reset()` method: ```js function logout() { - var service = getDriveService() + var service = getDriveService_() service.reset(); } ``` @@ -350,7 +354,7 @@ request parameters and saved saved into storage. ```js function authCallback(request) { - var service = getService(); + var service = getService_(); var authorized = service.handleCallback(request); if (authorized) { // Gets the authorized account ID from the scope string. Assumes the @@ -401,7 +405,7 @@ optional hash of parameter names and values to the `getAuthorizationUrl()` method: ```js -var authorizationUrl = getService().getAuthorizationUrl({ +var authorizationUrl = getService_().getAuthorizationUrl({ // Pass the additional parameter "lang" with the value "fr". lang: 'fr' }); @@ -467,17 +471,17 @@ means selecting a service name that matches the API the user will authorize: ```js function run() { - var gitHubService = getGitHubService(); - var mediumService = getMediumService(); + var gitHubService = getGitHubService_(); + var mediumService = getMediumService_(); // ... } -function getGitHubService() { +function getGitHubService_() { return OAuth2.createService('GitHub') // GitHub settings ... } -function getMediumService() { +function getMediumService_() { return OAuth2.createService('Medium') // Medium settings ... } @@ -490,12 +494,12 @@ names: ```js function run() { - var copyFromService = getGitHubService('from'); - var copyToService = getGitHubService('to'); + var copyFromService = getGitHubService_('from'); + var copyToService = getGitHubService_('to'); // ... } -function getGitHubService(label) { +function getGitHubService_(label) { return OAuth2.createService('GitHub_' + label) // GitHub settings ... } diff --git a/docs/index.html b/docs/index.html index 516d71ca..18fe78c3 100644 --- a/docs/index.html +++ b/docs/index.html @@ -103,7 +103,7 @@

Redirect URI

* Logs the redirect URI to register. */ function logRedirectUri() { - var service = getService(); + var service = getService_(); Logger.log(service.getRedirectUri()); } @@ -115,7 +115,7 @@

1. Create the OAuth2 service

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 Google Drive API.

-
function getDriveService() {
+
function getDriveService_() {
   // 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.
@@ -158,7 +158,7 @@ 

2. Direct the user to the authorization URL

you'll need to present the authorization URL as a link for the user to click. The URL is generated by the service, using the function getAuthorizationUrl().

function showSidebar() {
-  var driveService = getDriveService();
+  var driveService = getDriveService_();
   if (!driveService.hasAccess()) {
     var authorizationUrl = driveService.getAuthorizationUrl();
     var template = HtmlService.createTemplate(
@@ -178,7 +178,7 @@ 

3. Handle the callback

request object to the service's handleCallback function, and show a message to the user.

function authCallback(request) {
-  var driveService = getDriveService();
+  var driveService = getDriveService_();
   var isAuthorized = driveService.handleCallback(request);
   if (isAuthorized) {
     return HtmlService.createHtmlOutput('Success! You can close this tab.');
@@ -196,7 +196,7 @@ 

4. Get the access token

requests to the API. The access token can be passed along with a UrlFetchApp request in the "Authorization" header.

function makeRequest() {
-  var driveService = getDriveService();
+  var driveService = getDriveService_();
   var response = UrlFetchApp.fetch('https://www.googleapis.com/drive/v2/files?maxResults=10', {
     headers: {
       Authorization: 'Bearer ' + driveService.getAccessToken()
@@ -209,7 +209,7 @@ 

Logout

To logout the user or disconnect the service, perhaps so the user can select a different account, use the reset() method:

function logout() {
-  var service = getDriveService()
+  var service = getDriveService_()
   service.reset();
 }
 
@@ -310,7 +310,7 @@

Storing token-related data

in the callback URL. In the following code the account ID is extracted from the request parameters and saved saved into storage.

function authCallback(request) {
-  var service = getService();
+  var service = getService_();
   var authorized = service.handleCallback(request);
   if (authorized) {
     // Gets the authorized account ID from the scope string. Assumes the
@@ -352,7 +352,7 @@ 

Passing additional parameters to the callback function

token, which is a standard mechanism for this purpose. To do so, pass an optional hash of parameter names and values to the getAuthorizationUrl() method:

-
var authorizationUrl = getService().getAuthorizationUrl({
+
var authorizationUrl = getService_().getAuthorizationUrl({
   // Pass the additional parameter "lang" with the value "fr".
   lang: 'fr'
 });
@@ -403,17 +403,17 @@ 

How can I connect to multiple OAuth services?

multiple services merely ensure they have different service names. Often this means selecting a service name that matches the API the user will authorize:

function run() {
-  var gitHubService = getGitHubService();
-  var mediumService = getMediumService();
+  var gitHubService = getGitHubService_();
+  var mediumService = getMediumService_();
   // ...
 }
 
-function getGitHubService() {
+function getGitHubService_() {
   return OAuth2.createService('GitHub')
       // GitHub settings ...
 }
 
-function getMediumService() {
+function getMediumService_() {
   return OAuth2.createService('Medium')
       // Medium settings ...
 }
@@ -423,12 +423,12 @@ 

How can I connect to multiple OAuth services?

those cases you'll need to devise your own method for creating unique service names:

function run() {
-  var copyFromService = getGitHubService('from');
-  var copyToService = getGitHubService('to');
+  var copyFromService = getGitHubService_('from');
+  var copyToService = getGitHubService_('to');
   // ...
 }
 
-function getGitHubService(label) {
+function getGitHubService_(label) {
   return OAuth2.createService('GitHub_' + label)
       // GitHub settings ...
 }
diff --git a/samples/Add-on/Code.gs b/samples/Add-on/Code.gs
index 4a2e297f..af68a1f9 100644
--- a/samples/Add-on/Code.gs
+++ b/samples/Add-on/Code.gs
@@ -49,7 +49,7 @@ function onInstall(e) {
  * project file.
  */
 function showSidebar() {
-  var service = getGitHubService();
+  var service = getGitHubService_();
   var template = HtmlService.createTemplateFromFile('Sidebar');
   template.email = Session.getEffectiveUser().getEmail();
   template.isSignedIn = service.hasAccess();
@@ -64,7 +64,7 @@ function showSidebar() {
  * @return {String} The authorization URL.
  */
 function getAuthorizationUrl() {
-  return getGitHubService().getAuthorizationUrl();
+  return getGitHubService_().getAuthorizationUrl();
 }
 
 /**
@@ -72,14 +72,14 @@ function getAuthorizationUrl() {
  * additional authorization-required API calls can be made.
  */
 function signOut() {
-  getGitHubService().reset();
+  getGitHubService_().reset();
 }
 
 /**
  * Gets the user's GitHub profile.
  */
 function getGitHubProfile() {
-  var service = getGitHubService();
+  var service = getGitHubService_();
   if (!service.hasAccess()) {
     throw new Error('Error: Missing GitHub authorization.');
   }
@@ -96,7 +96,7 @@ function getGitHubProfile() {
  * Gets the user's GitHub repos.
  */
 function getGitHubRepos() {
-  var service = getGitHubService();
+  var service = getGitHubService_();
   if (!service.hasAccess()) {
     throw new Error('Error: Missing GitHub authorization.');
   }
@@ -113,7 +113,7 @@ function getGitHubRepos() {
  * Gets an OAuth2 service configured for the GitHub API.
  * @return {OAuth2.Service} The OAuth2 service
  */
-function getGitHubService() {
+function getGitHubService_() {
   return OAuth2.createService('github')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://github.com/login/oauth/authorize')
@@ -142,7 +142,7 @@ function authCallback(request) {
   template.error = null;
   var title;
   try {
-    var service = getGitHubService();
+    var service = getGitHubService_();
     var authorized = service.handleCallback(request);
     template.isSignedIn = authorized;
     title = authorized ? 'Access Granted' : 'Access Denied';
diff --git a/samples/AdobeSign.gs b/samples/AdobeSign.gs
index d2ff57e3..688cc65c 100644
--- a/samples/AdobeSign.gs
+++ b/samples/AdobeSign.gs
@@ -12,7 +12,7 @@ var API_ACCESS_POINT_KEY = 'api_access_point';
  * Authorizes and makes a request to the Adobe Sign API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     // Retrieve the API access point from storage.
     var apiAccessPoint = service.getStorage().getValue(API_ACCESS_POINT_KEY);
@@ -38,13 +38,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(optApiAccessPoint) {
+function getService_(optApiAccessPoint) {
   var service = OAuth2.createService('AdobeSign')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://secure.echosign.com/public/oauth')
@@ -82,7 +82,7 @@ function getService(optApiAccessPoint) {
 function authCallback(request) {
   // Get the API access point specified in the URL parameters.
   var apiAccessPoint = request.parameter[API_ACCESS_POINT_KEY];
-  var service = getService(apiAccessPoint);
+  var service = getService_(apiAccessPoint);
   var authorized = service.handleCallback(request);
   if (authorized) {
     // Save the API access point in the service's storage.
diff --git a/samples/Basecamp.gs b/samples/Basecamp.gs
index 96fa8617..cbdc66d0 100644
--- a/samples/Basecamp.gs
+++ b/samples/Basecamp.gs
@@ -5,7 +5,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the Basecamp 3 API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = 'https://launchpad.37signals.com/authorization.json';
     var response = UrlFetchApp.fetch(url, {
@@ -26,13 +26,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 OAuth2.createService('Basecamp')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl(
@@ -56,7 +56,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!');
diff --git a/samples/ChatWork.gs b/samples/ChatWork.gs
index b0abd49f..9dc7d839 100644
--- a/samples/ChatWork.gs
+++ b/samples/ChatWork.gs
@@ -5,7 +5,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the ChatWork API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var response = UrlFetchApp.fetch('https://api.chatwork.com/v2/me', {
       headers: {
@@ -25,13 +25,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_() {
   var scope = 'users.profile.me:read rooms.messages:read';
   return OAuth2.createService('ChatWork')
       // Set the endpoint URLs.
@@ -67,7 +67,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!');
diff --git a/samples/CloudIAPServiceAccount.gs b/samples/CloudIAPServiceAccount.gs
index 54e09608..07c57e19 100644
--- a/samples/CloudIAPServiceAccount.gs
+++ b/samples/CloudIAPServiceAccount.gs
@@ -23,7 +23,7 @@ var IAP_URL = '...';
  * Identity-Aware Proxy.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var response = UrlFetchApp.fetch(IAP_URL, {
       headers: {
@@ -43,13 +43,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 OAuth2.createService('CloudIAPServiceAccount')
       // Set the endpoint URL.
       .setTokenUrl('https://accounts.google.com/o/oauth2/token')
diff --git a/samples/CloudIdentityAwareProxy.gs b/samples/CloudIdentityAwareProxy.gs
index e0eb40a2..f36cf73c 100644
--- a/samples/CloudIdentityAwareProxy.gs
+++ b/samples/CloudIdentityAwareProxy.gs
@@ -22,7 +22,7 @@ var IAP_URL = '...';
  * Identity-Aware Proxy.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var response = UrlFetchApp.fetch(IAP_URL, {
       headers: {
@@ -44,13 +44,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 OAuth2.createService('CloudIAP')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
@@ -85,7 +85,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!');
diff --git a/samples/DocuSign.gs b/samples/DocuSign.gs
index e0ab6b7c..8e72fa10 100644
--- a/samples/DocuSign.gs
+++ b/samples/DocuSign.gs
@@ -16,7 +16,7 @@ var OAUTH_HOST = 'account-d.docusign.com';
  * Authorizes and makes a request to the Docusign API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     // Retrieve the account ID and base URI from storage.
     var storage = service.getStorage();
@@ -43,13 +43,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 OAuth2.createService('DocuSign')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://' + OAUTH_HOST + '/oauth/auth')
@@ -82,7 +82,7 @@ function getService() {
  * Handles the OAuth callback.
  */
 function authCallback(request) {
-  var service = getService();
+  var service = getService_();
   var authorized = service.handleCallback(request);
   if (authorized) {
     // Get the user info to determine the ase URI and account ID needed for
diff --git a/samples/Domo.gs b/samples/Domo.gs
index 85242bcf..3fb69501 100644
--- a/samples/Domo.gs
+++ b/samples/Domo.gs
@@ -11,7 +11,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the Domo API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = 'https://api.domo.com/v1/users';
     var response = UrlFetchApp.fetch(url, {
@@ -30,13 +30,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 OAuth2.createService('Domo')
       // Set the endpoint URLs.
       .setTokenUrl('https://api.domo.com/oauth/token')
diff --git a/samples/Dropbox.gs b/samples/Dropbox.gs
index b6fa7509..79826b10 100644
--- a/samples/Dropbox.gs
+++ b/samples/Dropbox.gs
@@ -5,7 +5,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the Dropbox API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = 'https://api.dropboxapi.com/2/users/get_current_account';
     var response = UrlFetchApp.fetch(url, {
@@ -30,13 +30,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 OAuth2.createService('Dropbox')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://www.dropbox.com/oauth2/authorize')
@@ -61,7 +61,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!');
diff --git a/samples/Facebook.gs b/samples/Facebook.gs
index 5da7af50..71cc63a9 100644
--- a/samples/Facebook.gs
+++ b/samples/Facebook.gs
@@ -11,7 +11,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the Facebook API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = 'https://graph.facebook.com/v10.0/me';
     var response = UrlFetchApp.fetch(url, {
@@ -32,13 +32,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 OAuth2.createService('Facebook')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://www.facebook.com/dialog/oauth')
@@ -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) {
     return HtmlService.createHtmlOutput('Success!');
diff --git a/samples/FirebaseDB.gs b/samples/FirebaseDB.gs
index 04e78455..d2b0f55b 100644
--- a/samples/FirebaseDB.gs
+++ b/samples/FirebaseDB.gs
@@ -13,7 +13,7 @@ var CLIENT_EMAIL = '...';
  * Authorizes and makes a request to a Firebase Database.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = 'https://' + PROJECT_ID + '.firebaseio.com/.json?shallow=true';
     var response = UrlFetchApp.fetch(url, {
@@ -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_() {
   return OAuth2.createService('FirebaseDB')
       // Set the endpoint URL.
       .setTokenUrl('https://accounts.google.com/o/oauth2/token')
diff --git a/samples/FitBit.gs b/samples/FitBit.gs
index 1275c31b..44954d28 100644
--- a/samples/FitBit.gs
+++ b/samples/FitBit.gs
@@ -5,7 +5,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the FitBit API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = 'https://api.fitbit.com/1/user/-/profile.json';
     var response = UrlFetchApp.fetch(url, {
@@ -26,13 +26,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 OAuth2.createService('FitBit')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://www.fitbit.com/oauth2/authorize')
@@ -61,7 +61,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!');
diff --git a/samples/GitHub.gs b/samples/GitHub.gs
index 3f017fd5..4cb1fa2c 100644
--- a/samples/GitHub.gs
+++ b/samples/GitHub.gs
@@ -5,7 +5,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the GitHub API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = 'https://api.github.com/user/repos';
     var response = UrlFetchApp.fetch(url, {
@@ -26,13 +26,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 OAuth2.createService('GitHub')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://github.com/login/oauth/authorize')
@@ -54,7 +54,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!');
diff --git a/samples/Google.gs b/samples/Google.gs
index 13e23cea..70d67969 100644
--- a/samples/Google.gs
+++ b/samples/Google.gs
@@ -11,7 +11,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the Google Drive API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = 'https://www.googleapis.com/drive/v3/files?pageSize=1';
     var response = UrlFetchApp.fetch(url, {
@@ -32,13 +32,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 OAuth2.createService('Google')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/v2/auth')
@@ -66,7 +66,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!');
diff --git a/samples/GoogleHangoutsChat.gs b/samples/GoogleHangoutsChat.gs
index b8a47c8d..574dd25b 100644
--- a/samples/GoogleHangoutsChat.gs
+++ b/samples/GoogleHangoutsChat.gs
@@ -9,7 +9,7 @@ var CLIENT_EMAIL = '...';
  * https://codelabs.developers.google.com/codelabs/chat-apps-script/
  */
 function sendPushMessage() {
-  var service = getChatbotService();
+  var service = getChatbotService_();
   if (service.hasAccess()) {
     // We retrieve all the spaces bot has been added
     var url = 'https://chat.googleapis.com/v1/spaces';
@@ -51,7 +51,7 @@ function sendPushMessage() {
  * Reset the authorization state, so that it can be re-tested.
  */
 function reset() {
-  getChatbotService().reset();
+  getChatbotService_().reset();
 }
 
 
@@ -60,7 +60,7 @@ function reset() {
  * For service account setup follow Step 1 on this page
  * https://developers.google.com/hangouts/chat/how-tos/service-accounts
  */
-function getChatbotService() {
+function getChatbotService_() {
   return OAuth2.createService('MyChatBot')
       // Set the endpoint URL.
       .setTokenUrl('https://oauth2.googleapis.com/token')
diff --git a/samples/GoogleServiceAccount.gs b/samples/GoogleServiceAccount.gs
index d9161283..4d96ac47 100644
--- a/samples/GoogleServiceAccount.gs
+++ b/samples/GoogleServiceAccount.gs
@@ -16,7 +16,7 @@ var USER_EMAIL = '...';
  * Authorizes and makes a request to the Google Drive API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = 'https://www.googleapis.com/drive/v3/files?pageSize=1';
     var response = UrlFetchApp.fetch(url, {
@@ -35,13 +35,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 OAuth2.createService('GoogleDrive:' + USER_EMAIL)
       // Set the endpoint URL.
       .setTokenUrl('https://oauth2.googleapis.com/token')
diff --git a/samples/Harvest.gs b/samples/Harvest.gs
index 7abab4c5..af366f84 100644
--- a/samples/Harvest.gs
+++ b/samples/Harvest.gs
@@ -5,7 +5,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the Harvest API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     // Retrieve the account ID from storage.
     var accountId = service.getStorage().getValue('Harvest-Account-Id');
@@ -30,13 +30,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 OAuth2.createService('Harvest')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://id.getharvest.com/oauth2/authorize')
@@ -59,7 +59,7 @@ function getService() {
  * Handles the OAuth callback.
  */
 function authCallback(request) {
-  var service = getService();
+  var service = getService_();
   var authorized = service.handleCallback(request);
   if (authorized) {
     // Gets the authorized account ID from the scope string. Assumes the
diff --git a/samples/HubSpot.gs b/samples/HubSpot.gs
index 38e4b0eb..3216225f 100644
--- a/samples/HubSpot.gs
+++ b/samples/HubSpot.gs
@@ -11,7 +11,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the HubSpot API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     // Make a request to retrieve the list of CRM owners.
     var url = 'https://api.hubapi.com/crm/v3/owners/';
@@ -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 OAuth2.createService('HubSpot')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://app.hubspot.com/oauth/authorize')
@@ -66,7 +66,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!');
diff --git a/samples/IdentityServer4.gs b/samples/IdentityServer4.gs
index 26f9a45b..cdec26c0 100644
--- a/samples/IdentityServer4.gs
+++ b/samples/IdentityServer4.gs
@@ -16,7 +16,7 @@ var CLIENT_SECRET = 'secret';
  * Authorizes and makes a request to the IdentityServer4 Demo API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = 'https://demo.identityserver.io/api/test';
     var response = UrlFetchApp.fetch(url, {
@@ -37,13 +37,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 OAuth2.createService('IdentityServer4')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://demo.identityserver.io/connect/authorize')
@@ -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!');
diff --git a/samples/Jira.gs b/samples/Jira.gs
index ee12a825..03f36994 100644
--- a/samples/Jira.gs
+++ b/samples/Jira.gs
@@ -14,7 +14,7 @@ var CLOUDID_KEY = 'cloudid';
  * Authorizes and makes a request to the UltraCart API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var cloudid = getCloudId(service);
     var url = 'https://api.atlassian.com/ex/jira/' + cloudid +
@@ -63,13 +63,13 @@ function getCloudId(service) {
  * 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 OAuth2.createService('Jira')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://auth.atlassian.com/authorize')
@@ -96,7 +96,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!');
diff --git a/samples/LINE.gs b/samples/LINE.gs
index 41dffbb0..91630704 100644
--- a/samples/LINE.gs
+++ b/samples/LINE.gs
@@ -11,7 +11,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the Line API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = 'https://api.line.me/v2/profile';
     var response = UrlFetchApp.fetch(url, {
@@ -32,13 +32,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 OAuth2.createService('LINE')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://access.line.me/oauth2/v2.1/authorize')
@@ -63,7 +63,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!');
diff --git a/samples/LinkedIn.gs b/samples/LinkedIn.gs
index fd444b0d..d19004e3 100644
--- a/samples/LinkedIn.gs
+++ b/samples/LinkedIn.gs
@@ -5,7 +5,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the LinkedIn API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = 'https://api.linkedin.com/v1/people/~?format=json';
     var response = UrlFetchApp.fetch(url, {
@@ -26,13 +26,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 OAuth2.createService('LinkedIn')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl(
@@ -58,7 +58,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!');
diff --git a/samples/Mailchimp.gs b/samples/Mailchimp.gs
index 47e90100..5a693ba3 100644
--- a/samples/Mailchimp.gs
+++ b/samples/Mailchimp.gs
@@ -11,7 +11,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the Docusign API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     // Retrieve the account ID and base URI from storage.
     var storage = service.getStorage();
@@ -37,13 +37,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 OAuth2.createService('Mailchimp')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://login.mailchimp.com/oauth2/authorize')
@@ -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) {
     // Get the user info to determine the data center needed for
diff --git a/samples/Meetup.gs b/samples/Meetup.gs
index d429cc50..f9a72f14 100644
--- a/samples/Meetup.gs
+++ b/samples/Meetup.gs
@@ -11,7 +11,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the Meetup API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = 'https://api.meetup.com/dashboard';
     var response = UrlFetchApp.fetch(url, {
@@ -32,13 +32,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 OAuth2.createService('Meetup')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://secure.meetup.com/oauth2/authorize')
@@ -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) {
     return HtmlService.createHtmlOutput('Success!');
diff --git a/samples/Notion.gs b/samples/Notion.gs
index 20566edf..9b3b80b5 100644
--- a/samples/Notion.gs
+++ b/samples/Notion.gs
@@ -5,7 +5,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the Notion API - https://developers.notion.com/reference/intro
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = 'https://api.notion.com/v1/search'; // refer https://developers.notion.com/reference/post-search
     var options = {
@@ -30,13 +30,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 OAuth2.createService('Notion')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://api.notion.com/v1/oauth/authorize')
@@ -63,7 +63,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!');
diff --git a/samples/QuickBooks.gs b/samples/QuickBooks.gs
index d23ebce6..e7efd130 100644
--- a/samples/QuickBooks.gs
+++ b/samples/QuickBooks.gs
@@ -13,7 +13,7 @@ var CLIENT_SECRET = '';
  * https://developer.intuit.com/v2/ui#/app//keys
  */
 function logRedirectUri() {
-  Logger.log(getService().getRedirectUri());
+  Logger.log(getService_().getRedirectUri());
 }
 
 /**
@@ -21,7 +21,7 @@ function logRedirectUri() {
  * sandbox company.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     // Get the Company ID to be used in the request.
     var companyId = service.getStorage().getValue('QuickBooks.companyId');
@@ -49,14 +49,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 OAuth2.createService('Quickbooks')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://appcenter.intuit.com/connect/oauth2')
@@ -78,7 +78,7 @@ function getService() {
  * Handles the OAuth callback.
  */
 function authCallback(request) {
-  var service = getService();
+  var service = getService_();
   var authorized = service.handleCallback(request);
   if (authorized) {
     // Save the Company ID in the service's storage.
diff --git a/samples/RingCentral.gs b/samples/RingCentral.gs
index 23eec69e..3abd4565 100644
--- a/samples/RingCentral.gs
+++ b/samples/RingCentral.gs
@@ -14,7 +14,7 @@ var SERVER = 'https://platform.devtest.ringcentral.com';
  * Authorizes and makes a request to the RingCentral API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = SERVER + '/restapi/v1.0/account/~';
     var response = UrlFetchApp.fetch(url, {
@@ -35,13 +35,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 OAuth2.createService('RingCentral')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl(SERVER + '/restapi/oauth/authorize')
@@ -69,7 +69,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!');
diff --git a/samples/Salesforce.gs b/samples/Salesforce.gs
index e6dfed4c..d061a118 100644
--- a/samples/Salesforce.gs
+++ b/samples/Salesforce.gs
@@ -10,7 +10,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the Saleforce API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = service.getToken().instance_url +
         '/services/data/v24.0/chatter/users/me';
@@ -60,13 +60,13 @@ function withRetry(service, func) {
  * 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 OAuth2.createService('Saleforce')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl(
@@ -92,7 +92,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!');
diff --git a/samples/Smartsheet.gs b/samples/Smartsheet.gs
index 2a9134cb..d5e7b48f 100644
--- a/samples/Smartsheet.gs
+++ b/samples/Smartsheet.gs
@@ -5,7 +5,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the Smartsheet API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = 'https://api.smartsheet.com/2.0/users/me';
     var response = UrlFetchApp.fetch(url, {
@@ -26,13 +26,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 OAuth2.createService('Smartsheet')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://app.smartsheet.com/b/authorize')
@@ -61,7 +61,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!');
diff --git a/samples/Spotify.gs b/samples/Spotify.gs
index 8f5f053b..3bfdac1c 100644
--- a/samples/Spotify.gs
+++ b/samples/Spotify.gs
@@ -11,7 +11,7 @@ var CLIENT_SECRET = '...';
 * Authorizes and makes a request to the Spotify API.
 */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = 'https://api.spotify.com/v1/me';
     var response = UrlFetchApp.fetch(url, {
@@ -30,13 +30,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 OAuth2.createService('Spotify')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://accounts.spotify.com/authorize')
@@ -58,7 +58,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!');
diff --git a/samples/StackOverflow.gs b/samples/StackOverflow.gs
index 3cc446df..764ed222 100644
--- a/samples/StackOverflow.gs
+++ b/samples/StackOverflow.gs
@@ -12,7 +12,7 @@ var KEY = '...';
  * Authorizes and makes a request to the Stack Overflow API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = `https://api.stackexchange.com/2.3/me?site=stackoverflow&key=${KEY}&access_token=${service.getAccessToken()}`;
     var response = UrlFetchApp.fetch(url);
@@ -29,13 +29,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 OAuth2.createService('Stack Overflow')
     // Set the endpoint URLs.
     .setAuthorizationBaseUrl('https://stackoverflow.com/oauth')
@@ -57,7 +57,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!');
diff --git a/samples/Tink.gs b/samples/Tink.gs
index d4937eac..775fbf0f 100644
--- a/samples/Tink.gs
+++ b/samples/Tink.gs
@@ -11,7 +11,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the Tink API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     // Make a request to retrieve user information.
     var url = 'https://api.tink.com/api/v1/user';
@@ -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_() {
   var service = OAuth2.createService('Tink')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://link.tink.com/1.0/authorize/')
@@ -88,7 +88,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!');
diff --git a/samples/Twitter.gs b/samples/Twitter.gs
index f05814cb..24eec571 100644
--- a/samples/Twitter.gs
+++ b/samples/Twitter.gs
@@ -7,7 +7,7 @@ var CLIENT_SECRET = '...';
  * https://developer.twitter.com/en/docs/authentication/oauth-2-0/user-access-token
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     // https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-by-username-username
     var url = `https://api.twitter.com/2/users/by/username/workspacedevs?user.fields=verified`;
@@ -30,7 +30,7 @@ function run() {
  * Reset the authorization state, so that it can be re-tested.
  */
 function reset() {
-  getService().reset();
+  getService_().reset();
   PropertiesService.getUserProperties().deleteProperty("code_challenge");
   PropertiesService.getUserProperties().deleteProperty("code_verifier");
 }
@@ -38,7 +38,7 @@ function reset() {
 /**
  * Configures the service.
  */
-function getService() {
+function getService_() {
   pkceChallengeVerifier();
   var userProps = PropertiesService.getUserProperties();
   return OAuth2.createService('Twitter')
@@ -76,7 +76,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!');
diff --git a/samples/TwitterAppOnly.gs b/samples/TwitterAppOnly.gs
index 234cee9b..3e9ba39f 100644
--- a/samples/TwitterAppOnly.gs
+++ b/samples/TwitterAppOnly.gs
@@ -13,7 +13,7 @@ var CLIENT_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/users/show.json?screen_name=googleworkspace';
     var response = UrlFetchApp.fetch(url, {
@@ -32,13 +32,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 OAuth2.createService('Twitter App Only')
       // Set the endpoint URLs.
       .setTokenUrl('https://api.twitter.com/oauth2/token')
diff --git a/samples/UltraCart.gs b/samples/UltraCart.gs
index b7a47cf9..709dfc31 100644
--- a/samples/UltraCart.gs
+++ b/samples/UltraCart.gs
@@ -10,7 +10,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the UltraCart API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = 'https://secure.ultracart.com/rest/v2/customer/customers';
     var response = UrlFetchApp.fetch(url, {
@@ -32,13 +32,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 OAuth2.createService('UltaCart')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://secure.ultracart.com/rest/v2/oauth/authorize')
@@ -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) {
     return HtmlService.createHtmlOutput('Success!');
diff --git a/samples/VK.gs b/samples/VK.gs
index dc7aea37..e29cbfc2 100644
--- a/samples/VK.gs
+++ b/samples/VK.gs
@@ -10,7 +10,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the VK API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     // GET requests require access_token parameter
 
@@ -36,13 +36,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 OAuth2.createService('VK')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://oauth.vk.com/authorize')
@@ -67,7 +67,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!');
diff --git a/samples/WebApp/Code.gs b/samples/WebApp/Code.gs
index 0677fbc6..eb2fbe2f 100644
--- a/samples/WebApp/Code.gs
+++ b/samples/WebApp/Code.gs
@@ -26,7 +26,7 @@
  * project file.
  */
 function doGet() {
-  var service = getGitHubService();
+  var service = getGitHubService_();
   var template = HtmlService.createTemplateFromFile('Page');
   template.email = Session.getEffectiveUser().getEmail();
   template.isSignedIn = service.hasAccess();
@@ -40,7 +40,7 @@ function doGet() {
  * @return {String} The authorization URL.
  */
 function getAuthorizationUrl() {
-  return getGitHubService().getAuthorizationUrl();
+  return getGitHubService_().getAuthorizationUrl();
 }
 
 /**
@@ -48,7 +48,7 @@ function getAuthorizationUrl() {
  * additional authorization-required API calls can be made.
  */
 function signOut() {
-  getGitHubService().reset();
+  getGitHubService_().reset();
 }
 
 /**
@@ -69,7 +69,7 @@ function getGitHubRepos() {
  * Fetches the specified resource from the GitHub API.
  */
 function getGitHubResource(resource) {
-  var service = getGitHubService();
+  var service = getGitHubService_();
   if (!service.hasAccess()) {
     throw new Error('Error: Missing GitHub authorization.');
   }
@@ -86,7 +86,7 @@ function getGitHubResource(resource) {
  * Gets an OAuth2 service configured for the GitHub API.
  * @return {OAuth2.Service} The OAuth2 service
  */
-function getGitHubService() {
+function getGitHubService_() {
   return OAuth2.createService('github')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://github.com/login/oauth/authorize')
@@ -115,7 +115,7 @@ function authCallback(request) {
   template.error = null;
   var title;
   try {
-    var service = getGitHubService();
+    var service = getGitHubService_();
     var authorized = service.handleCallback(request);
     template.isSignedIn = authorized;
     title = authorized ? 'Access Granted' : 'Access Denied';
diff --git a/samples/Wordpress.gs b/samples/Wordpress.gs
index 309039e6..26b096fc 100644
--- a/samples/Wordpress.gs
+++ b/samples/Wordpress.gs
@@ -5,7 +5,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the Wordpress API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var blogId = service.getToken().blog_id;
     var url = 'https://public-api.wordpress.com/rest/v1.1/sites/' + blogId + '/posts';
@@ -27,13 +27,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 OAuth2.createService('Wordpress')
       // Set the endpoint URLs.
       .setTokenUrl('https://public-api.wordpress.com/oauth2/token')
@@ -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!');
diff --git a/samples/Xero.gs b/samples/Xero.gs
index e1fbf337..3c7afbff 100644
--- a/samples/Xero.gs
+++ b/samples/Xero.gs
@@ -11,7 +11,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the Xero API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     // Retrieve the tenantId from storage.
     var tenantId = service.getStorage().getValue('tenantId');
@@ -36,13 +36,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 OAuth2.createService('Xero')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl(
@@ -70,7 +70,7 @@ function getService() {
  * Handles the OAuth callback.
  */
 function authCallback(request) {
-  var service = getService();
+  var service = getService_();
   var authorized = service.handleCallback(request);
   if (authorized) {
     // Retrieve the connected tenants.
diff --git a/samples/Yahoo.gs b/samples/Yahoo.gs
index c22f5885..8a28d7c0 100644
--- a/samples/Yahoo.gs
+++ b/samples/Yahoo.gs
@@ -11,7 +11,7 @@ var CLIENT_SECRET = '...';
 * Authorizes and makes a request to the Yahoo API.
 */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = 'https://social.yahooapis.com/v1/user/me/profile?format=json';
     var response = UrlFetchApp.fetch(url, {
@@ -32,13 +32,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 OAuth2.createService('Yahoo')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://api.login.yahoo.com/oauth2/request_auth')
@@ -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) {
     return HtmlService.createHtmlOutput('Success!');
diff --git a/samples/Yandex.gs b/samples/Yandex.gs
index 6c2a3823..fe64556e 100644
--- a/samples/Yandex.gs
+++ b/samples/Yandex.gs
@@ -10,7 +10,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the Yandex Passport API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = 'https://login.yandex.ru/info';
     var response = UrlFetchApp.fetch(url, {
@@ -31,13 +31,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 OAuth2.createService('Yandex')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://oauth.yandex.ru/authorize')
@@ -59,7 +59,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!');
diff --git a/samples/Zendesk.gs b/samples/Zendesk.gs
index ec9a3b8a..ee935ade 100644
--- a/samples/Zendesk.gs
+++ b/samples/Zendesk.gs
@@ -11,7 +11,7 @@ var SUBDOMAIN = '...';
  * Authorizes and makes a request to the Zendesk API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = 'https://'
         .concat(SUBDOMAIN, '.zendesk.com/api/v2/tickets/recent.json');
@@ -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 OAuth2.createService('Zendesk')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl(
@@ -65,7 +65,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!');
diff --git a/samples/ZohoCRM.gs b/samples/ZohoCRM.gs
index 08637e05..7428cdb3 100644
--- a/samples/ZohoCRM.gs
+++ b/samples/ZohoCRM.gs
@@ -10,7 +10,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the Zoho CRM API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     // Retrieve the API server from the token.
     var apiServer = service.getToken().api_domain;
@@ -33,7 +33,7 @@ function run() {
  * Reset the authorization state, so that it can be re-tested.
  */
 function reset() {
-  getService().reset();
+  getService_().reset();
 }
 
 /**
@@ -41,7 +41,7 @@ function reset() {
  * @param {string} optAccountServer The account server to use when requesting
  *     tokens.
  */
-function getService(optAccountServer) {
+function getService_(optAccountServer) {
   var service = OAuth2.createService('Zoho')
       // Set the authorization base URL.
       .setAuthorizationBaseUrl('https://accounts.zoho.com/oauth/v2/auth')
@@ -81,7 +81,7 @@ function getService(optAccountServer) {
  */
 function authCallback(request) {
   var accountServer = request.parameter['accounts-server'];
-  var service = getService(accountServer);
+  var service = getService_(accountServer);
   var authorized = service.handleCallback(request);
   if (authorized) {
     // Save the account server in the service's storage.
diff --git a/samples/Zoom.gs b/samples/Zoom.gs
index 3d0ee067..dad74e94 100644
--- a/samples/Zoom.gs
+++ b/samples/Zoom.gs
@@ -12,7 +12,7 @@ var CLIENT_SECRET = '...';
  * Authorizes and makes a request to the Zoom API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     var url = 'https://api.zoom.us/v2/users/me';
     var response = UrlFetchApp.fetch(url, {
@@ -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 OAuth2.createService('Zoom')
       // Set the endpoint URLs.
       .setAuthorizationBaseUrl('https://zoom.us/oauth/authorize')
@@ -72,7 +72,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!');
diff --git a/samples/eBay.gs b/samples/eBay.gs
index 01cd9cde..a8bf584d 100644
--- a/samples/eBay.gs
+++ b/samples/eBay.gs
@@ -13,7 +13,7 @@ var RU_NAME = '...'; // eBay Redirect URL name.
  * Authorizes and makes a request to the Ebay API.
  */
 function run() {
-  var service = getService();
+  var service = getService_();
   if (service.hasAccess()) {
     // Sandbox environment.
     var url = 'https://api.sandbox.ebay.com/sell/inventory/v1/inventory_item';
@@ -35,13 +35,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 OAuth2.createService('eBay')
       // Set the endpoint URLs (sandbox environment).
       .setTokenUrl('https://api.sandbox.ebay.com/identity/v1/oauth2/token')
@@ -75,7 +75,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!');