@jbrowse/plugin-authentication 4.3.0 → 5.0.0-beta.10

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 (50) hide show
  1. package/esm/DropboxOAuthModel/DropboxIcon.d.ts +1 -1
  2. package/esm/DropboxOAuthModel/configSchema.d.ts +154 -48
  3. package/esm/DropboxOAuthModel/configSchema.js +32 -2
  4. package/esm/DropboxOAuthModel/index.js +2 -2
  5. package/esm/DropboxOAuthModel/model.d.ts +301 -127
  6. package/esm/DropboxOAuthModel/model.js +46 -21
  7. package/esm/DropboxOAuthModel/util.d.ts +1 -1
  8. package/esm/DropboxOAuthModel/util.js +9 -12
  9. package/esm/ExternalTokenModel/ExternalTokenEntryForm.d.ts +1 -1
  10. package/esm/ExternalTokenModel/ExternalTokenEntryForm.js +11 -15
  11. package/esm/ExternalTokenModel/configSchema.d.ts +80 -19
  12. package/esm/ExternalTokenModel/configSchema.js +22 -1
  13. package/esm/ExternalTokenModel/index.js +2 -2
  14. package/esm/ExternalTokenModel/model.d.ts +49 -63
  15. package/esm/ExternalTokenModel/model.js +11 -54
  16. package/esm/GoogleDriveOAuthModel/GoogleDriveFilehandle.d.ts +2 -9
  17. package/esm/GoogleDriveOAuthModel/GoogleDriveFilehandle.js +27 -6
  18. package/esm/GoogleDriveOAuthModel/GoogleDriveIcon.d.ts +1 -1
  19. package/esm/GoogleDriveOAuthModel/configSchema.d.ts +152 -47
  20. package/esm/GoogleDriveOAuthModel/configSchema.js +32 -3
  21. package/esm/GoogleDriveOAuthModel/index.js +2 -2
  22. package/esm/GoogleDriveOAuthModel/model.d.ts +296 -128
  23. package/esm/GoogleDriveOAuthModel/model.js +45 -22
  24. package/esm/GoogleDriveOAuthModel/util.d.ts +1 -1
  25. package/esm/GoogleDriveOAuthModel/util.js +2 -11
  26. package/esm/HTTPBasicModel/HTTPBasicLoginForm.d.ts +1 -1
  27. package/esm/HTTPBasicModel/HTTPBasicLoginForm.js +17 -22
  28. package/esm/HTTPBasicModel/configSchema.d.ts +78 -21
  29. package/esm/HTTPBasicModel/configSchema.js +26 -1
  30. package/esm/HTTPBasicModel/index.js +2 -2
  31. package/esm/HTTPBasicModel/model.d.ts +57 -68
  32. package/esm/HTTPBasicModel/model.js +21 -51
  33. package/esm/OAuthModel/OAuthLoginPrompt.d.ts +4 -0
  34. package/esm/OAuthModel/OAuthLoginPrompt.js +12 -0
  35. package/esm/OAuthModel/configSchema.d.ts +81 -38
  36. package/esm/OAuthModel/configSchema.js +30 -1
  37. package/esm/OAuthModel/index.js +2 -2
  38. package/esm/OAuthModel/model.d.ts +231 -77
  39. package/esm/OAuthModel/model.js +361 -217
  40. package/esm/OAuthModel/util.d.ts +46 -7
  41. package/esm/OAuthModel/util.js +159 -16
  42. package/esm/index.d.ts +0 -1020
  43. package/esm/index.js +24 -57
  44. package/esm/lazyLoginForms.d.ts +18 -0
  45. package/esm/lazyLoginForms.js +25 -0
  46. package/esm/tokenEntryModelFactory.d.ts +135 -0
  47. package/esm/tokenEntryModelFactory.js +85 -0
  48. package/esm/util.d.ts +10 -0
  49. package/esm/util.js +24 -2
  50. package/package.json +10 -13
@@ -1,35 +1,59 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { ConfigurationReference } from '@jbrowse/core/configuration';
3
3
  import { types } from '@jbrowse/mobx-state-tree';
4
- import { GoogleDriveFile } from "./GoogleDriveFilehandle.js";
5
- import GoogleDriveIcon from "./GoogleDriveIcon.js";
6
- import { getDescriptiveErrorMessage } from "./util.js";
7
- import { configSchema as OAuthConfigSchema } from "../OAuthModel/index.js";
8
- import baseModel from "../OAuthModel/model.js";
4
+ import { configSchema as OAuthConfigSchema } from '../OAuthModel/index.js';
5
+ import baseModel from '../OAuthModel/model.js';
6
+ import { GoogleDriveFile } from './GoogleDriveFilehandle.js';
7
+ import GoogleDriveIcon from './GoogleDriveIcon.js';
8
+ import { getDescriptiveErrorMessage } from './util.js';
9
9
  function getUri(str) {
10
- const urlId = /[-\w]{25,}/.exec(str);
11
- return `https://www.googleapis.com/drive/v3/files/${urlId}`;
10
+ const urlId = /\/d\/([-\w]{25,})/.exec(str);
11
+ if (!urlId) {
12
+ throw new Error(`Could not extract Google Drive file ID from URL: ${str}`);
13
+ }
14
+ return `https://www.googleapis.com/drive/v3/files/${urlId[1]}`;
12
15
  }
16
+ /**
17
+ * #stateModel GoogleDriveOAuthInternetAccount
18
+ */
13
19
  export default function stateModelFactory(configSchema) {
14
20
  return baseModel(OAuthConfigSchema)
15
21
  .named('GoogleDriveOAuthInternetAccount')
16
22
  .props({
23
+ /**
24
+ * #property
25
+ */
17
26
  type: types.literal('GoogleDriveOAuthInternetAccount'),
27
+ /**
28
+ * #property
29
+ */
18
30
  configuration: ConfigurationReference(configSchema),
19
31
  })
20
32
  .views(() => ({
33
+ /**
34
+ * #getter
35
+ * The FileSelector icon for Google drive
36
+ */
21
37
  get toggleContents() {
22
38
  return _jsx(GoogleDriveIcon, {});
23
39
  },
40
+ /**
41
+ * #getter
42
+ */
24
43
  get selectorLabel() {
25
44
  return 'Enter Google Drive share link';
26
45
  },
27
46
  }))
28
47
  .actions(self => ({
48
+ /**
49
+ * #method
50
+ */
29
51
  getFetcher(location) {
30
52
  return async (input, init) => {
31
53
  const driveUrl = new URL(getUri(String(input)));
32
54
  const searchParams = new URLSearchParams();
55
+ // metadataOnly: private flag used by GoogleDriveFile constructor to
56
+ // pre-fetch just the file size for stat() without downloading content
33
57
  if (init?.metadataOnly) {
34
58
  searchParams.append('fields', 'size');
35
59
  }
@@ -37,30 +61,29 @@ export default function stateModelFactory(configSchema) {
37
61
  searchParams.append('alt', 'media');
38
62
  }
39
63
  driveUrl.search = searchParams.toString();
40
- const authToken = await self.getToken(location);
41
- const response = await fetch(driveUrl, self.addAuthHeaderToInit({ ...init, method: 'GET', credentials: 'same-origin' }, authToken));
64
+ const response = await self.fetchWithToken(location, authToken => fetch(driveUrl, self.addAuthHeaderToInit({ ...init, method: 'GET', credentials: 'same-origin' }, authToken)));
42
65
  if (!response.ok) {
43
66
  throw new Error(await getDescriptiveErrorMessage(response));
44
67
  }
45
68
  return response;
46
69
  };
47
70
  },
71
+ /**
72
+ * #action
73
+ */
74
+ async validateToken(token, location) {
75
+ const uri = getUri(location.uri);
76
+ return self.validateTokenWithProbe(token, authToken => fetch(uri, { headers: { Authorization: `Bearer ${authToken}` } }), getDescriptiveErrorMessage);
77
+ },
78
+ }))
79
+ .actions(self => ({
80
+ /**
81
+ * #method
82
+ */
48
83
  openLocation(location) {
49
84
  return new GoogleDriveFile(location.uri, {
50
- fetch: this.getFetcher(location),
51
- });
52
- },
53
- async validateToken(token, location) {
54
- const response = await fetch(getUri(location.uri), {
55
- headers: {
56
- Authorization: `Bearer ${token}`,
57
- 'Content-Type': 'application/x-www-form-urlencoded',
58
- },
85
+ fetch: self.getFetcher(location),
59
86
  });
60
- if (!response.ok) {
61
- throw new Error(await getDescriptiveErrorMessage(response, 'Token could not be validated'));
62
- }
63
- return token;
64
87
  },
65
88
  }));
66
89
  }
@@ -1 +1 @@
1
- export declare function getDescriptiveErrorMessage(response: Response, reason?: string): Promise<string>;
1
+ export declare const getDescriptiveErrorMessage: (response: Response, reason?: string) => Promise<string>;
@@ -1,11 +1,2 @@
1
- import { getResponseError } from "../util.js";
2
- export async function getDescriptiveErrorMessage(response, reason) {
3
- let errorMessage = '';
4
- try {
5
- const err = JSON.parse(await response.text());
6
- errorMessage = err.error.message;
7
- }
8
- catch (error) {
9
- }
10
- return getResponseError({ response, reason, statusText: errorMessage });
11
- }
1
+ import { descriptiveErrorMessage } from '../util.js';
2
+ export const getDescriptiveErrorMessage = descriptiveErrorMessage(err => err.error.message);
@@ -1,4 +1,4 @@
1
1
  export declare function HTTPBasicLoginForm({ internetAccountId, handleClose, }: {
2
2
  internetAccountId: string;
3
3
  handleClose: (arg?: string) => void;
4
- }): import("react/jsx-runtime").JSX.Element;
4
+ }): import("react").JSX.Element;
@@ -1,29 +1,24 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState } from 'react';
3
- import { Dialog } from '@jbrowse/core/ui';
4
- import { Button, DialogActions, DialogContent, TextField } from '@mui/material';
3
+ import { SubmitDialog } from '@jbrowse/core/ui';
4
+ import { TextField } from '@mui/material';
5
5
  export function HTTPBasicLoginForm({ internetAccountId, handleClose, }) {
6
6
  const [username, setUsername] = useState('');
7
7
  const [password, setPassword] = useState('');
8
- return (_jsx(Dialog, { open: true, maxWidth: "xl", "data-testid": "login-httpbasic", title: `Log in for ${internetAccountId}`, onClose: () => {
8
+ return (_jsx(SubmitDialog, { open: true, maxWidth: "xl", "data-testid": "login-httpbasic", title: `Log in for ${internetAccountId}`,
9
+ // an incomplete submit used to close as if cancelled, which the account
10
+ // reports as "User cancelled entry" — a failed login the user never made
11
+ submitDisabled: !username || !password, onCancel: () => {
9
12
  handleClose();
10
- }, children: _jsxs("form", { onSubmit: event => {
11
- if (username && password) {
12
- handleClose(btoa(`${username}:${password}`));
13
- }
14
- else {
15
- handleClose();
16
- }
17
- event.preventDefault();
18
- }, children: [_jsxs(DialogContent, { style: { display: 'flex', flexDirection: 'column' }, children: [_jsx(TextField, { required: true, label: "Username", variant: "outlined", onChange: event => {
19
- setUsername(event.target.value);
20
- }, margin: "dense", slotProps: {
21
- htmlInput: { 'data-testid': 'login-httpbasic-username' },
22
- } }), _jsx(TextField, { required: true, label: "Password", type: "password", autoComplete: "current-password", variant: "outlined", onChange: event => {
23
- setPassword(event.target.value);
24
- }, margin: "dense", slotProps: {
25
- htmlInput: { 'data-testid': 'login-httpbasic-password' },
26
- } })] }), _jsxs(DialogActions, { children: [_jsx(Button, { variant: "contained", color: "primary", type: "submit", children: "Submit" }), _jsx(Button, { variant: "contained", color: "secondary", type: "submit", onClick: () => {
27
- handleClose();
28
- }, children: "Cancel" })] })] }) }));
13
+ }, onSubmit: () => {
14
+ handleClose(btoa(`${username}:${password}`));
15
+ }, children: _jsxs("div", { style: { display: 'flex', flexDirection: 'column' }, children: [_jsx(TextField, { required: true, label: "Username", variant: "outlined", onChange: event => {
16
+ setUsername(event.target.value);
17
+ }, margin: "dense", slotProps: {
18
+ htmlInput: { 'data-testid': 'login-httpbasic-username' },
19
+ } }), _jsx(TextField, { required: true, label: "Password", type: "password", autoComplete: "current-password", variant: "outlined", onChange: event => {
20
+ setPassword(event.target.value);
21
+ }, margin: "dense", slotProps: {
22
+ htmlInput: { 'data-testid': 'login-httpbasic-password' },
23
+ } })] }) }));
29
24
  }
@@ -1,42 +1,99 @@
1
1
  import type { Instance } from '@jbrowse/mobx-state-tree';
2
+ /**
3
+ * #config HTTPBasicInternetAccount
4
+ *
5
+ * #example
6
+ * An entry in the config's `internetAccounts`. JBrowse prompts for the username
7
+ * and password the first time a file under one of `domains` is opened, and
8
+ * sends them as an `Authorization: Basic …` header from then on.
9
+ * ```js
10
+ * {
11
+ * type: 'HTTPBasicInternetAccount',
12
+ * internetAccountId: 'myLabServer',
13
+ * name: 'My lab server',
14
+ * description: 'Sequencing data behind the lab htaccess',
15
+ * domains: ['data.mylab.org'],
16
+ * }
17
+ * ```
18
+ */
2
19
  declare const HTTPBasicConfigSchema: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
20
+ authHeader: {
21
+ type: "string";
22
+ } & {
23
+ defaultValue: string;
24
+ };
25
+ description: {
26
+ type: "string";
27
+ } & {
28
+ defaultValue: string;
29
+ };
30
+ domains: {
31
+ type: "stringArray";
32
+ } & {
33
+ defaultValue: unknown;
34
+ };
35
+ internetAccountId: {
36
+ type: "string";
37
+ } & {
38
+ defaultValue: string;
39
+ };
40
+ name: {
41
+ type: "string";
42
+ } & {
43
+ defaultValue: string;
44
+ };
3
45
  tokenType: {
4
- description: string;
5
- type: string;
46
+ type: "string";
47
+ } & {
48
+ defaultValue: string;
49
+ };
50
+ type: {
51
+ type: "string";
52
+ } & {
6
53
  defaultValue: string;
7
54
  };
8
55
  validateWithHEAD: {
9
- description: string;
10
- type: string;
56
+ type: "boolean";
57
+ } & {
11
58
  defaultValue: boolean;
12
59
  };
13
60
  }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
14
- name: {
15
- description: string;
16
- type: string;
61
+ readonly name: {
62
+ type: "string";
63
+ } & {
17
64
  defaultValue: string;
18
65
  };
19
- description: {
20
- description: string;
21
- type: string;
66
+ readonly description: {
67
+ type: "string";
68
+ } & {
22
69
  defaultValue: string;
23
70
  };
24
- authHeader: {
25
- description: string;
26
- type: string;
71
+ readonly authHeader: {
72
+ type: "string";
73
+ } & {
27
74
  defaultValue: string;
28
75
  };
29
- tokenType: {
30
- description: string;
31
- type: string;
76
+ readonly tokenType: {
77
+ type: "string";
78
+ } & {
32
79
  defaultValue: string;
33
80
  };
34
- domains: {
35
- description: string;
36
- type: string;
37
- defaultValue: never[];
81
+ readonly domains: {
82
+ type: "stringArray";
83
+ } & {
84
+ defaultValue: unknown;
85
+ };
86
+ type: {
87
+ type: "string";
88
+ } & {
89
+ defaultValue: string;
90
+ };
91
+ internetAccountId: {
92
+ type: "string";
93
+ } & {
94
+ defaultValue: string;
38
95
  };
39
- }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "internetAccountId">>, undefined>>;
96
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "internetAccountId", true, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>, undefined, true, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>;
40
97
  export type HTTPBasicInternetAccountConfigModel = typeof HTTPBasicConfigSchema;
41
98
  export type HTTPBasicInternetAccountConfig = Instance<HTTPBasicInternetAccountConfigModel>;
42
99
  export default HTTPBasicConfigSchema;
@@ -1,18 +1,43 @@
1
1
  import { ConfigurationSchema } from '@jbrowse/core/configuration';
2
2
  import { BaseInternetAccountConfig } from '@jbrowse/core/pluggableElementTypes/models';
3
- function x() { }
3
+ /**
4
+ * #config HTTPBasicInternetAccount
5
+ *
6
+ * #example
7
+ * An entry in the config's `internetAccounts`. JBrowse prompts for the username
8
+ * and password the first time a file under one of `domains` is opened, and
9
+ * sends them as an `Authorization: Basic …` header from then on.
10
+ * ```js
11
+ * {
12
+ * type: 'HTTPBasicInternetAccount',
13
+ * internetAccountId: 'myLabServer',
14
+ * name: 'My lab server',
15
+ * description: 'Sequencing data behind the lab htaccess',
16
+ * domains: ['data.mylab.org'],
17
+ * }
18
+ * ```
19
+ */
4
20
  const HTTPBasicConfigSchema = ConfigurationSchema('HTTPBasicInternetAccount', {
21
+ /**
22
+ * #slot
23
+ */
5
24
  tokenType: {
6
25
  description: 'a custom name for a token to include in the header',
7
26
  type: 'string',
8
27
  defaultValue: 'Basic',
9
28
  },
29
+ /**
30
+ * #slot
31
+ */
10
32
  validateWithHEAD: {
11
33
  description: 'validate the token with a HEAD request before using it',
12
34
  type: 'boolean',
13
35
  defaultValue: true,
14
36
  },
15
37
  }, {
38
+ /**
39
+ * #baseConfiguration
40
+ */
16
41
  baseConfiguration: BaseInternetAccountConfig,
17
42
  explicitlyTyped: true,
18
43
  });
@@ -1,2 +1,2 @@
1
- export { default as configSchema } from "./configSchema.js";
2
- export { default as modelFactory } from "./model.js";
1
+ export { default as configSchema } from './configSchema.js';
2
+ export { default as modelFactory } from './model.js';
@@ -1,76 +1,55 @@
1
1
  import type { HTTPBasicInternetAccountConfigModel } from './configSchema.ts';
2
- import type { UriLocation } from '@jbrowse/core/util/types';
3
2
  import type { Instance } from '@jbrowse/mobx-state-tree';
4
- declare const stateModelFactory: (configSchema: HTTPBasicInternetAccountConfigModel) => import("@jbrowse/mobx-state-tree").IModelType<{
3
+ /**
4
+ * #stateModel HTTPBasicInternetAccount
5
+ * Internet account that authenticates requests with an HTTP Basic
6
+ * username/password the user enters through a dialog, optionally validated with
7
+ * a HEAD request. See [TokenEntryInternetAccount](../tokenentryinternetaccount)
8
+ * for the shared behavior.
9
+ */
10
+ declare const stateModelFactory: (configSchema: HTTPBasicInternetAccountConfigModel) => import("@jbrowse/mobx-state-tree").IModelType<Omit<{
5
11
  id: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<string>, [undefined]>;
6
12
  type: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
7
- configuration: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
8
- name: {
9
- description: string;
10
- type: string;
13
+ configuration: import("@jbrowse/core/configuration/configurationSchema").IConfigurationReference<import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
14
+ readonly name: {
15
+ type: "string";
16
+ } & {
11
17
  defaultValue: string;
12
18
  };
13
- description: {
14
- description: string;
15
- type: string;
19
+ readonly description: {
20
+ type: "string";
21
+ } & {
16
22
  defaultValue: string;
17
23
  };
18
- authHeader: {
19
- description: string;
20
- type: string;
24
+ readonly authHeader: {
25
+ type: "string";
26
+ } & {
21
27
  defaultValue: string;
22
28
  };
23
- tokenType: {
24
- description: string;
25
- type: string;
29
+ readonly tokenType: {
30
+ type: "string";
31
+ } & {
26
32
  defaultValue: string;
27
33
  };
28
- domains: {
29
- description: string;
30
- type: string;
31
- defaultValue: never[];
34
+ readonly domains: {
35
+ type: "stringArray";
36
+ } & {
37
+ defaultValue: unknown;
32
38
  };
33
- }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "internetAccountId">>;
34
- } & {
35
- type: import("@jbrowse/mobx-state-tree").ISimpleType<"HTTPBasicInternetAccount">;
36
- configuration: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
37
- tokenType: {
38
- description: string;
39
- type: string;
40
- defaultValue: string;
41
- };
42
- validateWithHEAD: {
43
- description: string;
44
- type: string;
45
- defaultValue: boolean;
46
- };
47
- }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
48
- name: {
49
- description: string;
50
- type: string;
51
- defaultValue: string;
52
- };
53
- description: {
54
- description: string;
55
- type: string;
56
- defaultValue: string;
57
- };
58
- authHeader: {
59
- description: string;
60
- type: string;
39
+ type: {
40
+ type: "string";
41
+ } & {
61
42
  defaultValue: string;
62
43
  };
63
- tokenType: {
64
- description: string;
65
- type: string;
44
+ internetAccountId: {
45
+ type: "string";
46
+ } & {
66
47
  defaultValue: string;
67
48
  };
68
- domains: {
69
- description: string;
70
- type: string;
71
- defaultValue: never[];
72
- };
73
- }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "internetAccountId">>, undefined>>;
49
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "internetAccountId", true, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>>;
50
+ }, "configuration" | "type"> & {
51
+ type: import("@jbrowse/mobx-state-tree").ILiteralType<"HTTPBasicInternetAccount">;
52
+ configuration: import("@jbrowse/core/configuration/configurationSchema").IConfigurationReference<import("@jbrowse/core/configuration").AnyConfigurationSchemaType>;
74
53
  }, {
75
54
  readonly name: string;
76
55
  readonly description: string;
@@ -79,22 +58,21 @@ declare const stateModelFactory: (configSchema: HTTPBasicInternetAccountConfigMo
79
58
  readonly tokenType: string;
80
59
  readonly domains: string[];
81
60
  readonly toggleContents: React.ReactNode;
82
- readonly SelectorComponent: import("@jbrowse/core/util").AnyReactComponentType | undefined;
83
61
  readonly selectorLabel: string | undefined;
62
+ readonly showInFileSelector: boolean;
84
63
  } & {
85
- handlesLocation(location: UriLocation): boolean;
64
+ handlesLocation(location: import("@jbrowse/core/util").UriLocation): boolean;
86
65
  readonly tokenKey: string;
87
66
  } & {
88
67
  getTokenFromUser(_resolve: (token: string) => void, _reject: (error: Error) => void): void;
89
68
  storeToken(token: string): void;
90
- removeToken(): void;
91
- retrieveToken(): string | null;
92
- validateToken(token: string, _loc: UriLocation): Promise<string>;
69
+ retrieveToken(): string | undefined;
70
+ validateToken(token: string, _loc: import("@jbrowse/core/util").UriLocation): Promise<string>;
93
71
  } & {
94
- getToken(location?: UriLocation): Promise<string>;
72
+ removeToken(): void;
73
+ getToken(location?: import("@jbrowse/core/util").UriLocation): Promise<string>;
95
74
  } & {
96
75
  addAuthHeaderToInit(init?: RequestInit, token?: string): {
97
- headers: Headers;
98
76
  body?: BodyInit | null;
99
77
  cache?: RequestCache;
100
78
  credentials?: RequestCredentials;
@@ -108,23 +86,34 @@ declare const stateModelFactory: (configSchema: HTTPBasicInternetAccountConfigMo
108
86
  referrerPolicy?: ReferrerPolicy;
109
87
  signal?: AbortSignal | null;
110
88
  window?: null;
89
+ headers: Headers;
111
90
  };
112
- getPreAuthorizationInformation(location: UriLocation): Promise<{
91
+ fetchWithToken(loc: import("@jbrowse/core/util").UriLocation | undefined, run: (token: string) => Promise<Response>): Promise<Response>;
92
+ getPreAuthorizationInformation(location: import("@jbrowse/core/util").UriLocation): Promise<{
113
93
  internetAccountType: string;
114
94
  authInfo: {
115
95
  token: string;
116
- configuration: any;
96
+ configuration: import("@jbrowse/mobx-state-tree").ModelSnapshotType<Record<string, any>>;
117
97
  };
118
98
  }>;
119
99
  } & {
120
- getFetcher(loc?: UriLocation): (input: RequestInfo, init?: RequestInit) => Promise<Response>;
100
+ getFetcher(loc?: import("@jbrowse/core/util").UriLocation): (input: RequestInfo, init?: RequestInit) => Promise<Response>;
121
101
  } & {
122
- openLocation(location: UriLocation): import("@jbrowse/core/util/io").RemoteFileWithRangeCache;
102
+ openLocation(location: import("@jbrowse/core/util").UriLocation): import("@gmod/range-cache-filehandle").RemoteFileWithRangeCache;
123
103
  } & {
124
104
  readonly validateWithHEAD: boolean;
125
105
  } & {
126
106
  getTokenFromUser(resolve: (token: string) => void, reject: (error: Error) => void): void;
127
- validateToken(token: string, location: UriLocation): Promise<string>;
107
+ validateToken(token: string, location: import("@jbrowse/core/util").UriLocation): Promise<string>;
108
+ } & {
109
+ /**
110
+ * #getter
111
+ * There is nothing to pick: an HTTP Basic account matches by domain and
112
+ * prompts on its own. RpcManager also mints one of these per origin on a
113
+ * 401, so offering them would fill the picker with a toggle per server the
114
+ * session happened to touch.
115
+ */
116
+ readonly showInFileSelector: boolean;
128
117
  }, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>;
129
118
  export default stateModelFactory;
130
119
  export type HTTPBasicStateModel = ReturnType<typeof stateModelFactory>;
@@ -1,52 +1,22 @@
1
- import { ConfigurationReference, getConf } from '@jbrowse/core/configuration';
2
- import { InternetAccount } from '@jbrowse/core/pluggableElementTypes/models';
3
- import { getRoot, types } from '@jbrowse/mobx-state-tree';
4
- import { HTTPBasicLoginForm } from "./HTTPBasicLoginForm.js";
5
- import { getResponseError } from "../util.js";
6
- const stateModelFactory = (configSchema) => {
7
- return InternetAccount.named('HTTPBasicInternetAccount')
8
- .props({
9
- type: types.literal('HTTPBasicInternetAccount'),
10
- configuration: ConfigurationReference(configSchema),
11
- })
12
- .views(self => ({
13
- get validateWithHEAD() {
14
- return getConf(self, 'validateWithHEAD');
15
- },
16
- }))
17
- .actions(self => ({
18
- getTokenFromUser(resolve, reject) {
19
- const { session } = getRoot(self);
20
- session.queueDialog((doneCallback) => [
21
- HTTPBasicLoginForm,
22
- {
23
- internetAccountId: self.internetAccountId,
24
- handleClose: (token) => {
25
- if (token) {
26
- resolve(token);
27
- }
28
- else {
29
- reject(new Error('User cancelled entry'));
30
- }
31
- doneCallback();
32
- },
33
- },
34
- ]);
35
- },
36
- async validateToken(token, location) {
37
- if (!self.validateWithHEAD) {
38
- return token;
39
- }
40
- const newInit = self.addAuthHeaderToInit({ method: 'HEAD' }, token);
41
- const response = await fetch(location.uri, newInit);
42
- if (!response.ok) {
43
- throw new Error(await getResponseError({
44
- response,
45
- reason: 'Error validating token',
46
- }));
47
- }
48
- return token;
49
- },
50
- }));
51
- };
1
+ import { HTTPBasicLoginForm } from '../lazyLoginForms.js';
2
+ import { tokenEntryModelFactory } from '../tokenEntryModelFactory.js';
3
+ /**
4
+ * #stateModel HTTPBasicInternetAccount
5
+ * Internet account that authenticates requests with an HTTP Basic
6
+ * username/password the user enters through a dialog, optionally validated with
7
+ * a HEAD request. See [TokenEntryInternetAccount](../tokenentryinternetaccount)
8
+ * for the shared behavior.
9
+ */
10
+ const stateModelFactory = (configSchema) => tokenEntryModelFactory('HTTPBasicInternetAccount', 'HTTPBasicInternetAccount', configSchema, HTTPBasicLoginForm).views(() => ({
11
+ /**
12
+ * #getter
13
+ * There is nothing to pick: an HTTP Basic account matches by domain and
14
+ * prompts on its own. RpcManager also mints one of these per origin on a
15
+ * 401, so offering them would fill the picker with a toggle per server the
16
+ * session happened to touch.
17
+ */
18
+ get showInFileSelector() {
19
+ return false;
20
+ },
21
+ }));
52
22
  export default stateModelFactory;
@@ -0,0 +1,4 @@
1
+ export declare function OAuthLoginPrompt({ internetAccountId, handleClose, }: {
2
+ internetAccountId: string;
3
+ handleClose: (proceed: boolean) => void;
4
+ }): import("react").JSX.Element;
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Dialog } from '@jbrowse/core/ui';
3
+ import { Button, DialogActions, DialogContent, Typography } from '@mui/material';
4
+ export function OAuthLoginPrompt({ internetAccountId, handleClose, }) {
5
+ return (_jsxs(Dialog, { open: true, maxWidth: "xs", "data-testid": "oauth-login-prompt", title: `Log in to ${internetAccountId}`, onClose: () => {
6
+ handleClose(false);
7
+ }, children: [_jsx(DialogContent, { children: _jsxs(Typography, { children: ["This session has a track that needs you to log in to", ' ', internetAccountId, ". Browsers only allow the login window to open from a click, so it could not be opened on your behalf."] }) }), _jsxs(DialogActions, { children: [_jsx(Button, { color: "secondary", variant: "contained", onClick: () => {
8
+ handleClose(false);
9
+ }, children: "Cancel" }), _jsx(Button, { color: "primary", variant: "contained", onClick: () => {
10
+ handleClose(true);
11
+ }, children: "Log in" })] })] }));
12
+ }