@jbrowse/plugin-authentication 2.5.0 → 2.6.2

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 (133) hide show
  1. package/dist/DropboxOAuthModel/configSchema.d.ts +3 -14
  2. package/dist/DropboxOAuthModel/configSchema.js +0 -9
  3. package/dist/DropboxOAuthModel/index.js +0 -1
  4. package/dist/DropboxOAuthModel/model.d.ts +35 -33
  5. package/dist/DropboxOAuthModel/model.js +26 -36
  6. package/dist/DropboxOAuthModel/util.d.ts +1 -0
  7. package/dist/DropboxOAuthModel/util.js +27 -0
  8. package/dist/ExternalTokenModel/ExternalTokenEntryForm.d.ts +2 -1
  9. package/dist/ExternalTokenModel/ExternalTokenEntryForm.js +10 -12
  10. package/dist/ExternalTokenModel/configSchema.js +0 -1
  11. package/dist/ExternalTokenModel/index.js +0 -1
  12. package/dist/ExternalTokenModel/model.js +0 -1
  13. package/dist/GoogleDriveOAuthModel/GoogleDriveFilehandle.d.ts +15 -0
  14. package/dist/GoogleDriveOAuthModel/GoogleDriveFilehandle.js +19 -0
  15. package/dist/GoogleDriveOAuthModel/configSchema.d.ts +0 -5
  16. package/dist/GoogleDriveOAuthModel/configSchema.js +0 -1
  17. package/dist/GoogleDriveOAuthModel/index.js +0 -1
  18. package/dist/GoogleDriveOAuthModel/model.d.ts +36 -121
  19. package/dist/GoogleDriveOAuthModel/model.js +38 -52
  20. package/dist/GoogleDriveOAuthModel/util.d.ts +1 -0
  21. package/dist/GoogleDriveOAuthModel/util.js +16 -0
  22. package/dist/HTTPBasicModel/HTTPBasicLoginForm.d.ts +2 -1
  23. package/dist/HTTPBasicModel/HTTPBasicLoginForm.js +17 -22
  24. package/dist/HTTPBasicModel/configSchema.js +0 -1
  25. package/dist/HTTPBasicModel/index.js +0 -1
  26. package/dist/HTTPBasicModel/model.d.ts +36 -4
  27. package/dist/HTTPBasicModel/model.js +24 -10
  28. package/dist/OAuthModel/configSchema.d.ts +0 -8
  29. package/dist/OAuthModel/configSchema.js +1 -10
  30. package/dist/OAuthModel/index.js +0 -1
  31. package/dist/OAuthModel/model.d.ts +103 -18
  32. package/dist/OAuthModel/model.js +165 -114
  33. package/dist/OAuthModel/util.d.ts +7 -0
  34. package/dist/OAuthModel/util.js +59 -0
  35. package/dist/index.d.ts +7 -433
  36. package/dist/index.js +0 -1
  37. package/dist/util.d.ts +6 -0
  38. package/dist/util.js +22 -0
  39. package/esm/DropboxOAuthModel/configSchema.d.ts +3 -14
  40. package/esm/DropboxOAuthModel/configSchema.js +0 -9
  41. package/esm/DropboxOAuthModel/index.js +0 -1
  42. package/esm/DropboxOAuthModel/model.d.ts +35 -33
  43. package/esm/DropboxOAuthModel/model.js +26 -36
  44. package/esm/DropboxOAuthModel/util.d.ts +1 -0
  45. package/esm/DropboxOAuthModel/util.js +23 -0
  46. package/esm/ExternalTokenModel/ExternalTokenEntryForm.d.ts +2 -1
  47. package/esm/ExternalTokenModel/ExternalTokenEntryForm.js +10 -12
  48. package/esm/ExternalTokenModel/configSchema.js +0 -1
  49. package/esm/ExternalTokenModel/index.js +0 -1
  50. package/esm/ExternalTokenModel/model.js +0 -1
  51. package/esm/GoogleDriveOAuthModel/GoogleDriveFilehandle.d.ts +15 -0
  52. package/esm/GoogleDriveOAuthModel/GoogleDriveFilehandle.js +15 -0
  53. package/esm/GoogleDriveOAuthModel/configSchema.d.ts +0 -5
  54. package/esm/GoogleDriveOAuthModel/configSchema.js +0 -1
  55. package/esm/GoogleDriveOAuthModel/index.js +0 -1
  56. package/esm/GoogleDriveOAuthModel/model.d.ts +36 -121
  57. package/esm/GoogleDriveOAuthModel/model.js +37 -50
  58. package/esm/GoogleDriveOAuthModel/util.d.ts +1 -0
  59. package/esm/GoogleDriveOAuthModel/util.js +12 -0
  60. package/esm/HTTPBasicModel/HTTPBasicLoginForm.d.ts +2 -1
  61. package/esm/HTTPBasicModel/HTTPBasicLoginForm.js +18 -23
  62. package/esm/HTTPBasicModel/configSchema.js +0 -1
  63. package/esm/HTTPBasicModel/index.js +0 -1
  64. package/esm/HTTPBasicModel/model.d.ts +36 -4
  65. package/esm/HTTPBasicModel/model.js +24 -10
  66. package/esm/OAuthModel/configSchema.d.ts +0 -8
  67. package/esm/OAuthModel/configSchema.js +1 -10
  68. package/esm/OAuthModel/index.js +0 -1
  69. package/esm/OAuthModel/model.d.ts +103 -18
  70. package/esm/OAuthModel/model.js +164 -87
  71. package/esm/OAuthModel/util.d.ts +7 -0
  72. package/esm/OAuthModel/util.js +29 -0
  73. package/esm/index.d.ts +7 -433
  74. package/esm/index.js +0 -1
  75. package/esm/util.d.ts +6 -0
  76. package/esm/util.js +17 -0
  77. package/package.json +4 -6
  78. package/dist/DropboxOAuthModel/configSchema.js.map +0 -1
  79. package/dist/DropboxOAuthModel/index.js.map +0 -1
  80. package/dist/DropboxOAuthModel/model.js.map +0 -1
  81. package/dist/ExternalTokenModel/ExternalTokenEntryForm.js.map +0 -1
  82. package/dist/ExternalTokenModel/configSchema.js.map +0 -1
  83. package/dist/ExternalTokenModel/index.js.map +0 -1
  84. package/dist/ExternalTokenModel/model.js.map +0 -1
  85. package/dist/GoogleDriveOAuthModel/configSchema.js.map +0 -1
  86. package/dist/GoogleDriveOAuthModel/index.js.map +0 -1
  87. package/dist/GoogleDriveOAuthModel/model.js.map +0 -1
  88. package/dist/HTTPBasicModel/HTTPBasicLoginForm.js.map +0 -1
  89. package/dist/HTTPBasicModel/configSchema.js.map +0 -1
  90. package/dist/HTTPBasicModel/index.js.map +0 -1
  91. package/dist/HTTPBasicModel/model.js.map +0 -1
  92. package/dist/OAuthModel/configSchema.js.map +0 -1
  93. package/dist/OAuthModel/index.js.map +0 -1
  94. package/dist/OAuthModel/model.js.map +0 -1
  95. package/dist/index.js.map +0 -1
  96. package/esm/DropboxOAuthModel/configSchema.js.map +0 -1
  97. package/esm/DropboxOAuthModel/index.js.map +0 -1
  98. package/esm/DropboxOAuthModel/model.js.map +0 -1
  99. package/esm/ExternalTokenModel/ExternalTokenEntryForm.js.map +0 -1
  100. package/esm/ExternalTokenModel/configSchema.js.map +0 -1
  101. package/esm/ExternalTokenModel/index.js.map +0 -1
  102. package/esm/ExternalTokenModel/model.js.map +0 -1
  103. package/esm/GoogleDriveOAuthModel/configSchema.js.map +0 -1
  104. package/esm/GoogleDriveOAuthModel/index.js.map +0 -1
  105. package/esm/GoogleDriveOAuthModel/model.js.map +0 -1
  106. package/esm/HTTPBasicModel/HTTPBasicLoginForm.js.map +0 -1
  107. package/esm/HTTPBasicModel/configSchema.js.map +0 -1
  108. package/esm/HTTPBasicModel/index.js.map +0 -1
  109. package/esm/HTTPBasicModel/model.js.map +0 -1
  110. package/esm/OAuthModel/configSchema.js.map +0 -1
  111. package/esm/OAuthModel/index.js.map +0 -1
  112. package/esm/OAuthModel/model.js.map +0 -1
  113. package/esm/index.js.map +0 -1
  114. package/src/DropboxOAuthModel/configSchema.ts +0 -77
  115. package/src/DropboxOAuthModel/index.ts +0 -2
  116. package/src/DropboxOAuthModel/model.tsx +0 -141
  117. package/src/ExternalTokenModel/ExternalTokenEntryForm.tsx +0 -57
  118. package/src/ExternalTokenModel/configSchema.ts +0 -36
  119. package/src/ExternalTokenModel/index.ts +0 -2
  120. package/src/ExternalTokenModel/model.tsx +0 -70
  121. package/src/GoogleDriveOAuthModel/configSchema.ts +0 -61
  122. package/src/GoogleDriveOAuthModel/index.ts +0 -2
  123. package/src/GoogleDriveOAuthModel/model.tsx +0 -174
  124. package/src/HTTPBasicModel/HTTPBasicLoginForm.tsx +0 -71
  125. package/src/HTTPBasicModel/configSchema.ts +0 -43
  126. package/src/HTTPBasicModel/index.ts +0 -2
  127. package/src/HTTPBasicModel/model.tsx +0 -70
  128. package/src/OAuthModel/configSchema.ts +0 -98
  129. package/src/OAuthModel/index.ts +0 -2
  130. package/src/OAuthModel/model.tsx +0 -348
  131. package/src/__snapshots__/index.test.js.snap +0 -8
  132. package/src/index.test.js +0 -96
  133. package/src/index.ts +0 -108
@@ -67,18 +67,10 @@ const OAuthConfigSchema = (0, configuration_1.ConfigurationSchema)('OAuthInterne
67
67
  * #slot
68
68
  */
69
69
  responseType: {
70
- description: 'the type of response from the authorization endpoint',
70
+ description: "the type of response from the authorization endpoint. can be 'token' or 'code'",
71
71
  type: 'string',
72
72
  defaultValue: 'code',
73
73
  },
74
- /**
75
- * #slot
76
- */
77
- hasRefreshToken: {
78
- description: 'true if the endpoint can supply a refresh token',
79
- type: 'boolean',
80
- defaultValue: false,
81
- },
82
74
  }, {
83
75
  /**
84
76
  * #baseConfiguration
@@ -87,4 +79,3 @@ const OAuthConfigSchema = (0, configuration_1.ConfigurationSchema)('OAuthInterne
87
79
  explicitlyTyped: true,
88
80
  });
89
81
  exports.default = OAuthConfigSchema;
90
- //# sourceMappingURL=configSchema.js.map
@@ -8,4 +8,3 @@ var configSchema_1 = require("./configSchema");
8
8
  Object.defineProperty(exports, "configSchema", { enumerable: true, get: function () { return __importDefault(configSchema_1).default; } });
9
9
  var model_1 = require("./model");
10
10
  Object.defineProperty(exports, "modelFactory", { enumerable: true, get: function () { return __importDefault(model_1).default; } });
11
- //# sourceMappingURL=index.js.map
@@ -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
- * OAuth state parameter: https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1
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
- readonly hasRefreshToken: boolean;
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>;
@@ -1,172 +1,174 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
2
  Object.defineProperty(exports, "__esModule", { value: true });
29
3
  const configuration_1 = require("@jbrowse/core/configuration");
30
4
  const models_1 = require("@jbrowse/core/pluggableElementTypes/models");
31
5
  const util_1 = require("@jbrowse/core/util");
32
6
  const mobx_state_tree_1 = require("mobx-state-tree");
33
- const jwt_decode_1 = __importDefault(require("jwt-decode"));
34
- function fixup(buf) {
35
- return buf.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
36
- }
7
+ const util_2 = require("./util");
8
+ const util_3 = require("../util");
9
+ /**
10
+ * #stateModel OAuthInternetAccount
11
+ */
37
12
  const stateModelFactory = (configSchema) => {
38
13
  return models_1.InternetAccount.named('OAuthInternetAccount')
39
14
  .props({
15
+ /**
16
+ * #property
17
+ */
40
18
  type: mobx_state_tree_1.types.literal('OAuthInternetAccount'),
19
+ /**
20
+ * #property
21
+ */
41
22
  configuration: (0, configuration_1.ConfigurationReference)(configSchema),
42
23
  })
43
24
  .views(() => {
44
25
  let codeVerifier = undefined;
45
26
  return {
27
+ /**
28
+ * #getter
29
+ */
46
30
  get codeVerifierPKCE() {
47
31
  if (codeVerifier) {
48
32
  return codeVerifier;
49
33
  }
50
34
  const array = new Uint8Array(32);
51
35
  globalThis.crypto.getRandomValues(array);
52
- codeVerifier = fixup(Buffer.from(array).toString('base64'));
36
+ codeVerifier = (0, util_2.fixup)(Buffer.from(array).toString('base64'));
53
37
  return codeVerifier;
54
38
  },
55
39
  };
56
40
  })
57
41
  .views(self => ({
42
+ /**
43
+ * #getter
44
+ */
58
45
  get authEndpoint() {
59
46
  return (0, configuration_1.getConf)(self, 'authEndpoint');
60
47
  },
48
+ /**
49
+ * #getter
50
+ */
61
51
  get tokenEndpoint() {
62
52
  return (0, configuration_1.getConf)(self, 'tokenEndpoint');
63
53
  },
54
+ /**
55
+ * #getter
56
+ */
64
57
  get needsPKCE() {
65
58
  return (0, configuration_1.getConf)(self, 'needsPKCE');
66
59
  },
60
+ /**
61
+ * #getter
62
+ */
67
63
  get clientId() {
68
64
  return (0, configuration_1.getConf)(self, 'clientId');
69
65
  },
66
+ /**
67
+ * #getter
68
+ */
70
69
  get scopes() {
71
70
  return (0, configuration_1.getConf)(self, 'scopes');
72
71
  },
73
72
  /**
74
- * OAuth state parameter: https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1
73
+ * #method
74
+ * OAuth state parameter:
75
+ * https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1
76
+ *
75
77
  * Can override or extend if dynamic state is needed.
76
78
  */
77
79
  state() {
78
- return (0, configuration_1.getConf)(self, 'state') || undefined;
80
+ return (0, configuration_1.getConf)(self, 'state');
79
81
  },
82
+ /**
83
+ * #getter
84
+ */
80
85
  get responseType() {
81
86
  return (0, configuration_1.getConf)(self, 'responseType');
82
87
  },
83
- get hasRefreshToken() {
84
- return (0, configuration_1.getConf)(self, 'hasRefreshToken');
85
- },
88
+ /**
89
+ * #getter
90
+ */
86
91
  get refreshTokenKey() {
87
92
  return `${self.internetAccountId}-refreshToken`;
88
93
  },
89
94
  }))
90
95
  .actions(self => ({
96
+ /**
97
+ * #action
98
+ */
91
99
  storeRefreshToken(refreshToken) {
92
100
  localStorage.setItem(self.refreshTokenKey, refreshToken);
93
101
  },
102
+ /**
103
+ * #action
104
+ */
94
105
  removeRefreshToken() {
95
106
  localStorage.removeItem(self.refreshTokenKey);
96
107
  },
108
+ /**
109
+ * #method
110
+ */
97
111
  retrieveRefreshToken() {
98
112
  return localStorage.getItem(self.refreshTokenKey);
99
113
  },
114
+ /**
115
+ * #action
116
+ */
100
117
  async exchangeAuthorizationForAccessToken(token, redirectUri) {
101
- const data = {
118
+ const params = new URLSearchParams(Object.entries({
102
119
  code: token,
103
120
  grant_type: 'authorization_code',
104
121
  client_id: self.clientId,
105
- code_verifier: self.codeVerifierPKCE,
106
122
  redirect_uri: redirectUri,
107
- };
108
- const params = new URLSearchParams(Object.entries(data));
123
+ ...(self.needsPKCE ? { code_verifier: self.codeVerifierPKCE } : {}),
124
+ }));
109
125
  const response = await fetch(self.tokenEndpoint, {
110
126
  method: 'POST',
111
127
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
112
128
  body: params.toString(),
113
129
  });
114
130
  if (!response.ok) {
115
- let errorMessage;
116
- try {
117
- errorMessage = await response.text();
118
- }
119
- catch (error) {
120
- errorMessage = '';
121
- }
122
- throw new Error(`Failed to obtain token from endpoint: ${response.status} (${response.statusText})${errorMessage ? ` (${errorMessage})` : ''}`);
131
+ throw new Error(await (0, util_3.getResponseError)({
132
+ response,
133
+ reason: 'Failed to obtain token',
134
+ }));
123
135
  }
124
- const accessToken = await response.json();
125
- if (accessToken.refresh_token) {
126
- this.storeRefreshToken(accessToken.refresh_token);
127
- }
128
- return accessToken.access_token;
136
+ const data = await response.json();
137
+ return (0, util_2.processTokenResponse)(data, token => this.storeRefreshToken(token));
129
138
  },
139
+ /**
140
+ * #action
141
+ */
130
142
  async exchangeRefreshForAccessToken(refreshToken) {
131
- var _a;
132
- const data = {
133
- grant_type: 'refresh_token',
134
- refresh_token: refreshToken,
135
- client_id: self.clientId,
136
- };
137
- const params = new URLSearchParams(Object.entries(data));
138
143
  const response = await fetch(self.tokenEndpoint, {
139
144
  method: 'POST',
140
145
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
141
- body: params.toString(),
146
+ body: new URLSearchParams(Object.entries({
147
+ grant_type: 'refresh_token',
148
+ refresh_token: refreshToken,
149
+ client_id: self.clientId,
150
+ })).toString(),
142
151
  });
143
152
  if (!response.ok) {
144
153
  self.removeToken();
145
- let text = await response.text();
146
- try {
147
- const obj = JSON.parse(text);
148
- if (obj.error === 'invalid_grant') {
149
- this.removeRefreshToken();
150
- }
151
- text = (_a = obj === null || obj === void 0 ? void 0 : obj.error_description) !== null && _a !== void 0 ? _a : text;
152
- }
153
- catch (e) {
154
- /* just use original text as error */
155
- }
156
- throw new Error(`Network response failure — ${response.status} (${response.statusText}) ${text ? ` (${text})` : ''}`);
154
+ const text = await response.text();
155
+ throw new Error(await (0, util_3.getResponseError)({
156
+ response,
157
+ statusText: (0, util_2.processError)(text, () => this.removeRefreshToken()),
158
+ }));
157
159
  }
158
- const accessToken = await response.json();
159
- if (accessToken.refresh_token) {
160
- this.storeRefreshToken(accessToken.refresh_token);
161
- }
162
- return accessToken.access_token;
160
+ const data = await response.json();
161
+ return (0, util_2.processTokenResponse)(data, token => this.storeRefreshToken(token));
163
162
  },
164
163
  }))
165
164
  .actions(self => {
166
165
  let listener;
167
- let refreshTokenPromise = undefined;
166
+ let exchangedTokenPromise = undefined;
168
167
  return {
169
- // used to listen to child window for auth code/token
168
+ /**
169
+ * #action
170
+ * used to listen to child window for auth code/token
171
+ */
170
172
  addMessageChannel(resolve, reject) {
171
173
  listener = event => {
172
174
  // this should probably get better handling, but ignored for now
@@ -175,9 +177,15 @@ const stateModelFactory = (configSchema) => {
175
177
  };
176
178
  window.addEventListener('message', listener);
177
179
  },
180
+ /**
181
+ * #action
182
+ */
178
183
  deleteMessageChannel() {
179
184
  window.removeEventListener('message', listener);
180
185
  },
186
+ /**
187
+ * #action
188
+ */
181
189
  async finishOAuthWindow(event, resolve, reject) {
182
190
  if (event.data.name !== `JBrowseAuthWindow-${self.internetAccountId}`) {
183
191
  return this.deleteMessageChannel();
@@ -205,21 +213,25 @@ const stateModelFactory = (configSchema) => {
205
213
  self.storeToken(token);
206
214
  return resolve(token);
207
215
  }
208
- catch (error) {
209
- return error instanceof Error
210
- ? reject(error)
211
- : reject(new Error(String(error)));
216
+ catch (e) {
217
+ return e instanceof Error
218
+ ? reject(e)
219
+ : reject(new Error(String(e)));
212
220
  }
213
221
  }
214
222
  if (redirectUriWithInfo.includes('access_denied')) {
215
223
  return reject(new Error('OAuth flow was cancelled'));
216
224
  }
217
225
  if (redirectUriWithInfo.includes('error')) {
218
- return reject(new Error('Oauth flow error: ' + queryStringSearch));
226
+ return reject(new Error('OAuth flow error: ' + queryStringSearch));
219
227
  }
220
228
  this.deleteMessageChannel();
221
229
  },
222
- // opens external OAuth flow, popup for web and new browser window for desktop
230
+ /**
231
+ * #action
232
+ * opens external OAuth flow, popup for web and new browser window for
233
+ * desktop
234
+ */
223
235
  async useEndpointForAuthorization(resolve, reject) {
224
236
  const redirectUri = util_1.isElectron
225
237
  ? 'http://localhost/auth'
@@ -228,6 +240,7 @@ const stateModelFactory = (configSchema) => {
228
240
  client_id: self.clientId,
229
241
  redirect_uri: redirectUri,
230
242
  response_type: self.responseType || 'code',
243
+ token_access_type: 'offline',
231
244
  };
232
245
  if (self.state()) {
233
246
  data.state = self.state();
@@ -236,16 +249,9 @@ const stateModelFactory = (configSchema) => {
236
249
  data.scope = self.scopes;
237
250
  }
238
251
  if (self.needsPKCE) {
239
- const { codeVerifierPKCE } = self;
240
- const sha256 = await Promise.resolve().then(() => __importStar(require('crypto-js/sha256'))).then(f => f.default);
241
- const Base64 = await Promise.resolve().then(() => __importStar(require('crypto-js/enc-base64')));
242
- const codeChallenge = fixup(Base64.stringify(sha256(codeVerifierPKCE)));
243
- data.code_challenge = codeChallenge;
252
+ data.code_challenge = await (0, util_2.generateChallenge)(self.codeVerifierPKCE);
244
253
  data.code_challenge_method = 'S256';
245
254
  }
246
- if (self.hasRefreshToken) {
247
- data.token_access_type = 'offline';
248
- }
249
255
  const params = new URLSearchParams(Object.entries(data));
250
256
  const url = new URL(self.authEndpoint);
251
257
  url.search = params.toString();
@@ -265,45 +271,90 @@ const stateModelFactory = (configSchema) => {
265
271
  this.finishOAuthWindow(eventFromDesktop, resolve, reject);
266
272
  }
267
273
  else {
268
- const options = `width=500,height=600,left=0,top=0`;
269
- window.open(url, eventName, options);
274
+ window.open(url, eventName, `width=500,height=600,left=0,top=0`);
270
275
  }
271
276
  },
277
+ /**
278
+ * #action
279
+ */
272
280
  async getTokenFromUser(resolve, reject) {
273
- const refreshToken = self.hasRefreshToken && self.retrieveRefreshToken();
281
+ const refreshToken = self.retrieveRefreshToken();
282
+ let doUserFlow = true;
283
+ // if there is a refresh token, then try it out, and only if that
284
+ // refresh token succeeds, set doUserFlow to false
274
285
  if (refreshToken) {
275
- resolve(await self.exchangeRefreshForAccessToken(refreshToken));
286
+ try {
287
+ const token = await self.exchangeRefreshForAccessToken(refreshToken);
288
+ resolve(token);
289
+ doUserFlow = false;
290
+ }
291
+ catch (e) {
292
+ console.error(e);
293
+ self.removeRefreshToken();
294
+ }
295
+ }
296
+ if (doUserFlow) {
297
+ this.addMessageChannel(resolve, reject);
298
+ // may want to improve handling
299
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
300
+ this.useEndpointForAuthorization(resolve, reject);
276
301
  }
277
- this.addMessageChannel(resolve, reject);
278
- // may want to improve handling
279
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
280
- this.useEndpointForAuthorization(resolve, reject);
281
302
  },
303
+ /**
304
+ * #action
305
+ */
282
306
  async validateToken(token, location) {
283
- const decoded = (0, jwt_decode_1.default)(token);
284
- if (decoded.exp && decoded.exp < Date.now() / 1000) {
285
- const refreshToken = self.hasRefreshToken && self.retrieveRefreshToken();
307
+ const newInit = self.addAuthHeaderToInit({ method: 'HEAD' }, token);
308
+ const response = await fetch(location.uri, newInit);
309
+ if (!response.ok) {
310
+ self.removeToken();
311
+ const refreshToken = self.retrieveRefreshToken();
286
312
  if (refreshToken) {
287
313
  try {
288
- if (!refreshTokenPromise) {
289
- refreshTokenPromise =
314
+ if (!exchangedTokenPromise) {
315
+ exchangedTokenPromise =
290
316
  self.exchangeRefreshForAccessToken(refreshToken);
291
317
  }
292
- const newToken = await refreshTokenPromise;
293
- return this.validateToken(newToken, location);
318
+ const newToken = await exchangedTokenPromise;
319
+ exchangedTokenPromise = undefined;
320
+ return newToken;
294
321
  }
295
322
  catch (err) {
296
- throw new Error(`Token could not be refreshed. ${err}`);
323
+ console.error('Token could not be refreshed', err);
324
+ // let original error be thrown
297
325
  }
298
326
  }
299
- }
300
- else {
301
- refreshTokenPromise = undefined;
327
+ throw new Error(await (0, util_3.getResponseError)({
328
+ response,
329
+ reason: 'Error validating token',
330
+ }));
302
331
  }
303
332
  return token;
304
333
  },
305
334
  };
335
+ })
336
+ .actions(self => {
337
+ const superGetFetcher = self.getFetcher;
338
+ return {
339
+ /**
340
+ * #action
341
+ * Get a fetch method that will add any needed authentication headers to
342
+ * the request before sending it. If location is provided, it will be
343
+ * checked to see if it includes a token in it's pre-auth information.
344
+ *
345
+ * @param loc - UriLocation of the resource
346
+ * @returns A function that can be used to fetch
347
+ */
348
+ getFetcher(loc) {
349
+ const fetcher = superGetFetcher(loc);
350
+ return async (input, init) => {
351
+ if (loc) {
352
+ await self.validateToken(await self.getToken(loc), loc);
353
+ }
354
+ return fetcher(input, init);
355
+ };
356
+ },
357
+ };
306
358
  });
307
359
  };
308
360
  exports.default = stateModelFactory;
309
- //# sourceMappingURL=model.js.map