UNPKG

nebulab-dropbox

Version:
161 lines (146 loc) 6.86 kB
# OAuth driver code common to Chrome apps and extensions. # # @private # Application code should use {Dropbox.AuthDriver.ChromeApp} or # {Dropbox.AuthDriver.ChromeExtension}. class Dropbox.AuthDriver.ChromeBase extends Dropbox.AuthDriver.BrowserBase # Sets up an OAuth driver for Chrome. # # @param {Object} options (optional) one or more of the options below # @option options {String} scope embedded in the chrome.storage.local key # that holds the authentication data; useful for having multiple OAuth # tokens in a single application constructor: (options) -> super options @storageKey = "dropbox_js_#{@scope}_credentials" # Saves token information when appropriate. onAuthStepChange: (client, callback) -> switch client.authStep when Dropbox.Client.RESET @loadCredentials (credentials) -> client.setCredentials credentials if credentials callback() when Dropbox.Client.DONE @storeCredentials client.credentials(), callback when Dropbox.Client.SIGNED_OUT @forgetCredentials callback when Dropbox.Client.ERROR @forgetCredentials callback else callback() # URL of the redirect receiver page that messages the app / extension. # # @see Dropbox.AuthDriver#url url: -> @receiverUrl # Stores a Dropbox.Client's credentials in chrome.storage.local. # # @private # onAuthStepChange calls this method during the authentication flow. # # @param {Object} credentials the result of a Drobpox.Client#credentials call # @param {function()} callback called when the storing operation is complete # @return {Dropbox.AuthDriver.BrowserBase} this, for easy call chaining storeCredentials: (credentials, callback) -> items= {} items[@storageKey] = credentials chrome.storage.local.set items, callback @ # Retrieves a token and secret from chrome.storage.local. # # @private # onAuthStepChange calls this method during the authentication flow. # # @param {function(?Object)} callback supplied with the credentials object # stored by a previous call to # Dropbox.AuthDriver.BrowserBase#storeCredentials; null if no credentials # were stored, or if the previously stored credentials were deleted # @return {Dropbox.AuthDriver.BrowserBase} this, for easy call chaining loadCredentials: (callback) -> chrome.storage.local.get @storageKey, (items) => callback items[@storageKey] or null @ # Deletes information previously stored by a call to storeCredentials. # # @private # onAuthStepChange calls this method during the authentication flow. # # @param {function()} callback called after the credentials are deleted # @return {Dropbox.AuthDriver.BrowserBase} this, for easy call chaining forgetCredentials: (callback) -> chrome.storage.local.remove @storageKey, callback @ # OAuth driver code specific to Chrome packaged applications. # # @see http://developer.chrome.com/apps/about_apps.html class Dropbox.AuthDriver.ChromeApp extends Dropbox.AuthDriver.ChromeBase # Sets up an OAuth driver for a Chrome packaged application. # # @param {Object} options (optional) one or more of the options below # @option options {String} scope embedded in the chrome.storage.local key # that holds the authentication data; useful for having multiple OAuth # tokens in a single application constructor: (options) -> super options @receiverUrl = "https://#{chrome.runtime.id}.chromiumapp.org/" # Uses the Chrome identity API to drive the OAuth 2 flow. # # @see Dropbox.AuthDriver#doAuthorize # @see http://developer.chrome.com/apps/identity.html doAuthorize: (authUrl, stateParam, client, callback) -> chrome.identity.launchWebAuthFlow url: authUrl, interactive: true, (redirectUrl) => if @locationStateParam(redirectUrl) is stateParam stateParam = false # Avoid having this matched in the future. callback Dropbox.Util.Oauth.queryParamsFromUrl(redirectUrl) # OAuth driver code specific to Chrome extensions. class Dropbox.AuthDriver.ChromeExtension extends Dropbox.AuthDriver.ChromeBase # Sets up an OAuth driver for a Chrome extension. # # @param {Object} options (optional) one or more of the options below # @option options {String} scope embedded in the chrome.storage.local key # that holds the authentication data; useful for having multiple OAuth # tokens in a single application # @option options {String} receiverPath the path of page that receives the # /authorize redirect and calls {Dropbox.AuthDriver.Chrome.oauthReceiver}; # the path should be relative to the extension folder; by default, is # 'chrome_oauth_receiver.html' constructor: (options) -> super options receiverPath = (options and options.receiverPath) or 'chrome_oauth_receiver.html' @receiverUrl = chrome.runtime.getURL receiverPath # Shows the authorization URL in a new tab, waits for it to send a message. # # @see Dropbox.AuthDriver#doAuthorize doAuthorize: (authUrl, stateParam, client, callback) -> oauthTab = null listener = (message, sender) => # Reject messages not coming from the OAuth receiver window. if sender and sender.tab unless sender.tab.url.substring(0, @receiverUrl.length) is @receiverUrl return # Reject improperly formatted messages. return unless message.dropbox_oauth_receiver_href receiverHref = message.dropbox_oauth_receiver_href if @locationStateParam(receiverHref) is stateParam stateParam = false # Avoid having this matched in the future. chrome.tabs.remove oauthTab.id if oauthTab chrome.runtime.onMessage.removeListener listener callback Dropbox.Util.Oauth.queryParamsFromUrl(receiverHref) chrome.runtime.onMessage.addListener listener chrome.tabs.create url: authUrl, active: true, pinned: false, (tab) -> oauthTab = tab # Communicates with the driver from the OAuth receiver page. # # The easiest way for a Chrome extension to keep up to date with dropbox.js # is to set up a popup receiver page that loads dropbox.js and calls this # method. This guarantees that the code used to communicate between the popup # receiver page and {Dropbox.AuthDriver.ChromeExtension#doAuthorize} stays up # to date as dropbox.js is updated. @oauthReceiver: -> window.addEventListener 'load', -> pageUrl = window.location.href window.location.hash = '' # Remove the token from the browser history. chrome.runtime.sendMessage dropbox_oauth_receiver_href: pageUrl window.close() if window.close