diff --git a/app/scripts/const/default-app-settings.js b/app/scripts/const/default-app-settings.js index f0cf345c..cc7e9a5c 100644 --- a/app/scripts/const/default-app-settings.js +++ b/app/scripts/const/default-app-settings.js @@ -46,6 +46,7 @@ const DefaultAppSettings = { deviceOwnerAuth: null, // Touch ID: null / 'memory' / 'file' deviceOwnerAuthTimeoutMinutes: 0, // how often master password is required with Touch ID disableOfflineStorage: false, // don't cache loaded files in offline storage + shortLivedStorageToken: false, // short-lived sessions in cloud storage providers yubiKeyShowIcon: true, // show an icon to open OTP codes from YubiKey yubiKeyAutoOpen: false, // auto-load one-time codes when there are open files diff --git a/app/scripts/locales/base.json b/app/scripts/locales/base.json index 2939387a..b5db4085 100644 --- a/app/scripts/locales/base.json +++ b/app/scripts/locales/base.json @@ -455,6 +455,7 @@ "setGenLockOrSleep": "When the computer is locked or put to sleep", "setGenStorage": "Storage", "setGenDisableOfflineStorage": "Don't cache loaded files in offline storage", + "setGenShortLivedStorageToken": "Use short-lived sessions in cloud storage providers", "setGenStorageLogout": "Log out", "setGenShowAdvanced": "Show advanced settings", "setGenDevTools": "Show dev tools", diff --git a/app/scripts/storage/impl/storage-dropbox.js b/app/scripts/storage/impl/storage-dropbox.js index e20f04b8..3482d966 100644 --- a/app/scripts/storage/impl/storage-dropbox.js +++ b/app/scripts/storage/impl/storage-dropbox.js @@ -83,7 +83,9 @@ class StorageDropbox extends StorageBase { pkce: true, width: 600, height: 400, - urlParams: { 'token_access_type': 'offline' } + urlParams: this.appSettings.shortLivedStorageToken + ? {} + : { 'token_access_type': 'offline' } }; } diff --git a/app/scripts/storage/impl/storage-gdrive.js b/app/scripts/storage/impl/storage-gdrive.js index 4b1dd809..7403ebc3 100644 --- a/app/scripts/storage/impl/storage-gdrive.js +++ b/app/scripts/storage/impl/storage-gdrive.js @@ -254,9 +254,9 @@ class StorageGDrive extends StorageBase { width: 600, height: 400, pkce: true, - redirectUrlParams: { - 'access_type': 'offline' - } + redirectUrlParams: this.appSettings.shortLivedStorageToken + ? {} + : { 'access_type': 'offline' } }; } } diff --git a/app/scripts/storage/impl/storage-onedrive.js b/app/scripts/storage/impl/storage-onedrive.js index b8995333..c96b0baf 100644 --- a/app/scripts/storage/impl/storage-onedrive.js +++ b/app/scripts/storage/impl/storage-onedrive.js @@ -230,10 +230,14 @@ class StorageOneDrive extends StorageBase { ({ id: clientId, secret: clientSecret } = OneDriveApps.Production); } } + let scope = 'files.readwrite'; + if (!this.appSettings.shortLivedStorageToken) { + scope += ' offline_access'; + } return { url: 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize', tokenUrl: 'https://login.microsoftonline.com/common/oauth2/v2.0/token', - scope: 'files.readwrite offline_access', + scope, clientId, clientSecret, pkce: true, diff --git a/app/scripts/storage/storage-base.js b/app/scripts/storage/storage-base.js index 85a421f3..e7d10c90 100644 --- a/app/scripts/storage/storage-base.js +++ b/app/scripts/storage/storage-base.js @@ -50,6 +50,10 @@ class StorageBase { logout() {} + deleteStoredToken() { + delete this.runtimeData[this.name + 'OAuthToken']; + } + _xhr(config) { this.logger.info('HTTP request', config.method || 'GET', config.url); if (config.data) { @@ -315,7 +319,9 @@ class StorageBase { const token = this._oauthMsgToToken(message); if (token && !token.error) { this._oauthToken = token; - this.runtimeData[this.name + 'OAuthToken'] = token; + if (!this.appSettings.shortLivedStorageToken) { + this.runtimeData[this.name + 'OAuthToken'] = token; + } this.logger.debug('OAuth token received'); } return token; @@ -343,7 +349,9 @@ class StorageBase { _oauthGetNewToken(callback) { this._oauthToken.expired = true; - this.runtimeData[this.name + 'OAuthToken'] = this._oauthToken; + if (!this.appSettings.shortLivedStorageToken) { + this.runtimeData[this.name + 'OAuthToken'] = this._oauthToken; + } if (this._oauthToken.refreshToken) { this._oauthExchangeRefreshToken(callback); } else { diff --git a/app/scripts/views/settings/settings-general-view.js b/app/scripts/views/settings/settings-general-view.js index 6f412d0a..f287ccda 100644 --- a/app/scripts/views/settings/settings-general-view.js +++ b/app/scripts/views/settings/settings-general-view.js @@ -62,6 +62,7 @@ class SettingsGeneralView extends View { 'click .settings__general-download-update-btn': 'downloadUpdate', 'click .settings__general-update-found-btn': 'installFoundUpdate', 'change .settings__general-disable-offline-storage': 'changeDisableOfflineStorage', + 'change .settings__general-short-lived-storage-token': 'changeShortLivedStorageToken', 'change .settings__general-prv-check': 'changeStorageEnabled', 'click .settings__general-prv-logout': 'logoutFromStorage', 'click .settings__general-show-advanced': 'showAdvancedSettings', @@ -142,7 +143,8 @@ class SettingsGeneralView extends View { hasDeviceOwnerAuth: Features.isDesktop && Features.isMac, deviceOwnerAuth: AppSettingsModel.deviceOwnerAuth, deviceOwnerAuthTimeout: AppSettingsModel.deviceOwnerAuthTimeoutMinutes, - disableOfflineStorage: AppSettingsModel.disableOfflineStorage + disableOfflineStorage: AppSettingsModel.disableOfflineStorage, + shortLivedStorageToken: AppSettingsModel.shortLivedStorageToken }); this.renderProviderViews(storageProviders); } @@ -486,6 +488,16 @@ class SettingsGeneralView extends View { } } + changeShortLivedStorageToken(e) { + const shortLivedStorageToken = e.target.checked; + AppSettingsModel.shortLivedStorageToken = shortLivedStorageToken; + if (shortLivedStorageToken) { + for (const storage of Object.values(Storage)) { + storage.deleteStoredToken(); + } + } + } + changeStorageEnabled(e) { const storage = Storage[$(e.target).data('storage')]; if (storage) { diff --git a/app/templates/settings/settings-general.hbs b/app/templates/settings/settings-general.hbs index 06568907..457e45fc 100644 --- a/app/templates/settings/settings-general.hbs +++ b/app/templates/settings/settings-general.hbs @@ -312,6 +312,11 @@ {{#if disableOfflineStorage}}checked{{/if}} /> +
+ + +
{{#each storageProviders as |prv|}}