@jbrowse/plugin-authentication 2.5.0 → 2.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/DropboxOAuthModel/configSchema.d.ts +3 -14
- package/dist/DropboxOAuthModel/configSchema.js +0 -8
- package/dist/DropboxOAuthModel/configSchema.js.map +1 -1
- package/dist/DropboxOAuthModel/model.d.ts +35 -33
- package/dist/DropboxOAuthModel/model.js +26 -35
- package/dist/DropboxOAuthModel/model.js.map +1 -1
- package/dist/DropboxOAuthModel/util.d.ts +1 -0
- package/dist/DropboxOAuthModel/util.js +28 -0
- package/dist/DropboxOAuthModel/util.js.map +1 -0
- package/dist/ExternalTokenModel/ExternalTokenEntryForm.d.ts +2 -1
- package/dist/ExternalTokenModel/ExternalTokenEntryForm.js +10 -11
- package/dist/ExternalTokenModel/ExternalTokenEntryForm.js.map +1 -1
- package/dist/GoogleDriveOAuthModel/GoogleDriveFilehandle.d.ts +15 -0
- package/dist/GoogleDriveOAuthModel/GoogleDriveFilehandle.js +20 -0
- package/dist/GoogleDriveOAuthModel/GoogleDriveFilehandle.js.map +1 -0
- package/dist/GoogleDriveOAuthModel/configSchema.d.ts +0 -5
- package/dist/GoogleDriveOAuthModel/model.d.ts +36 -121
- package/dist/GoogleDriveOAuthModel/model.js +38 -51
- package/dist/GoogleDriveOAuthModel/model.js.map +1 -1
- package/dist/GoogleDriveOAuthModel/util.d.ts +1 -0
- package/dist/GoogleDriveOAuthModel/util.js +17 -0
- package/dist/GoogleDriveOAuthModel/util.js.map +1 -0
- package/dist/HTTPBasicModel/HTTPBasicLoginForm.d.ts +2 -1
- package/dist/HTTPBasicModel/HTTPBasicLoginForm.js +17 -21
- package/dist/HTTPBasicModel/HTTPBasicLoginForm.js.map +1 -1
- package/dist/HTTPBasicModel/model.d.ts +36 -4
- package/dist/HTTPBasicModel/model.js +24 -9
- package/dist/HTTPBasicModel/model.js.map +1 -1
- package/dist/OAuthModel/configSchema.d.ts +0 -8
- package/dist/OAuthModel/configSchema.js +1 -9
- package/dist/OAuthModel/configSchema.js.map +1 -1
- package/dist/OAuthModel/model.d.ts +103 -18
- package/dist/OAuthModel/model.js +165 -113
- package/dist/OAuthModel/model.js.map +1 -1
- package/dist/OAuthModel/util.d.ts +7 -0
- package/dist/OAuthModel/util.js +60 -0
- package/dist/OAuthModel/util.js.map +1 -0
- package/dist/index.d.ts +7 -433
- package/dist/util.d.ts +6 -0
- package/dist/util.js +23 -0
- package/dist/util.js.map +1 -0
- package/esm/DropboxOAuthModel/configSchema.d.ts +3 -14
- package/esm/DropboxOAuthModel/configSchema.js +0 -8
- package/esm/DropboxOAuthModel/configSchema.js.map +1 -1
- package/esm/DropboxOAuthModel/model.d.ts +35 -33
- package/esm/DropboxOAuthModel/model.js +26 -35
- package/esm/DropboxOAuthModel/model.js.map +1 -1
- package/esm/DropboxOAuthModel/util.d.ts +1 -0
- package/esm/DropboxOAuthModel/util.js +24 -0
- package/esm/DropboxOAuthModel/util.js.map +1 -0
- package/esm/ExternalTokenModel/ExternalTokenEntryForm.d.ts +2 -1
- package/esm/ExternalTokenModel/ExternalTokenEntryForm.js +10 -11
- package/esm/ExternalTokenModel/ExternalTokenEntryForm.js.map +1 -1
- package/esm/GoogleDriveOAuthModel/GoogleDriveFilehandle.d.ts +15 -0
- package/esm/GoogleDriveOAuthModel/GoogleDriveFilehandle.js +16 -0
- package/esm/GoogleDriveOAuthModel/GoogleDriveFilehandle.js.map +1 -0
- package/esm/GoogleDriveOAuthModel/configSchema.d.ts +0 -5
- package/esm/GoogleDriveOAuthModel/model.d.ts +36 -121
- package/esm/GoogleDriveOAuthModel/model.js +37 -49
- package/esm/GoogleDriveOAuthModel/model.js.map +1 -1
- package/esm/GoogleDriveOAuthModel/util.d.ts +1 -0
- package/esm/GoogleDriveOAuthModel/util.js +13 -0
- package/esm/GoogleDriveOAuthModel/util.js.map +1 -0
- package/esm/HTTPBasicModel/HTTPBasicLoginForm.d.ts +2 -1
- package/esm/HTTPBasicModel/HTTPBasicLoginForm.js +18 -22
- package/esm/HTTPBasicModel/HTTPBasicLoginForm.js.map +1 -1
- package/esm/HTTPBasicModel/model.d.ts +36 -4
- package/esm/HTTPBasicModel/model.js +24 -9
- package/esm/HTTPBasicModel/model.js.map +1 -1
- package/esm/OAuthModel/configSchema.d.ts +0 -8
- package/esm/OAuthModel/configSchema.js +1 -9
- package/esm/OAuthModel/configSchema.js.map +1 -1
- package/esm/OAuthModel/model.d.ts +103 -18
- package/esm/OAuthModel/model.js +164 -86
- package/esm/OAuthModel/model.js.map +1 -1
- package/esm/OAuthModel/util.d.ts +7 -0
- package/esm/OAuthModel/util.js +30 -0
- package/esm/OAuthModel/util.js.map +1 -0
- package/esm/index.d.ts +7 -433
- package/esm/util.d.ts +6 -0
- package/esm/util.js +18 -0
- package/esm/util.js.map +1 -0
- package/package.json +3 -4
- package/src/DropboxOAuthModel/configSchema.ts +0 -8
- package/src/DropboxOAuthModel/model.tsx +35 -54
- package/src/DropboxOAuthModel/util.ts +36 -0
- package/src/ExternalTokenModel/ExternalTokenEntryForm.tsx +39 -41
- package/src/GoogleDriveOAuthModel/GoogleDriveFilehandle.ts +38 -0
- package/src/GoogleDriveOAuthModel/model.tsx +54 -104
- package/src/GoogleDriveOAuthModel/util.ts +29 -0
- package/src/HTTPBasicModel/HTTPBasicLoginForm.tsx +53 -56
- package/src/HTTPBasicModel/model.tsx +26 -11
- package/src/OAuthModel/configSchema.ts +2 -9
- package/src/OAuthModel/model.tsx +190 -108
- package/src/OAuthModel/util.ts +33 -0
- package/src/util.ts +25 -0
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import { UriLocation } from '@jbrowse/core/util';
|
|
3
3
|
import { Instance } from 'mobx-state-tree';
|
|
4
|
+
/**
|
|
5
|
+
* #stateModel OAuthInternetAccount
|
|
6
|
+
*/
|
|
4
7
|
declare const stateModelFactory: (configSchema: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
5
8
|
tokenType: {
|
|
6
9
|
description: string;
|
|
@@ -23,7 +26,9 @@ declare const stateModelFactory: (configSchema: import("@jbrowse/core/configurat
|
|
|
23
26
|
defaultValue: boolean;
|
|
24
27
|
};
|
|
25
28
|
clientId: {
|
|
26
|
-
description: string;
|
|
29
|
+
description: string; /**
|
|
30
|
+
* #getter
|
|
31
|
+
*/
|
|
27
32
|
type: string;
|
|
28
33
|
defaultValue: string;
|
|
29
34
|
};
|
|
@@ -42,11 +47,6 @@ declare const stateModelFactory: (configSchema: import("@jbrowse/core/configurat
|
|
|
42
47
|
type: string;
|
|
43
48
|
defaultValue: string;
|
|
44
49
|
};
|
|
45
|
-
hasRefreshToken: {
|
|
46
|
-
description: string;
|
|
47
|
-
type: string;
|
|
48
|
-
defaultValue: boolean;
|
|
49
|
-
};
|
|
50
50
|
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
51
51
|
name: {
|
|
52
52
|
description: string;
|
|
@@ -98,13 +98,21 @@ declare const stateModelFactory: (configSchema: import("@jbrowse/core/configurat
|
|
|
98
98
|
defaultValue: string;
|
|
99
99
|
};
|
|
100
100
|
domains: {
|
|
101
|
-
description: string;
|
|
101
|
+
description: string; /**
|
|
102
|
+
* #getter
|
|
103
|
+
*/
|
|
102
104
|
type: string;
|
|
103
105
|
defaultValue: never[];
|
|
104
106
|
};
|
|
105
107
|
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "internetAccountId">>;
|
|
106
108
|
} & {
|
|
109
|
+
/**
|
|
110
|
+
* #property
|
|
111
|
+
*/
|
|
107
112
|
type: import("mobx-state-tree").ISimpleType<"OAuthInternetAccount">;
|
|
113
|
+
/**
|
|
114
|
+
* #property
|
|
115
|
+
*/
|
|
108
116
|
configuration: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
109
117
|
tokenType: {
|
|
110
118
|
description: string;
|
|
@@ -127,7 +135,9 @@ declare const stateModelFactory: (configSchema: import("@jbrowse/core/configurat
|
|
|
127
135
|
defaultValue: boolean;
|
|
128
136
|
};
|
|
129
137
|
clientId: {
|
|
130
|
-
description: string;
|
|
138
|
+
description: string; /**
|
|
139
|
+
* #getter
|
|
140
|
+
*/
|
|
131
141
|
type: string;
|
|
132
142
|
defaultValue: string;
|
|
133
143
|
};
|
|
@@ -146,11 +156,6 @@ declare const stateModelFactory: (configSchema: import("@jbrowse/core/configurat
|
|
|
146
156
|
type: string;
|
|
147
157
|
defaultValue: string;
|
|
148
158
|
};
|
|
149
|
-
hasRefreshToken: {
|
|
150
|
-
description: string;
|
|
151
|
-
type: string;
|
|
152
|
-
defaultValue: boolean;
|
|
153
|
-
};
|
|
154
159
|
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
155
160
|
name: {
|
|
156
161
|
description: string;
|
|
@@ -181,9 +186,13 @@ declare const stateModelFactory: (configSchema: import("@jbrowse/core/configurat
|
|
|
181
186
|
}, {
|
|
182
187
|
readonly name: string;
|
|
183
188
|
readonly description: string;
|
|
184
|
-
readonly internetAccountId: string;
|
|
189
|
+
readonly internetAccountId: string; /**
|
|
190
|
+
* #getter
|
|
191
|
+
*/
|
|
185
192
|
readonly authHeader: string;
|
|
186
|
-
readonly tokenType: string;
|
|
193
|
+
readonly tokenType: string; /**
|
|
194
|
+
* #getter
|
|
195
|
+
*/
|
|
187
196
|
readonly domains: string[];
|
|
188
197
|
readonly toggleContents: import("react").ReactNode;
|
|
189
198
|
readonly SelectorComponent: import("@jbrowse/core/util").AnyReactComponentType | undefined;
|
|
@@ -218,7 +227,10 @@ declare const stateModelFactory: (configSchema: import("@jbrowse/core/configurat
|
|
|
218
227
|
getPreAuthorizationInformation(location: UriLocation): Promise<{
|
|
219
228
|
internetAccountType: string;
|
|
220
229
|
authInfo: {
|
|
221
|
-
token: string;
|
|
230
|
+
token: string; /**
|
|
231
|
+
* #action
|
|
232
|
+
* used to listen to child window for auth code/token
|
|
233
|
+
*/
|
|
222
234
|
configuration: any;
|
|
223
235
|
};
|
|
224
236
|
}>;
|
|
@@ -227,34 +239,107 @@ declare const stateModelFactory: (configSchema: import("@jbrowse/core/configurat
|
|
|
227
239
|
} & {
|
|
228
240
|
openLocation(location: UriLocation): import("@jbrowse/core/util/io").RemoteFileWithRangeCache;
|
|
229
241
|
} & {
|
|
242
|
+
/**
|
|
243
|
+
* #getter
|
|
244
|
+
*/
|
|
230
245
|
readonly codeVerifierPKCE: string;
|
|
231
246
|
} & {
|
|
247
|
+
/**
|
|
248
|
+
* #getter
|
|
249
|
+
*/
|
|
232
250
|
readonly authEndpoint: string;
|
|
251
|
+
/**
|
|
252
|
+
* #getter
|
|
253
|
+
*/
|
|
233
254
|
readonly tokenEndpoint: string;
|
|
255
|
+
/**
|
|
256
|
+
* #getter
|
|
257
|
+
*/
|
|
234
258
|
readonly needsPKCE: boolean;
|
|
259
|
+
/**
|
|
260
|
+
* #getter
|
|
261
|
+
*/
|
|
235
262
|
readonly clientId: string;
|
|
263
|
+
/**
|
|
264
|
+
* #getter
|
|
265
|
+
*/
|
|
236
266
|
readonly scopes: string;
|
|
237
267
|
/**
|
|
238
|
-
*
|
|
268
|
+
* #method
|
|
269
|
+
* OAuth state parameter:
|
|
270
|
+
* https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1
|
|
271
|
+
*
|
|
239
272
|
* Can override or extend if dynamic state is needed.
|
|
240
273
|
*/
|
|
241
274
|
state(): string | undefined;
|
|
275
|
+
/**
|
|
276
|
+
* #getter
|
|
277
|
+
*/
|
|
242
278
|
readonly responseType: "code" | "token";
|
|
243
|
-
|
|
279
|
+
/**
|
|
280
|
+
* #getter
|
|
281
|
+
*/
|
|
244
282
|
readonly refreshTokenKey: string;
|
|
245
283
|
} & {
|
|
284
|
+
/**
|
|
285
|
+
* #action
|
|
286
|
+
*/
|
|
246
287
|
storeRefreshToken(refreshToken: string): void;
|
|
288
|
+
/**
|
|
289
|
+
* #action
|
|
290
|
+
*/
|
|
247
291
|
removeRefreshToken(): void;
|
|
292
|
+
/**
|
|
293
|
+
* #method
|
|
294
|
+
*/
|
|
248
295
|
retrieveRefreshToken(): string | null;
|
|
296
|
+
/**
|
|
297
|
+
* #action
|
|
298
|
+
*/
|
|
249
299
|
exchangeAuthorizationForAccessToken(token: string, redirectUri: string): Promise<string>;
|
|
300
|
+
/**
|
|
301
|
+
* #action
|
|
302
|
+
*/
|
|
250
303
|
exchangeRefreshForAccessToken(refreshToken: string): Promise<string>;
|
|
251
304
|
} & {
|
|
305
|
+
/**
|
|
306
|
+
* #action
|
|
307
|
+
* used to listen to child window for auth code/token
|
|
308
|
+
*/
|
|
252
309
|
addMessageChannel(resolve: (token: string) => void, reject: (error: Error) => void): void;
|
|
310
|
+
/**
|
|
311
|
+
* #action
|
|
312
|
+
*/
|
|
253
313
|
deleteMessageChannel(): void;
|
|
314
|
+
/**
|
|
315
|
+
* #action
|
|
316
|
+
*/
|
|
254
317
|
finishOAuthWindow(event: MessageEvent, resolve: (token: string) => void, reject: (error: Error) => void): Promise<void>;
|
|
318
|
+
/**
|
|
319
|
+
* #action
|
|
320
|
+
* opens external OAuth flow, popup for web and new browser window for
|
|
321
|
+
* desktop
|
|
322
|
+
*/
|
|
255
323
|
useEndpointForAuthorization(resolve: (token: string) => void, reject: (error: Error) => void): Promise<void>;
|
|
324
|
+
/**
|
|
325
|
+
* #action
|
|
326
|
+
*/
|
|
256
327
|
getTokenFromUser(resolve: (token: string) => void, reject: (error: Error) => void): Promise<void>;
|
|
328
|
+
/**
|
|
329
|
+
* #action
|
|
330
|
+
*/
|
|
257
331
|
validateToken(token: string, location: UriLocation): Promise<string>;
|
|
332
|
+
} & {
|
|
333
|
+
/**
|
|
334
|
+
* #action
|
|
335
|
+
* Get a fetch method that will add any needed authentication headers to
|
|
336
|
+
* the request before sending it. If location is provided, it will be
|
|
337
|
+
* checked to see if it includes a token in it's pre-auth information.
|
|
338
|
+
*
|
|
339
|
+
* @param loc - UriLocation of the resource
|
|
340
|
+
* @returns A function that can be used to fetch
|
|
341
|
+
*/
|
|
342
|
+
getFetcher(loc?: UriLocation): (input: RequestInfo, init?: RequestInit) => Promise<Response>;
|
|
258
343
|
}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>;
|
|
259
344
|
export default stateModelFactory;
|
|
260
345
|
export type OAuthStateModel = ReturnType<typeof stateModelFactory>;
|
package/esm/OAuthModel/model.js
CHANGED
|
@@ -2,19 +2,29 @@ import { ConfigurationReference, getConf } from '@jbrowse/core/configuration';
|
|
|
2
2
|
import { InternetAccount } from '@jbrowse/core/pluggableElementTypes/models';
|
|
3
3
|
import { isElectron } from '@jbrowse/core/util';
|
|
4
4
|
import { types } from 'mobx-state-tree';
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
import { fixup, generateChallenge, processError, processTokenResponse, } from './util';
|
|
6
|
+
import { getResponseError } from '../util';
|
|
7
|
+
/**
|
|
8
|
+
* #stateModel OAuthInternetAccount
|
|
9
|
+
*/
|
|
9
10
|
const stateModelFactory = (configSchema) => {
|
|
10
11
|
return InternetAccount.named('OAuthInternetAccount')
|
|
11
12
|
.props({
|
|
13
|
+
/**
|
|
14
|
+
* #property
|
|
15
|
+
*/
|
|
12
16
|
type: types.literal('OAuthInternetAccount'),
|
|
17
|
+
/**
|
|
18
|
+
* #property
|
|
19
|
+
*/
|
|
13
20
|
configuration: ConfigurationReference(configSchema),
|
|
14
21
|
})
|
|
15
22
|
.views(() => {
|
|
16
23
|
let codeVerifier = undefined;
|
|
17
24
|
return {
|
|
25
|
+
/**
|
|
26
|
+
* #getter
|
|
27
|
+
*/
|
|
18
28
|
get codeVerifierPKCE() {
|
|
19
29
|
if (codeVerifier) {
|
|
20
30
|
return codeVerifier;
|
|
@@ -27,118 +37,136 @@ const stateModelFactory = (configSchema) => {
|
|
|
27
37
|
};
|
|
28
38
|
})
|
|
29
39
|
.views(self => ({
|
|
40
|
+
/**
|
|
41
|
+
* #getter
|
|
42
|
+
*/
|
|
30
43
|
get authEndpoint() {
|
|
31
44
|
return getConf(self, 'authEndpoint');
|
|
32
45
|
},
|
|
46
|
+
/**
|
|
47
|
+
* #getter
|
|
48
|
+
*/
|
|
33
49
|
get tokenEndpoint() {
|
|
34
50
|
return getConf(self, 'tokenEndpoint');
|
|
35
51
|
},
|
|
52
|
+
/**
|
|
53
|
+
* #getter
|
|
54
|
+
*/
|
|
36
55
|
get needsPKCE() {
|
|
37
56
|
return getConf(self, 'needsPKCE');
|
|
38
57
|
},
|
|
58
|
+
/**
|
|
59
|
+
* #getter
|
|
60
|
+
*/
|
|
39
61
|
get clientId() {
|
|
40
62
|
return getConf(self, 'clientId');
|
|
41
63
|
},
|
|
64
|
+
/**
|
|
65
|
+
* #getter
|
|
66
|
+
*/
|
|
42
67
|
get scopes() {
|
|
43
68
|
return getConf(self, 'scopes');
|
|
44
69
|
},
|
|
45
70
|
/**
|
|
46
|
-
*
|
|
71
|
+
* #method
|
|
72
|
+
* OAuth state parameter:
|
|
73
|
+
* https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1
|
|
74
|
+
*
|
|
47
75
|
* Can override or extend if dynamic state is needed.
|
|
48
76
|
*/
|
|
49
77
|
state() {
|
|
50
|
-
return getConf(self, 'state')
|
|
78
|
+
return getConf(self, 'state');
|
|
51
79
|
},
|
|
80
|
+
/**
|
|
81
|
+
* #getter
|
|
82
|
+
*/
|
|
52
83
|
get responseType() {
|
|
53
84
|
return getConf(self, 'responseType');
|
|
54
85
|
},
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
86
|
+
/**
|
|
87
|
+
* #getter
|
|
88
|
+
*/
|
|
58
89
|
get refreshTokenKey() {
|
|
59
90
|
return `${self.internetAccountId}-refreshToken`;
|
|
60
91
|
},
|
|
61
92
|
}))
|
|
62
93
|
.actions(self => ({
|
|
94
|
+
/**
|
|
95
|
+
* #action
|
|
96
|
+
*/
|
|
63
97
|
storeRefreshToken(refreshToken) {
|
|
64
98
|
localStorage.setItem(self.refreshTokenKey, refreshToken);
|
|
65
99
|
},
|
|
100
|
+
/**
|
|
101
|
+
* #action
|
|
102
|
+
*/
|
|
66
103
|
removeRefreshToken() {
|
|
67
104
|
localStorage.removeItem(self.refreshTokenKey);
|
|
68
105
|
},
|
|
106
|
+
/**
|
|
107
|
+
* #method
|
|
108
|
+
*/
|
|
69
109
|
retrieveRefreshToken() {
|
|
70
110
|
return localStorage.getItem(self.refreshTokenKey);
|
|
71
111
|
},
|
|
112
|
+
/**
|
|
113
|
+
* #action
|
|
114
|
+
*/
|
|
72
115
|
async exchangeAuthorizationForAccessToken(token, redirectUri) {
|
|
73
|
-
const
|
|
116
|
+
const params = new URLSearchParams(Object.entries({
|
|
74
117
|
code: token,
|
|
75
118
|
grant_type: 'authorization_code',
|
|
76
119
|
client_id: self.clientId,
|
|
77
|
-
code_verifier: self.codeVerifierPKCE,
|
|
78
120
|
redirect_uri: redirectUri,
|
|
79
|
-
|
|
80
|
-
|
|
121
|
+
...(self.needsPKCE ? { code_verifier: self.codeVerifierPKCE } : {}),
|
|
122
|
+
}));
|
|
81
123
|
const response = await fetch(self.tokenEndpoint, {
|
|
82
124
|
method: 'POST',
|
|
83
125
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
84
126
|
body: params.toString(),
|
|
85
127
|
});
|
|
86
128
|
if (!response.ok) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
catch (error) {
|
|
92
|
-
errorMessage = '';
|
|
93
|
-
}
|
|
94
|
-
throw new Error(`Failed to obtain token from endpoint: ${response.status} (${response.statusText})${errorMessage ? ` (${errorMessage})` : ''}`);
|
|
95
|
-
}
|
|
96
|
-
const accessToken = await response.json();
|
|
97
|
-
if (accessToken.refresh_token) {
|
|
98
|
-
this.storeRefreshToken(accessToken.refresh_token);
|
|
129
|
+
throw new Error(await getResponseError({
|
|
130
|
+
response,
|
|
131
|
+
reason: 'Failed to obtain token',
|
|
132
|
+
}));
|
|
99
133
|
}
|
|
100
|
-
|
|
134
|
+
const data = await response.json();
|
|
135
|
+
return processTokenResponse(data, token => this.storeRefreshToken(token));
|
|
101
136
|
},
|
|
137
|
+
/**
|
|
138
|
+
* #action
|
|
139
|
+
*/
|
|
102
140
|
async exchangeRefreshForAccessToken(refreshToken) {
|
|
103
|
-
var _a;
|
|
104
|
-
const data = {
|
|
105
|
-
grant_type: 'refresh_token',
|
|
106
|
-
refresh_token: refreshToken,
|
|
107
|
-
client_id: self.clientId,
|
|
108
|
-
};
|
|
109
|
-
const params = new URLSearchParams(Object.entries(data));
|
|
110
141
|
const response = await fetch(self.tokenEndpoint, {
|
|
111
142
|
method: 'POST',
|
|
112
143
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
113
|
-
body:
|
|
144
|
+
body: new URLSearchParams(Object.entries({
|
|
145
|
+
grant_type: 'refresh_token',
|
|
146
|
+
refresh_token: refreshToken,
|
|
147
|
+
client_id: self.clientId,
|
|
148
|
+
})).toString(),
|
|
114
149
|
});
|
|
115
150
|
if (!response.ok) {
|
|
116
151
|
self.removeToken();
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
text = (_a = obj === null || obj === void 0 ? void 0 : obj.error_description) !== null && _a !== void 0 ? _a : text;
|
|
124
|
-
}
|
|
125
|
-
catch (e) {
|
|
126
|
-
/* just use original text as error */
|
|
127
|
-
}
|
|
128
|
-
throw new Error(`Network response failure — ${response.status} (${response.statusText}) ${text ? ` (${text})` : ''}`);
|
|
129
|
-
}
|
|
130
|
-
const accessToken = await response.json();
|
|
131
|
-
if (accessToken.refresh_token) {
|
|
132
|
-
this.storeRefreshToken(accessToken.refresh_token);
|
|
152
|
+
const text = await response.text();
|
|
153
|
+
throw new Error(await getResponseError({
|
|
154
|
+
response,
|
|
155
|
+
statusText: processError(text, () => this.removeRefreshToken()),
|
|
156
|
+
}));
|
|
133
157
|
}
|
|
134
|
-
|
|
158
|
+
const data = await response.json();
|
|
159
|
+
return processTokenResponse(data, token => this.storeRefreshToken(token));
|
|
135
160
|
},
|
|
136
161
|
}))
|
|
137
162
|
.actions(self => {
|
|
138
163
|
let listener;
|
|
139
|
-
let
|
|
164
|
+
let exchangedTokenPromise = undefined;
|
|
140
165
|
return {
|
|
141
|
-
|
|
166
|
+
/**
|
|
167
|
+
* #action
|
|
168
|
+
* used to listen to child window for auth code/token
|
|
169
|
+
*/
|
|
142
170
|
addMessageChannel(resolve, reject) {
|
|
143
171
|
listener = event => {
|
|
144
172
|
// this should probably get better handling, but ignored for now
|
|
@@ -147,9 +175,15 @@ const stateModelFactory = (configSchema) => {
|
|
|
147
175
|
};
|
|
148
176
|
window.addEventListener('message', listener);
|
|
149
177
|
},
|
|
178
|
+
/**
|
|
179
|
+
* #action
|
|
180
|
+
*/
|
|
150
181
|
deleteMessageChannel() {
|
|
151
182
|
window.removeEventListener('message', listener);
|
|
152
183
|
},
|
|
184
|
+
/**
|
|
185
|
+
* #action
|
|
186
|
+
*/
|
|
153
187
|
async finishOAuthWindow(event, resolve, reject) {
|
|
154
188
|
if (event.data.name !== `JBrowseAuthWindow-${self.internetAccountId}`) {
|
|
155
189
|
return this.deleteMessageChannel();
|
|
@@ -177,21 +211,25 @@ const stateModelFactory = (configSchema) => {
|
|
|
177
211
|
self.storeToken(token);
|
|
178
212
|
return resolve(token);
|
|
179
213
|
}
|
|
180
|
-
catch (
|
|
181
|
-
return
|
|
182
|
-
? reject(
|
|
183
|
-
: reject(new Error(String(
|
|
214
|
+
catch (e) {
|
|
215
|
+
return e instanceof Error
|
|
216
|
+
? reject(e)
|
|
217
|
+
: reject(new Error(String(e)));
|
|
184
218
|
}
|
|
185
219
|
}
|
|
186
220
|
if (redirectUriWithInfo.includes('access_denied')) {
|
|
187
221
|
return reject(new Error('OAuth flow was cancelled'));
|
|
188
222
|
}
|
|
189
223
|
if (redirectUriWithInfo.includes('error')) {
|
|
190
|
-
return reject(new Error('
|
|
224
|
+
return reject(new Error('OAuth flow error: ' + queryStringSearch));
|
|
191
225
|
}
|
|
192
226
|
this.deleteMessageChannel();
|
|
193
227
|
},
|
|
194
|
-
|
|
228
|
+
/**
|
|
229
|
+
* #action
|
|
230
|
+
* opens external OAuth flow, popup for web and new browser window for
|
|
231
|
+
* desktop
|
|
232
|
+
*/
|
|
195
233
|
async useEndpointForAuthorization(resolve, reject) {
|
|
196
234
|
const redirectUri = isElectron
|
|
197
235
|
? 'http://localhost/auth'
|
|
@@ -200,6 +238,7 @@ const stateModelFactory = (configSchema) => {
|
|
|
200
238
|
client_id: self.clientId,
|
|
201
239
|
redirect_uri: redirectUri,
|
|
202
240
|
response_type: self.responseType || 'code',
|
|
241
|
+
token_access_type: 'offline',
|
|
203
242
|
};
|
|
204
243
|
if (self.state()) {
|
|
205
244
|
data.state = self.state();
|
|
@@ -208,16 +247,9 @@ const stateModelFactory = (configSchema) => {
|
|
|
208
247
|
data.scope = self.scopes;
|
|
209
248
|
}
|
|
210
249
|
if (self.needsPKCE) {
|
|
211
|
-
|
|
212
|
-
const sha256 = await import('crypto-js/sha256').then(f => f.default);
|
|
213
|
-
const Base64 = await import('crypto-js/enc-base64');
|
|
214
|
-
const codeChallenge = fixup(Base64.stringify(sha256(codeVerifierPKCE)));
|
|
215
|
-
data.code_challenge = codeChallenge;
|
|
250
|
+
data.code_challenge = await generateChallenge(self.codeVerifierPKCE);
|
|
216
251
|
data.code_challenge_method = 'S256';
|
|
217
252
|
}
|
|
218
|
-
if (self.hasRefreshToken) {
|
|
219
|
-
data.token_access_type = 'offline';
|
|
220
|
-
}
|
|
221
253
|
const params = new URLSearchParams(Object.entries(data));
|
|
222
254
|
const url = new URL(self.authEndpoint);
|
|
223
255
|
url.search = params.toString();
|
|
@@ -237,44 +269,90 @@ const stateModelFactory = (configSchema) => {
|
|
|
237
269
|
this.finishOAuthWindow(eventFromDesktop, resolve, reject);
|
|
238
270
|
}
|
|
239
271
|
else {
|
|
240
|
-
|
|
241
|
-
window.open(url, eventName, options);
|
|
272
|
+
window.open(url, eventName, `width=500,height=600,left=0,top=0`);
|
|
242
273
|
}
|
|
243
274
|
},
|
|
275
|
+
/**
|
|
276
|
+
* #action
|
|
277
|
+
*/
|
|
244
278
|
async getTokenFromUser(resolve, reject) {
|
|
245
|
-
const refreshToken = self.
|
|
279
|
+
const refreshToken = self.retrieveRefreshToken();
|
|
280
|
+
let doUserFlow = true;
|
|
281
|
+
// if there is a refresh token, then try it out, and only if that
|
|
282
|
+
// refresh token succeeds, set doUserFlow to false
|
|
246
283
|
if (refreshToken) {
|
|
247
|
-
|
|
284
|
+
try {
|
|
285
|
+
const token = await self.exchangeRefreshForAccessToken(refreshToken);
|
|
286
|
+
resolve(token);
|
|
287
|
+
doUserFlow = false;
|
|
288
|
+
}
|
|
289
|
+
catch (e) {
|
|
290
|
+
console.error(e);
|
|
291
|
+
self.removeRefreshToken();
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (doUserFlow) {
|
|
295
|
+
this.addMessageChannel(resolve, reject);
|
|
296
|
+
// may want to improve handling
|
|
297
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
298
|
+
this.useEndpointForAuthorization(resolve, reject);
|
|
248
299
|
}
|
|
249
|
-
this.addMessageChannel(resolve, reject);
|
|
250
|
-
// may want to improve handling
|
|
251
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
252
|
-
this.useEndpointForAuthorization(resolve, reject);
|
|
253
300
|
},
|
|
301
|
+
/**
|
|
302
|
+
* #action
|
|
303
|
+
*/
|
|
254
304
|
async validateToken(token, location) {
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
-
|
|
305
|
+
const newInit = self.addAuthHeaderToInit({ method: 'HEAD' }, token);
|
|
306
|
+
const response = await fetch(location.uri, newInit);
|
|
307
|
+
if (!response.ok) {
|
|
308
|
+
self.removeToken();
|
|
309
|
+
const refreshToken = self.retrieveRefreshToken();
|
|
258
310
|
if (refreshToken) {
|
|
259
311
|
try {
|
|
260
|
-
if (!
|
|
261
|
-
|
|
312
|
+
if (!exchangedTokenPromise) {
|
|
313
|
+
exchangedTokenPromise =
|
|
262
314
|
self.exchangeRefreshForAccessToken(refreshToken);
|
|
263
315
|
}
|
|
264
|
-
const newToken = await
|
|
265
|
-
|
|
316
|
+
const newToken = await exchangedTokenPromise;
|
|
317
|
+
exchangedTokenPromise = undefined;
|
|
318
|
+
return newToken;
|
|
266
319
|
}
|
|
267
320
|
catch (err) {
|
|
268
|
-
|
|
321
|
+
console.error('Token could not be refreshed', err);
|
|
322
|
+
// let original error be thrown
|
|
269
323
|
}
|
|
270
324
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
325
|
+
throw new Error(await getResponseError({
|
|
326
|
+
response,
|
|
327
|
+
reason: 'Error validating token',
|
|
328
|
+
}));
|
|
274
329
|
}
|
|
275
330
|
return token;
|
|
276
331
|
},
|
|
277
332
|
};
|
|
333
|
+
})
|
|
334
|
+
.actions(self => {
|
|
335
|
+
const superGetFetcher = self.getFetcher;
|
|
336
|
+
return {
|
|
337
|
+
/**
|
|
338
|
+
* #action
|
|
339
|
+
* Get a fetch method that will add any needed authentication headers to
|
|
340
|
+
* the request before sending it. If location is provided, it will be
|
|
341
|
+
* checked to see if it includes a token in it's pre-auth information.
|
|
342
|
+
*
|
|
343
|
+
* @param loc - UriLocation of the resource
|
|
344
|
+
* @returns A function that can be used to fetch
|
|
345
|
+
*/
|
|
346
|
+
getFetcher(loc) {
|
|
347
|
+
const fetcher = superGetFetcher(loc);
|
|
348
|
+
return async (input, init) => {
|
|
349
|
+
if (loc) {
|
|
350
|
+
await self.validateToken(await self.getToken(loc), loc);
|
|
351
|
+
}
|
|
352
|
+
return fetcher(input, init);
|
|
353
|
+
};
|
|
354
|
+
},
|
|
355
|
+
};
|
|
278
356
|
});
|
|
279
357
|
};
|
|
280
358
|
export default stateModelFactory;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/OAuthModel/model.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAA;AAC5E,OAAO,EAAE,UAAU,EAAe,MAAM,oBAAoB,CAAA;AAC5D,OAAO,EAAY,KAAK,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/OAuthModel/model.tsx"],"names":[],"mappings":"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"}
|