Browse Source

Merge pull request #144 from transloadit/smooth-auth

feature: smoother auth process
Ifedapo .A. Olarewaju 8 years ago
parent
commit
7e4904c9d4

+ 2 - 2
src/generic-provider-views/AuthView.js

@@ -1,13 +1,13 @@
 const html = require('yo-yo')
 
 module.exports = (props) => {
-  const demoLink = props.demo ? html`<a class="UppyProvider-authBtnDemo" onclick=${props.handleDemoAuth}>Proceed with Demo Account</a>` : null
+  const demoLink = props.demo ? html`<button class="UppyProvider-authBtnDemo" onclick=${props.handleDemoAuth}>Proceed with Demo Account</button>` : null
   return html`
     <div class="UppyProvider-auth">
       <h1 class="UppyProvider-authTitle">
         Please authenticate with <span class="UppyProvider-authTitleName">${props.pluginName}</span><br> to select files
       </h1>
-      <a class="UppyProvider-authBtn" href=${props.link} target="_blank">Authenticate</a>
+      <button class="UppyProvider-authBtn" onclick=${props.handleAuth}>Authenticate</button>
       ${demoLink}
     </div>
   `

+ 33 - 7
src/generic-provider-views/index.js

@@ -49,6 +49,7 @@ module.exports = class View {
     this.getNextFolder = this.getNextFolder.bind(this)
     this.handleRowClick = this.handleRowClick.bind(this)
     this.logout = this.logout.bind(this)
+    this.handleAuth = this.handleAuth.bind(this)
     this.handleDemoAuth = this.handleDemoAuth.bind(this)
     this.sortByTitle = this.sortByTitle.bind(this)
     this.sortByDate = this.sortByDate.bind(this)
@@ -253,6 +254,37 @@ module.exports = class View {
     })
   }
 
+  handleAuth () {
+    const urlId = Math.floor(Math.random() * 999999) + 1
+    const redirect = `${location.href}${location.search ? '&' : '?'}id=${urlId}`
+
+    const authState = btoa(JSON.stringify({ redirect }))
+    const link = `${this.plugin.opts.host}/connect/${this.Provider.authProvider}?state=${authState}`
+
+    const authWindow = window.open(link, '_blank')
+    const checkAuth = () => {
+      let authWindowUrl
+
+      try {
+        authWindowUrl = authWindow.location.href
+      } catch (e) {
+        if (e instanceof DOMException || e instanceof TypeError) {
+          return setTimeout(checkAuth, 100)
+        } else throw e
+      }
+
+      // split url because chrome adds '#' to redirects
+      if (authWindowUrl.split('#')[0] === redirect) {
+        authWindow.close()
+        this.Provider.auth().then(this.plugin.onAuth)
+      } else {
+        setTimeout(checkAuth, 100)
+      }
+    }
+
+    checkAuth()
+  }
+
   render (state) {
     const { authenticated, error } = state[this.plugin.stateId]
 
@@ -261,16 +293,10 @@ module.exports = class View {
     }
 
     if (!authenticated) {
-      const authState = btoa(JSON.stringify({
-        redirect: location.href.split('#')[0]
-      }))
-
-      const link = `${this.plugin.opts.host}/connect/${this.Provider.authProvider}?state=${authState}`
-
       return AuthView({
         pluginName: this.plugin.title,
-        link: link,
         demo: this.plugin.opts.demo,
+        handleAuth: this.handleAuth,
         handleDemoAuth: this.handleDemoAuth
       })
     }

+ 9 - 7
src/plugins/Dropbox/index.js

@@ -30,6 +30,7 @@ module.exports = class Dropbox extends Plugin {
 
     this.files = []
 
+    this.onAuth = this.onAuth.bind(this)
     // Visual
     this.render = this.render.bind(this)
 
@@ -60,17 +61,18 @@ module.exports = class Dropbox extends Plugin {
     const plugin = this
     this.target = this.mount(target, plugin)
 
-    this[this.id].auth()
-      .then((authenticated) => {
-        this.view.updateState({authenticated})
-        if (authenticated) {
-          this.view.getFolder()
-        }
-      })
+    this[this.id].auth().then(this.onAuth)
 
     return
   }
 
+  onAuth (authenticated) {
+    this.view.updateState({authenticated})
+    if (authenticated) {
+      this.view.getFolder()
+    }
+  }
+
   isFolder (item) {
     return item.is_dir
   }

+ 9 - 8
src/plugins/GoogleDrive/index.js

@@ -28,6 +28,7 @@ module.exports = class Google extends Plugin {
 
     this.files = []
 
+    this.onAuth = this.onAuth.bind(this)
     // Visual
     this.render = this.render.bind(this)
 
@@ -58,17 +59,17 @@ module.exports = class Google extends Plugin {
     const plugin = this
     this.target = this.mount(target, plugin)
 
-    this[this.id].auth()
-      .then((authenticated) => {
-        this.view.updateState({authenticated})
-        if (authenticated) {
-          this.view.getFolder('root')
-        }
-      })
-
+    this[this.id].auth().then(this.onAuth)
     return
   }
 
+  onAuth (authenticated) {
+    this.view.updateState({authenticated})
+    if (authenticated) {
+      this.view.getFolder('root')
+    }
+  }
+
   isFolder (item) {
     return item.mimeType === 'application/vnd.google-apps.folder'
   }

+ 2 - 0
src/scss/_provider.scss

@@ -27,6 +27,7 @@
 }
 
 .UppyProvider-authBtn {
+  @include reset-button;
   // background-color: transparent;
   // border: 1px solid $color-cornflower-blue;
   border-radius: 6px;
@@ -38,6 +39,7 @@
   transition: background-color 0.3s;
   text-decoration: none;
   margin-bottom: 20px;
+  cursor: pointer;
 
   &:hover {
     background-color: darken($color-cornflower-blue, 10%);