Skip to content

Commit e590134

Browse files
author
Eric Koleda
authored
Don't require token storage in properties (#220)
* Make properties optional. * Add simple tests for no properties * Fix lint errors.
1 parent 70c337d commit e590134

File tree

5 files changed

+64
-17
lines changed

5 files changed

+64
-17
lines changed

README.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ function getDriveService() {
128128

129129
// Requests offline access.
130130
.setParam('access_type', 'offline')
131-
131+
132132
// Consent prompt is required to ensure a refresh token is always
133133
// returned when requesting offline access.
134134
.setParam('prompt', 'consent');
@@ -215,6 +215,36 @@ function logout() {
215215

216216
## Best practices
217217

218+
### Token storage
219+
220+
In almost all cases you'll want to persist the OAuth tokens after you retrieve
221+
them. This prevents having to request access from the user every time you want
222+
to call the API. To do so, make sure you set a properties store when you define
223+
your service:
224+
225+
```js
226+
return OAuth2.createService('Foo')
227+
.setPropertyStore(PropertiesService.getUserProperties())
228+
// ...
229+
```
230+
231+
Apps Script has [property stores][property_stores] scoped to the user, script,
232+
or document. In most cases you'll want to choose user-scoped properties, as it
233+
is most common to have each user of your script authorize access to their own
234+
account. However there are uses cases where you'd want to authorize access to
235+
a shared resource and then have all users of the script (or on the same
236+
document) share that access.
237+
238+
When using a service account or 2-legged OAuth flow, where users aren't prompted
239+
for authorization, storing tokens is still beneficial as there can be rate
240+
limits on generating new tokens. However there are edge cases where you need to
241+
generate lots of different tokens in a short amount of time, and persisting
242+
those tokens to properties can exceed your `PropertiesService` quota. In those
243+
cases you can omit any form of token storage and just retrieve new ones as
244+
needed.
245+
246+
[property_stores]: https://developers.google.com/apps-script/reference/properties/properties-service
247+
218248
### Caching
219249

220250
Scripts that use the library heavily should enable caching on the service, so as

package-lock.json

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Service.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -607,9 +607,6 @@ Service_.prototype.refresh = function() {
607607
* @return {Storage} The service's storage.
608608
*/
609609
Service_.prototype.getStorage = function() {
610-
validate_({
611-
'Property store': this.propertyStore_
612-
});
613610
if (!this.storage_) {
614611
var prefix = 'oauth2.' + this.serviceName_;
615612
this.storage_ = new Storage_(prefix, this.propertyStore_, this.cache_);

src/Storage.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@
2121
* related information.
2222
* @param {string} prefix The prefix to use for keys in the properties and
2323
* cache.
24-
* @param {PropertiesService.Properties} properties The properties instance to
25-
* use.
24+
* @param {PropertiesService.Properties} optProperties The optional properties
25+
* instance to use.
2626
* @param {CacheService.Cache} [optCache] The optional cache instance to use.
2727
* @constructor
2828
*/
29-
function Storage_(prefix, properties, optCache) {
29+
function Storage_(prefix, optProperties, optCache) {
3030
this.prefix_ = prefix;
31-
this.properties_ = properties;
31+
this.properties_ = optProperties;
3232
this.cache_ = optCache;
3333
this.memory_ = {};
3434
}
@@ -80,7 +80,8 @@ Storage_.prototype.getValue = function(key, optSkipMemoryCheck) {
8080
}
8181

8282
// Check properties.
83-
if (jsonValue = this.properties_.getProperty(prefixedKey)) {
83+
if (this.properties_ &&
84+
(jsonValue = this.properties_.getProperty(prefixedKey))) {
8485
if (this.cache_) {
8586
this.cache_.put(prefixedKey,
8687
jsonValue, Storage_.CACHE_EXPIRATION_TIME_SECONDS);
@@ -108,7 +109,9 @@ Storage_.prototype.getValue = function(key, optSkipMemoryCheck) {
108109
Storage_.prototype.setValue = function(key, value) {
109110
var prefixedKey = this.getPrefixedKey_(key);
110111
var jsonValue = JSON.stringify(value);
111-
this.properties_.setProperty(prefixedKey, jsonValue);
112+
if (this.properties_) {
113+
this.properties_.setProperty(prefixedKey, jsonValue);
114+
}
112115
if (this.cache_) {
113116
this.cache_.put(prefixedKey, jsonValue,
114117
Storage_.CACHE_EXPIRATION_TIME_SECONDS);
@@ -122,7 +125,9 @@ Storage_.prototype.setValue = function(key, value) {
122125
*/
123126
Storage_.prototype.removeValue = function(key) {
124127
var prefixedKey = this.getPrefixedKey_(key);
125-
this.properties_.deleteProperty(prefixedKey);
128+
if (this.properties_) {
129+
this.properties_.deleteProperty(prefixedKey);
130+
}
126131
if (this.cache_) {
127132
this.cache_.remove(prefixedKey);
128133
}

test/test.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,12 @@ describe('Service', function() {
141141
assert.equal(cache.counter, cacheStart);
142142
assert.equal(properties.counter, propertiesStart);
143143
});
144+
145+
it('should not fail if no properties are set',
146+
function() {
147+
var service = OAuth2.createService('test');
148+
service.getToken();
149+
});
144150
});
145151

146152
describe('#saveToken_()', function() {
@@ -159,6 +165,15 @@ describe('Service', function() {
159165
assert.deepEqual(JSON.parse(cache.get(key)), token);
160166
assert.deepEqual(JSON.parse(properties.getProperty(key)), token);
161167
});
168+
169+
it('should not fail if no properties are set',
170+
function() {
171+
var service = OAuth2.createService('test');
172+
var token = {
173+
access_token: 'foo'
174+
};
175+
service.saveToken_(token);
176+
});
162177
});
163178

164179
describe('#reset()', function() {

0 commit comments

Comments
 (0)