Skip to content

Commit 4c96c44

Browse files
authored
Migrate from callbacks to promises (#40)
* Migrate callback logic to promise - Add timeout option to throw an error if no response is returned - Downgrade the Dropbox dependency to 7.0.0 - Add Upgrading.md for v2.0.0 * Add upgrading.md
1 parent dbe35c6 commit 4c96c44

File tree

6 files changed

+81
-40
lines changed

6 files changed

+81
-40
lines changed

UPGRADING.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Upgrading the OAuth Popup
2+
3+
This document shows you how to upgrade to the latest version of the popup, accomodating any breaking changes introduced by major version updates. If you find any issues with either this guide on upgrading or the changes introduced in the new version, please see file an issue.
4+
5+
# Upgrading from v1.X.X to v2.X.X
6+
7+
## Updating from callbacks to promises
8+
9+
We have updated the library to use the newer promises over callbacks. Previously this would have looked like this:
10+
11+
```
12+
var popup = new DropboxPopup();
13+
popup.authUser((auth) => {
14+
// Do logic with auth
15+
});
16+
```
17+
18+
This now becomes:
19+
20+
```
21+
var popup = new DropboxPopup();
22+
popup.authUser().then((auth) => {
23+
// Do logic with auth
24+
}).catch((error) => {
25+
// Handle Error
26+
});
27+
```
28+
29+
## Timeout Functionality
30+
31+
We have also added timeout functionality. When attempting to authenticate, we will timeout and throw an error if the request is not fulfilled in the time specified. The default is 5 minutes but can be configured to any time in milliseconds.
32+

examples/browser.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<script src="https://cdn.jsdelivr.net/npm/promise-polyfill@7/dist/polyfill.min.js"></script>
66
<script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/2.0.3/fetch.js"></script>
77
<script src="https://cdn.jsdelivr.net/npm/dropbox/dist/Dropbox-sdk.js"></script>
8-
<script src="https://cdn.jsdelivr.net/npm/dropbox-oauth-popup@1.4.1/dist/dropboxPopup.js"></script>
8+
<script src="https://cdn.jsdelivr.net/npm/dropbox-oauth-popup@2.0.0/dist/dropboxPopup.js"></script>
99
</head>
1010

1111
<body>

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "dropbox-oauth-popup",
3-
"version": "1.4.1",
3+
"version": "2.0.0",
44
"registry": "npm",
55
"description": "This is a simple addition built onto the Dropbox SDK that allows for OAuth in the browser to be done via a popup window.",
66
"homepage": "https://github.com/rogebrd/dropbox-oauth-popup",
@@ -30,7 +30,7 @@
3030
"rollup-plugin-terser": "^7.0.2"
3131
},
3232
"dependencies": {
33-
"dropbox": "^7.1.0"
33+
"dropbox": "^7.0.0"
3434
},
3535
"browserslist": [
3636
"> 0.25%",
@@ -40,7 +40,6 @@
4040
"*.md",
4141
"LICENSE",
4242
"src",
43-
"test",
4443
"dist"
4544
],
4645
"repository": {

src/dropboxPopup.js

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ const defaultWindowOptions = {
2727
left: 100,
2828
};
2929

30+
const defaultTimeout = 300000; // 5 minutes
31+
3032
/**
3133
* @class DropboxPopup
3234
* @classdesc The DropboxPopup class is to provide a simple popup window to preform OAuth in.
@@ -57,16 +59,18 @@ const defaultWindowOptions = {
5759
* @param {object} [windowOptions.additionalParams] - Any additional parameters desired to be used
5860
* with the window.open() command. Note, by default, we add the parameters toolbar=no and menubar=no
5961
* in order to ensure this opens as a popup.
62+
* @param {number} timeout - The timeout for when to give up on the promise and throw an error
6063
*/
6164
export default class DropboxPopup {
62-
constructor(options, windowOptions) {
65+
constructor(options, windowOptions, timeout) {
6366
this.clientId = options.clientId;
6467
this.redirectUri = options.redirectUri;
6568
this.clientSecret = options.clientSecret || '';
6669
this.tokenAccessType = options.tokenAccessType || 'offline';
6770
this.scope = options.scope || null;
6871
this.includeGrantedScopes = options.includeGrantedScopes || 'none';
6972
this.usePKCE = options.usePKCE || false;
73+
this.timeout = timeout || defaultTimeout;
7074

7175
this.authObject = new DropboxAuth({
7276
clientId: this.clientId,
@@ -90,40 +94,44 @@ export default class DropboxPopup {
9094
/**
9195
* The main function to handle authentication via a popup window.
9296
*
93-
* @param {Function} callback - The callback function which will utilize the DropboxAuth object.
94-
* @returns {void}
97+
* @returns {Promise<DropboxAuth>} The promise which contains the end auth object
9598
*/
96-
authUser(callback) {
97-
window.removeEventListener('message', this.handleRedirect);
98-
this.callback = callback;
99-
this.callback.bind(this);
100-
const authUrl = this.authObject.getAuthenticationUrl(this.redirectUri, this.state, 'code', this.tokenAccessType, this.scope, this.includeGrantedScopes, this.usePKCE);
101-
const popupWindow = window.open(authUrl, windowName, this.windowOptions);
102-
popupWindow.focus();
99+
authUser() {
100+
const popup = this;
101+
return new Promise((resolve, reject) => {
102+
setTimeout(() => {
103+
reject(new Error('Request timed out'));
104+
}, popup.timeout);
103105

104-
window.addEventListener('message', (event) => this.handleRedirect(event), false);
105-
}
106+
/**
107+
* The function in charge of handling the redirect once the popup has completed.
108+
*
109+
* @param {MessageEvent} event - The incoming message from the popup window.
110+
* @returns {void}
111+
*/
112+
function handleRedirect(event) {
113+
window.removeEventListener('message', popup.handleRedirect);
106114

107-
/**
108-
* The function in charge of handling the redirect once the popup has completed.
109-
*
110-
* @param {MessageEvent} event - The incoming message from the popup window.
111-
* @returns {void}
112-
*/
113-
handleRedirect(event) {
114-
const { data } = event;
115-
const urlParams = new URLSearchParams(data);
116-
const code = urlParams.get('code');
117-
this.authObject.getAccessTokenFromCode(this.redirectUri, code)
118-
.then((response) => {
119-
const { result } = response;
120-
this.authObject.setAccessToken(result.access_token);
121-
this.authObject.setRefreshToken(result.refresh_token);
122-
this.authObject.setAccessTokenExpiresAt(new Date(Date.now() + result.expires_in));
123-
this.callback(this.authObject);
124-
})
125-
.catch((error) => {
126-
throw error;
127-
});
115+
const { data } = event;
116+
const urlParams = new URLSearchParams(data);
117+
const code = urlParams.get('code');
118+
119+
popup.authObject.getAccessTokenFromCode(popup.redirectUri, code).then((response) => {
120+
const { result } = response;
121+
popup.authObject.setAccessToken(result.access_token);
122+
popup.authObject.setRefreshToken(result.refresh_token);
123+
popup.authObject.setAccessTokenExpiresAt(new Date(Date.now() + result.expires_in));
124+
resolve(popup.authObject);
125+
})
126+
.catch((error) => {
127+
reject(error);
128+
});
129+
}
130+
131+
const authUrl = popup.authObject.getAuthenticationUrl(popup.redirectUri, popup.state, 'code', popup.tokenAccessType, popup.scope, popup.includeGrantedScopes, popup.usePKCE);
132+
const popupWindow = window.open(authUrl, windowName, popup.windowOptions);
133+
popupWindow.focus();
134+
window.addEventListener('message', handleRedirect, false);
135+
});
128136
}
129137
}

test/static/index.html

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ <h1>Dropbox OAuth Popup Window</h1>
3131
width: 400,
3232
top: 100,
3333
left: 100
34-
});
34+
}, 200000);
3535
function runAuth() {
3636
document.getElementById("result").innerHTML = "Waiting for auth...";
37-
popup.authUser((auth) => {
37+
popup.authUser().then((auth) => {
3838
const dbx = new Dropbox.Dropbox(auth);
3939
dbx.usersGetCurrentAccount()
4040
.then((response) => {
@@ -43,6 +43,8 @@ <h1>Dropbox OAuth Popup Window</h1>
4343
.catch((error) => {
4444
document.getElementById("result").innerHTML = error;
4545
});
46+
}).catch((error) => {
47+
document.getElementById("result").innerHTML = error;
4648
});
4749
}
4850
</script>

0 commit comments

Comments
 (0)