@jbrowse/plugin-authentication 2.17.0 → 3.0.0

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.
Files changed (70) hide show
  1. package/dist/DropboxOAuthModel/DropboxIcon.d.ts +2 -3
  2. package/dist/DropboxOAuthModel/DropboxIcon.js +2 -6
  3. package/dist/DropboxOAuthModel/configSchema.d.ts +1 -13
  4. package/dist/DropboxOAuthModel/configSchema.js +1 -19
  5. package/dist/DropboxOAuthModel/model.d.ts +5 -28
  6. package/dist/DropboxOAuthModel/model.js +4 -26
  7. package/dist/DropboxOAuthModel/util.js +0 -5
  8. package/dist/ExternalTokenModel/ExternalTokenEntryForm.d.ts +1 -2
  9. package/dist/ExternalTokenModel/ExternalTokenEntryForm.js +16 -41
  10. package/dist/ExternalTokenModel/configSchema.d.ts +1 -4
  11. package/dist/ExternalTokenModel/configSchema.js +1 -10
  12. package/dist/ExternalTokenModel/model.d.ts +3 -3
  13. package/dist/GoogleDriveOAuthModel/GoogleDriveFilehandle.d.ts +3 -3
  14. package/dist/GoogleDriveOAuthModel/GoogleDriveFilehandle.js +1 -1
  15. package/dist/GoogleDriveOAuthModel/GoogleDriveIcon.d.ts +2 -3
  16. package/dist/GoogleDriveOAuthModel/GoogleDriveIcon.js +2 -6
  17. package/dist/GoogleDriveOAuthModel/configSchema.d.ts +1 -13
  18. package/dist/GoogleDriveOAuthModel/configSchema.js +1 -19
  19. package/dist/GoogleDriveOAuthModel/model.d.ts +5 -31
  20. package/dist/GoogleDriveOAuthModel/model.js +4 -29
  21. package/dist/GoogleDriveOAuthModel/util.js +0 -1
  22. package/dist/HTTPBasicModel/HTTPBasicLoginForm.d.ts +1 -2
  23. package/dist/HTTPBasicModel/HTTPBasicLoginForm.js +17 -44
  24. package/dist/HTTPBasicModel/configSchema.d.ts +1 -7
  25. package/dist/HTTPBasicModel/configSchema.js +1 -13
  26. package/dist/HTTPBasicModel/model.d.ts +3 -21
  27. package/dist/HTTPBasicModel/model.js +0 -18
  28. package/dist/OAuthModel/configSchema.d.ts +1 -25
  29. package/dist/OAuthModel/configSchema.js +1 -31
  30. package/dist/OAuthModel/model.d.ts +4 -90
  31. package/dist/OAuthModel/model.js +11 -101
  32. package/dist/OAuthModel/util.js +17 -9
  33. package/dist/index.d.ts +4 -4
  34. package/dist/index.js +3 -3
  35. package/esm/DropboxOAuthModel/DropboxIcon.d.ts +2 -3
  36. package/esm/DropboxOAuthModel/DropboxIcon.js +2 -3
  37. package/esm/DropboxOAuthModel/configSchema.d.ts +1 -13
  38. package/esm/DropboxOAuthModel/configSchema.js +1 -19
  39. package/esm/DropboxOAuthModel/model.d.ts +5 -28
  40. package/esm/DropboxOAuthModel/model.js +4 -26
  41. package/esm/DropboxOAuthModel/util.js +0 -5
  42. package/esm/ExternalTokenModel/ExternalTokenEntryForm.d.ts +1 -2
  43. package/esm/ExternalTokenModel/ExternalTokenEntryForm.js +16 -18
  44. package/esm/ExternalTokenModel/configSchema.d.ts +1 -4
  45. package/esm/ExternalTokenModel/configSchema.js +1 -10
  46. package/esm/ExternalTokenModel/model.d.ts +3 -3
  47. package/esm/ExternalTokenModel/model.js +1 -1
  48. package/esm/GoogleDriveOAuthModel/GoogleDriveFilehandle.d.ts +3 -3
  49. package/esm/GoogleDriveOAuthModel/GoogleDriveFilehandle.js +1 -1
  50. package/esm/GoogleDriveOAuthModel/GoogleDriveIcon.d.ts +2 -3
  51. package/esm/GoogleDriveOAuthModel/GoogleDriveIcon.js +2 -3
  52. package/esm/GoogleDriveOAuthModel/configSchema.d.ts +1 -13
  53. package/esm/GoogleDriveOAuthModel/configSchema.js +1 -19
  54. package/esm/GoogleDriveOAuthModel/model.d.ts +5 -31
  55. package/esm/GoogleDriveOAuthModel/model.js +4 -29
  56. package/esm/GoogleDriveOAuthModel/util.js +0 -1
  57. package/esm/HTTPBasicModel/HTTPBasicLoginForm.d.ts +1 -2
  58. package/esm/HTTPBasicModel/HTTPBasicLoginForm.js +17 -21
  59. package/esm/HTTPBasicModel/configSchema.d.ts +1 -7
  60. package/esm/HTTPBasicModel/configSchema.js +1 -13
  61. package/esm/HTTPBasicModel/model.d.ts +3 -21
  62. package/esm/HTTPBasicModel/model.js +1 -19
  63. package/esm/OAuthModel/configSchema.d.ts +1 -25
  64. package/esm/OAuthModel/configSchema.js +1 -31
  65. package/esm/OAuthModel/model.d.ts +4 -90
  66. package/esm/OAuthModel/model.js +11 -101
  67. package/esm/OAuthModel/util.js +0 -2
  68. package/esm/index.d.ts +4 -4
  69. package/esm/index.js +3 -3
  70. package/package.json +3 -3
@@ -1,9 +1,6 @@
1
- import { UriLocation } from '@jbrowse/core/util';
2
- import { Instance } from 'mobx-state-tree';
3
- import { OAuthInternetAccountConfigModel } from './configSchema';
4
- /**
5
- * #stateModel OAuthInternetAccount
6
- */
1
+ import type { OAuthInternetAccountConfigModel } from './configSchema';
2
+ import type { UriLocation } from '@jbrowse/core/util';
3
+ import type { Instance } from 'mobx-state-tree';
7
4
  declare const stateModelFactory: (configSchema: OAuthInternetAccountConfigModel) => import("mobx-state-tree").IModelType<{
8
5
  id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
9
6
  type: import("mobx-state-tree").ISimpleType<string>;
@@ -35,13 +32,7 @@ declare const stateModelFactory: (configSchema: OAuthInternetAccountConfigModel)
35
32
  };
36
33
  }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "internetAccountId">>;
37
34
  } & {
38
- /**
39
- * #property
40
- */
41
35
  type: import("mobx-state-tree").ISimpleType<"OAuthInternetAccount">;
42
- /**
43
- * #property
44
- */
45
36
  configuration: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
46
37
  tokenType: {
47
38
  description: string;
@@ -160,107 +151,30 @@ declare const stateModelFactory: (configSchema: OAuthInternetAccountConfigModel)
160
151
  } & {
161
152
  openLocation(location: UriLocation): import("@jbrowse/core/util/io").RemoteFileWithRangeCache;
162
153
  } & {
163
- /**
164
- * #getter
165
- */
166
154
  readonly codeVerifierPKCE: string;
167
155
  } & {
168
- /**
169
- * #getter
170
- */
171
156
  readonly authEndpoint: string;
172
- /**
173
- * #getter
174
- */
175
157
  readonly tokenEndpoint: string;
176
- /**
177
- * #getter
178
- */
179
158
  readonly needsPKCE: boolean;
180
- /**
181
- * #getter
182
- */
183
159
  readonly clientId: string;
184
- /**
185
- * #getter
186
- */
187
160
  readonly scopes: string;
188
- /**
189
- * #method
190
- * OAuth state parameter:
191
- * https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1
192
- *
193
- * Can override or extend if dynamic state is needed.
194
- */
195
161
  state(): string | undefined;
196
- /**
197
- * #getter
198
- */
199
- readonly responseType: "code" | "token";
200
- /**
201
- * #getter
202
- */
162
+ readonly responseType: "token" | "code";
203
163
  readonly refreshTokenKey: string;
204
164
  } & {
205
- /**
206
- * #action
207
- */
208
165
  storeRefreshToken(refreshToken: string): void;
209
- /**
210
- * #action
211
- */
212
166
  removeRefreshToken(): void;
213
- /**
214
- * #method
215
- */
216
167
  retrieveRefreshToken(): string | null;
217
- /**
218
- * #action
219
- */
220
168
  exchangeAuthorizationForAccessToken(token: string, redirectUri: string): Promise<string>;
221
- /**
222
- * #action
223
- */
224
169
  exchangeRefreshForAccessToken(refreshToken: string): Promise<string>;
225
170
  } & {
226
- /**
227
- * #action
228
- * used to listen to child window for auth code/token
229
- */
230
171
  addMessageChannel(resolve: (token: string) => void, reject: (error: Error) => void): void;
231
- /**
232
- * #action
233
- */
234
172
  deleteMessageChannel(): void;
235
- /**
236
- * #action
237
- */
238
173
  finishOAuthWindow(event: MessageEvent, resolve: (token: string) => void, reject: (error: Error) => void): Promise<void>;
239
- /**
240
- * #action
241
- * opens external OAuth flow, popup for web and new browser window for
242
- * desktop
243
- */
244
174
  useEndpointForAuthorization(resolve: (token: string) => void, reject: (error: Error) => void): Promise<void>;
245
- /**
246
- * #action
247
- */
248
175
  getTokenFromUser(resolve: (token: string) => void, reject: (error: Error) => void): Promise<void>;
249
- /**
250
- * #action
251
- */
252
176
  validateToken(token: string, location: UriLocation): Promise<string>;
253
177
  } & {
254
- /**
255
- * #action
256
- * Get a fetch method that will add any needed authentication headers
257
- * to the request before sending it. If location is provided, it will
258
- * be checked to see if it includes a token in it's pre-auth
259
- * information.
260
- *
261
- * @param loc - UriLocation of the resource
262
- * @returns A function that can be used to fetch
263
- */
264
178
  getFetcher(loc?: UriLocation): (input: RequestInfo, init?: RequestInit) => Promise<Response>;
265
179
  }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>;
266
180
  export default stateModelFactory;
@@ -2,117 +2,70 @@ 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 { Buffer } from 'buffer';
6
5
  import { fixup, generateChallenge, processError, processTokenResponse, } from './util';
7
6
  import { getResponseError } from '../util';
8
- /**
9
- * #stateModel OAuthInternetAccount
10
- */
7
+ function encode(uint8array) {
8
+ const output = [];
9
+ for (let i = 0, length = uint8array.length; i < length; i++) {
10
+ output.push(String.fromCharCode(uint8array[i]));
11
+ }
12
+ return btoa(output.join(''));
13
+ }
11
14
  const stateModelFactory = (configSchema) => {
12
15
  return InternetAccount.named('OAuthInternetAccount')
13
16
  .props({
14
- /**
15
- * #property
16
- */
17
17
  type: types.literal('OAuthInternetAccount'),
18
- /**
19
- * #property
20
- */
21
18
  configuration: ConfigurationReference(configSchema),
22
19
  })
23
20
  .views(() => {
24
21
  let codeVerifier = undefined;
25
22
  return {
26
- /**
27
- * #getter
28
- */
29
23
  get codeVerifierPKCE() {
30
- if (codeVerifier) {
31
- return codeVerifier;
24
+ if (!codeVerifier) {
25
+ const array = new Uint8Array(32);
26
+ globalThis.crypto.getRandomValues(array);
27
+ codeVerifier = fixup(encode(array));
32
28
  }
33
- const array = new Uint8Array(32);
34
- globalThis.crypto.getRandomValues(array);
35
- codeVerifier = fixup(Buffer.from(array).toString('base64'));
36
29
  return codeVerifier;
37
30
  },
38
31
  };
39
32
  })
40
33
  .views(self => ({
41
- /**
42
- * #getter
43
- */
44
34
  get authEndpoint() {
45
35
  return getConf(self, 'authEndpoint');
46
36
  },
47
- /**
48
- * #getter
49
- */
50
37
  get tokenEndpoint() {
51
38
  return getConf(self, 'tokenEndpoint');
52
39
  },
53
- /**
54
- * #getter
55
- */
56
40
  get needsPKCE() {
57
41
  return getConf(self, 'needsPKCE');
58
42
  },
59
- /**
60
- * #getter
61
- */
62
43
  get clientId() {
63
44
  return getConf(self, 'clientId');
64
45
  },
65
- /**
66
- * #getter
67
- */
68
46
  get scopes() {
69
47
  return getConf(self, 'scopes');
70
48
  },
71
- /**
72
- * #method
73
- * OAuth state parameter:
74
- * https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1
75
- *
76
- * Can override or extend if dynamic state is needed.
77
- */
78
49
  state() {
79
50
  return getConf(self, 'state');
80
51
  },
81
- /**
82
- * #getter
83
- */
84
52
  get responseType() {
85
53
  return getConf(self, 'responseType');
86
54
  },
87
- /**
88
- * #getter
89
- */
90
55
  get refreshTokenKey() {
91
56
  return `${self.internetAccountId}-refreshToken`;
92
57
  },
93
58
  }))
94
59
  .actions(self => ({
95
- /**
96
- * #action
97
- */
98
60
  storeRefreshToken(refreshToken) {
99
61
  localStorage.setItem(self.refreshTokenKey, refreshToken);
100
62
  },
101
- /**
102
- * #action
103
- */
104
63
  removeRefreshToken() {
105
64
  localStorage.removeItem(self.refreshTokenKey);
106
65
  },
107
- /**
108
- * #method
109
- */
110
66
  retrieveRefreshToken() {
111
67
  return localStorage.getItem(self.refreshTokenKey);
112
68
  },
113
- /**
114
- * #action
115
- */
116
69
  async exchangeAuthorizationForAccessToken(token, redirectUri) {
117
70
  const params = new URLSearchParams(Object.entries({
118
71
  code: token,
@@ -137,9 +90,6 @@ const stateModelFactory = (configSchema) => {
137
90
  this.storeRefreshToken(token);
138
91
  });
139
92
  },
140
- /**
141
- * #action
142
- */
143
93
  async exchangeRefreshForAccessToken(refreshToken) {
144
94
  const response = await fetch(self.tokenEndpoint, {
145
95
  method: 'POST',
@@ -170,27 +120,15 @@ const stateModelFactory = (configSchema) => {
170
120
  let listener;
171
121
  let exchangedTokenPromise = undefined;
172
122
  return {
173
- /**
174
- * #action
175
- * used to listen to child window for auth code/token
176
- */
177
123
  addMessageChannel(resolve, reject) {
178
124
  listener = event => {
179
- // this should probably get better handling, but ignored for now
180
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
181
125
  this.finishOAuthWindow(event, resolve, reject);
182
126
  };
183
127
  window.addEventListener('message', listener);
184
128
  },
185
- /**
186
- * #action
187
- */
188
129
  deleteMessageChannel() {
189
130
  window.removeEventListener('message', listener);
190
131
  },
191
- /**
192
- * #action
193
- */
194
132
  async finishOAuthWindow(event, resolve, reject) {
195
133
  if (event.data.name !== `JBrowseAuthWindow-${self.internetAccountId}`) {
196
134
  this.deleteMessageChannel();
@@ -243,11 +181,6 @@ const stateModelFactory = (configSchema) => {
243
181
  }
244
182
  this.deleteMessageChannel();
245
183
  },
246
- /**
247
- * #action
248
- * opens external OAuth flow, popup for web and new browser window for
249
- * desktop
250
- */
251
184
  async useEndpointForAuthorization(resolve, reject) {
252
185
  const redirectUri = isElectron
253
186
  ? 'http://localhost/auth'
@@ -282,22 +215,15 @@ const stateModelFactory = (configSchema) => {
282
215
  const eventFromDesktop = new MessageEvent('message', {
283
216
  data: { name: eventName, redirectUri: redirectUri },
284
217
  });
285
- // may want to improve handling
286
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
287
218
  this.finishOAuthWindow(eventFromDesktop, resolve, reject);
288
219
  }
289
220
  else {
290
221
  window.open(url, eventName, 'width=500,height=600,left=0,top=0');
291
222
  }
292
223
  },
293
- /**
294
- * #action
295
- */
296
224
  async getTokenFromUser(resolve, reject) {
297
225
  const refreshToken = self.retrieveRefreshToken();
298
226
  let doUserFlow = true;
299
- // if there is a refresh token, then try it out, and only if that
300
- // refresh token succeeds, set doUserFlow to false
301
227
  if (refreshToken) {
302
228
  try {
303
229
  const token = await self.exchangeRefreshForAccessToken(refreshToken);
@@ -311,14 +237,9 @@ const stateModelFactory = (configSchema) => {
311
237
  }
312
238
  if (doUserFlow) {
313
239
  this.addMessageChannel(resolve, reject);
314
- // may want to improve handling
315
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
316
240
  this.useEndpointForAuthorization(resolve, reject);
317
241
  }
318
242
  },
319
- /**
320
- * #action
321
- */
322
243
  async validateToken(token, location) {
323
244
  const newInit = self.addAuthHeaderToInit({ method: 'HEAD' }, token);
324
245
  const response = await fetch(location.uri, newInit);
@@ -337,7 +258,6 @@ const stateModelFactory = (configSchema) => {
337
258
  }
338
259
  catch (err) {
339
260
  console.error('Token could not be refreshed', err);
340
- // let original error be thrown
341
261
  }
342
262
  }
343
263
  throw new Error(await getResponseError({
@@ -352,16 +272,6 @@ const stateModelFactory = (configSchema) => {
352
272
  .actions(self => {
353
273
  const superGetFetcher = self.getFetcher;
354
274
  return {
355
- /**
356
- * #action
357
- * Get a fetch method that will add any needed authentication headers
358
- * to the request before sending it. If location is provided, it will
359
- * be checked to see if it includes a token in it's pre-auth
360
- * information.
361
- *
362
- * @param loc - UriLocation of the resource
363
- * @returns A function that can be used to fetch
364
- */
365
275
  getFetcher(loc) {
366
276
  const fetcher = superGetFetcher(loc);
367
277
  return async (input, init) => {
@@ -6,7 +6,6 @@ export async function generateChallenge(val) {
6
6
  const Base64 = await import('crypto-js/enc-base64');
7
7
  return fixup(Base64.stringify(sha256(val)));
8
8
  }
9
- // if response is JSON, checks if it needs to remove tokens in error, or just plain throw
10
9
  export function processError(text, invalidErrorCb) {
11
10
  var _a;
12
11
  try {
@@ -17,7 +16,6 @@ export function processError(text, invalidErrorCb) {
17
16
  return (_a = obj === null || obj === void 0 ? void 0 : obj.error_description) !== null && _a !== void 0 ? _a : text;
18
17
  }
19
18
  catch (e) {
20
- /* response text is not json, just use original text as error */
21
19
  }
22
20
  return text;
23
21
  }
package/esm/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import Plugin from '@jbrowse/core/Plugin';
2
- import PluginManager from '@jbrowse/core/PluginManager';
3
2
  import { modelFactory as GoogleDriveOAuthInternetAccountModelFactory } from './GoogleDriveOAuthModel';
3
+ import type PluginManager from '@jbrowse/core/PluginManager';
4
4
  export default class AuthenticationPlugin extends Plugin {
5
5
  name: string;
6
6
  exports: {
@@ -230,7 +230,7 @@ export default class AuthenticationPlugin extends Plugin {
230
230
  readonly clientId: string;
231
231
  readonly scopes: string;
232
232
  state(): string | undefined;
233
- readonly responseType: "code" | "token";
233
+ readonly responseType: "token" | "code";
234
234
  readonly refreshTokenKey: string;
235
235
  } & {
236
236
  storeRefreshToken(refreshToken: string): void;
@@ -902,7 +902,7 @@ export default class AuthenticationPlugin extends Plugin {
902
902
  readonly clientId: string;
903
903
  readonly scopes: string;
904
904
  state(): string | undefined;
905
- readonly responseType: "code" | "token";
905
+ readonly responseType: "token" | "code";
906
906
  readonly refreshTokenKey: string;
907
907
  } & {
908
908
  storeRefreshToken(refreshToken: string): void;
@@ -920,7 +920,7 @@ export default class AuthenticationPlugin extends Plugin {
920
920
  } & {
921
921
  getFetcher(loc?: import("@jbrowse/core/util").UriLocation): (input: RequestInfo, init?: RequestInit) => Promise<Response>;
922
922
  } & {
923
- readonly toggleContents: import("react").JSX.Element;
923
+ readonly toggleContents: import("react/jsx-runtime").JSX.Element;
924
924
  readonly selectorLabel: string;
925
925
  } & {
926
926
  getFetcher(location?: import("@jbrowse/core/util").UriLocation): (input: RequestInfo, init?: RequestInit) => Promise<Response>;
package/esm/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import Plugin from '@jbrowse/core/Plugin';
2
2
  import InternetAccountType from '@jbrowse/core/pluggableElementTypes/InternetAccountType';
3
- import { configSchema as OAuthConfigSchema, modelFactory as OAuthInternetAccountModelFactory, } from './OAuthModel';
4
- import { configSchema as ExternalTokenConfigSchema, modelFactory as ExternalTokenInternetAccountModelFactory, } from './ExternalTokenModel';
5
- import { configSchema as HTTPBasicConfigSchema, modelFactory as HTTPBasicInternetAccountModelFactory, } from './HTTPBasicModel';
6
3
  import { configSchema as DropboxOAuthConfigSchema, modelFactory as DropboxOAuthInternetAccountModelFactory, } from './DropboxOAuthModel';
4
+ import { configSchema as ExternalTokenConfigSchema, modelFactory as ExternalTokenInternetAccountModelFactory, } from './ExternalTokenModel';
7
5
  import { configSchema as GoogleDriveOAuthConfigSchema, modelFactory as GoogleDriveOAuthInternetAccountModelFactory, } from './GoogleDriveOAuthModel';
6
+ import { configSchema as HTTPBasicConfigSchema, modelFactory as HTTPBasicInternetAccountModelFactory, } from './HTTPBasicModel';
7
+ import { configSchema as OAuthConfigSchema, modelFactory as OAuthInternetAccountModelFactory, } from './OAuthModel';
8
8
  export default class AuthenticationPlugin extends Plugin {
9
9
  constructor() {
10
10
  super(...arguments);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/plugin-authentication",
3
- "version": "2.17.0",
3
+ "version": "3.0.0",
4
4
  "description": "JBrowse 2 Authentication",
5
5
  "keywords": [
6
6
  "jbrowse",
@@ -37,7 +37,7 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "crypto-js": "^4.2.0",
40
- "generic-filehandle": "^3.0.0"
40
+ "generic-filehandle2": "^1.0.0"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "@jbrowse/core": "^2.0.0",
@@ -55,5 +55,5 @@
55
55
  "distModule": "esm/index.js",
56
56
  "srcModule": "src/index.ts",
57
57
  "module": "esm/index.js",
58
- "gitHead": "eed30b5e671f8f7823652d7cecc51aa89226de46"
58
+ "gitHead": "2c6897f1fa732b1db5b094d1dca197e333e95319"
59
59
  }