UNPKG

nebulab-dropbox

Version:
93 lines (82 loc) 3.31 kB
# OAuth driver that redirects the browser to a node app to complete the flow. # # This is useful for testing node.js libraries and applications. class Dropbox.AuthDriver.NodeServer # Starts up the node app that intercepts the browser redirect. # # @param {Object} options (optional) one or more of the options below # @option options {Number} port the number of the TCP port that will receive # HTTPS requests; defaults to 8912 # @option options {Object} tls one or more of the options accepted by # tls.createServer in the node.js standard library; at a minimum, the key # option should be provided constructor: (options) -> @_port = options?.port or 8912 if options?.tls @_tlsOptions = options.tls if typeof @_tlsOptions is 'string' or @_tlsOptions instanceof Buffer @_tlsOptions = key: @_tlsOptions, cert: @_tlsOptions else @_tlsOptions = null # Calling require in the constructor because this doesn't work in browsers. @_fs = Dropbox.Env.require 'fs' @_http = Dropbox.Env.require 'http' @_https = Dropbox.Env.require 'https' @_open = Dropbox.Env.require 'open' @_callbacks = {} @_nodeUrl = Dropbox.Env.require 'url' @createApp() # The /authorize response type. authType: -> "code" # URL to the node.js OAuth callback handler. url: -> protocol = if @_tlsOptions is null then 'http' else 'https' "#{protocol}://localhost:#{@_port}/oauth_callback" # Opens the token doAuthorize: (authUrl, stateParam, client, callback) -> @_callbacks[stateParam] = callback @openBrowser authUrl # Opens the given URL in a browser. openBrowser: (url) -> unless url.match /^https?:\/\// throw new Error("Not a http/https URL: #{url}") if 'BROWSER' of process.env @_open url, process.env['BROWSER'] else @_open url # Creates and starts up an HTTP server that will intercept the redirect. createApp: -> if @_tlsOptions @_app = @_https.createServer @_tlsOptions, (request, response) => @doRequest request, response else @_app = @_http.createServer (request, response) => @doRequest request, response @_app.listen @_port # Shuts down the HTTP server. # # The driver will become unusable after this call. closeServer: -> @_app.close() # Reads out an /authorize callback. doRequest: (request, response) -> url = @_nodeUrl.parse request.url, true if url.pathname is '/oauth_callback' stateParam = url.query.state if @_callbacks[stateParam] @_callbacks[stateParam](url.query) delete @_callbacks[stateParam] data = '' request.on 'data', (dataFragment) -> data += dataFragment request.on 'end', => @closeBrowser response # Renders a response that will close the browser window used for OAuth. closeBrowser: (response) -> closeHtml = """ <!doctype html> <script type="text/javascript">window.close();</script> <p>Please close this window.</p> """ response.writeHead(200, 'Content-Length': closeHtml.length, 'Content-Type': 'text/html') response.write closeHtml response.end()