Skip to content

Commit 0f48eb8

Browse files
committed
Make the fetch wrapper more compatible with fetch
(closes #117) This makes `oauth.fetch` work exactly like regular `fetch`. Also adds an `authenticateAsync` function that works just like `authenticate`, but wraps in a Promise for chaining.
1 parent 792c6f5 commit 0f48eb8

File tree

6 files changed

+175
-139
lines changed

6 files changed

+175
-139
lines changed

README.md

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,15 @@ Param: `callback` An "errback"-style callback (`err`, `result`), called when
189189
Returns: none<br/>
190190

191191

192+
## `.authenticateAsync()`
193+
194+
Promisified version of `.authenticate()`<br/>
195+
First logs out, then runs the authentication flow and resolves if successful, or rejects if not.<br/>
196+
<br/>
197+
Param: `callback` An "errback"-style callback (`err`, `result`), called when complete<br/>
198+
Returns: `Promise` settled with whatever authenticate did.<br/>
199+
200+
192201
## `.bringPopupWindowToFront()`
193202

194203
Tries to bring an existing authentication popup to the front.<br/>
@@ -205,18 +214,14 @@ Param: `callback` An "errback"-style callback (`err`, `result`), called when
205214
Returns: none<br/>
206215

207216

208-
## `.fetch(path, options)`
217+
## `.fetch(resource, options)`
209218

210-
A `fetch` wrapper that does authenticated calls if the user has logged in.<br/>
219+
A `fetch` wrapper that includes the Authorization header if the user is authenticated.<br/>
211220
See: https://developer.mozilla.org/en-US/docs/Web/API/fetch<br/>
212221
<br/>
213-
Param: `path` The URL path (e.g. "/api/0.6/user/details") (or full url, if `options.prefix`=`false`)<br/>
214-
Param: `options`:<br/>
215-
`options.method` Passed to `fetch` (e.g. 'GET', 'POST')<br/>
216-
`options.prefix` If `true` path contains a path, if `false` path contains the full url<br/>
217-
`options.body` Passed to `fetch`<br/>
218-
`options.headers` optional `Object` containing request headers<br/>
219-
Return: `Promise` that resolves to a `Response` if authenticated, otherwise `null`<br/>
222+
Param: `resource` Resource passed to `fetch`<br/>
223+
Param: `options` Options passed to `fetch`<br/>
224+
Return: `Promise` that wraps `authenticateAsync` then `fetch`<br/>
220225

221226

222227
## `.xhr(options, callback)`

dist/osm-auth.cjs

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,26 @@ function osmAuth(o) {
4949
return;
5050
}
5151
oauth.logout();
52-
generatePkceChallenge(function(pkce) {
52+
_generatePkceChallenge(function(pkce) {
5353
_authenticate(pkce, callback);
5454
});
5555
};
56+
oauth.authenticateAsync = function() {
57+
if (oauth.authenticated()) {
58+
return Promise.resolve(oauth);
59+
}
60+
oauth.logout();
61+
return new Promise((resolve, reject) => {
62+
var errback = (err, result) => {
63+
if (err) {
64+
reject(new Error(err));
65+
} else {
66+
resolve(result);
67+
}
68+
};
69+
_generatePkceChallenge((pkce) => _authenticate(pkce, errback));
70+
});
71+
};
5672
function _authenticate(pkce, callback) {
5773
var state = generateState();
5874
var url = o.url + "/oauth2/authorize?" + utilQsString({
@@ -107,7 +123,7 @@ function osmAuth(o) {
107123
callback(error);
108124
return;
109125
}
110-
getAccessToken(params2.code, pkce.code_verifier, accessTokenDone);
126+
_getAccessToken(params2.code, pkce.code_verifier, accessTokenDone);
111127
delete window.authComplete;
112128
};
113129
function accessTokenDone(err, xhr) {
@@ -121,7 +137,7 @@ function osmAuth(o) {
121137
callback(null, oauth);
122138
}
123139
}
124-
function getAccessToken(auth_code, code_verifier, accessTokenDone) {
140+
function _getAccessToken(auth_code, code_verifier, accessTokenDone) {
125141
var url = o.url + "/oauth2/token?" + utilQsString({
126142
client_id: o.client_id,
127143
redirect_uri: o.redirect_uri,
@@ -155,7 +171,7 @@ function osmAuth(o) {
155171
}
156172
var code_verifier = token("oauth2_pkce_code_verifier");
157173
token("oauth2_pkce_code_verifier", "");
158-
getAccessToken(auth_code, code_verifier, accessTokenDone);
174+
_getAccessToken(auth_code, code_verifier, accessTokenDone);
159175
function accessTokenDone(err, xhr) {
160176
o.done();
161177
if (err) {
@@ -167,55 +183,38 @@ function osmAuth(o) {
167183
callback(null, oauth);
168184
}
169185
};
170-
oauth.fetch = function(path, options, callback) {
186+
oauth.fetch = function(resource, options) {
171187
if (oauth.authenticated()) {
172-
return run();
188+
return _doFetch();
173189
} else {
174190
if (o.auto) {
175-
oauth.authenticate(run);
176-
return;
191+
return oauth.authenticateAsync().then(_doFetch);
177192
} else {
178-
callback("not authenticated", null);
179-
return;
193+
return Promise.reject(new Error("not authenticated"));
180194
}
181195
}
182-
function run() {
183-
var url = options.prefix !== false ? o.url + path : path;
184-
var headers = options.headers || { "Content-Type": "application/x-www-form-urlencoded" };
185-
headers.Authorization = "Bearer " + token("oauth2_access_token");
186-
return fetch(url, {
187-
method: options.method,
188-
body: options.body,
189-
headers
190-
}).then((resp) => {
191-
var contentType = resp.headers.get("content-type").split(";")[0];
192-
switch (contentType) {
193-
case "text/html":
194-
case "text/xml":
195-
return resp.text().then(
196-
(txt) => new window.DOMParser().parseFromString(txt, contentType)
197-
);
198-
case "application/html":
199-
return resp.json();
200-
default:
201-
return resp.text();
202-
}
203-
});
196+
function _doFetch() {
197+
options = options || {};
198+
if (!options.headers) {
199+
options.headers = { "Content-Type": "application/x-www-form-urlencoded" };
200+
}
201+
options.headers.Authorization = "Bearer " + token("oauth2_access_token");
202+
return fetch(resource, options);
204203
}
205204
};
206205
oauth.xhr = function(options, callback) {
207206
if (oauth.authenticated()) {
208-
return run();
207+
return _doXHR();
209208
} else {
210209
if (o.auto) {
211-
oauth.authenticate(run);
210+
oauth.authenticate(_doXHR);
212211
return;
213212
} else {
214213
callback("not authenticated", null);
215214
return;
216215
}
217216
}
218-
function run() {
217+
function _doXHR() {
219218
var url = options.prefix !== false ? o.url + options.path : options.path;
220219
return oauth.rawxhr(
221220
options.method,
@@ -322,7 +321,7 @@ function utilStringQs(str) {
322321
function supportsWebCryptoAPI() {
323322
return window && window.crypto && window.crypto.getRandomValues && window.crypto.subtle && window.crypto.subtle.digest;
324323
}
325-
function generatePkceChallenge(callback) {
324+
function _generatePkceChallenge(callback) {
326325
var code_verifier;
327326
if (supportsWebCryptoAPI()) {
328327
var random = window.crypto.getRandomValues(new Uint8Array(32));

0 commit comments

Comments
 (0)