@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.
- package/esm/DropboxOAuthModel/DropboxIcon.d.ts +1 -1
- package/esm/DropboxOAuthModel/configSchema.d.ts +154 -48
- package/esm/DropboxOAuthModel/configSchema.js +32 -2
- package/esm/DropboxOAuthModel/index.js +2 -2
- package/esm/DropboxOAuthModel/model.d.ts +301 -127
- package/esm/DropboxOAuthModel/model.js +46 -21
- package/esm/DropboxOAuthModel/util.d.ts +1 -1
- package/esm/DropboxOAuthModel/util.js +9 -12
- package/esm/ExternalTokenModel/ExternalTokenEntryForm.d.ts +1 -1
- package/esm/ExternalTokenModel/ExternalTokenEntryForm.js +11 -15
- package/esm/ExternalTokenModel/configSchema.d.ts +80 -19
- package/esm/ExternalTokenModel/configSchema.js +22 -1
- package/esm/ExternalTokenModel/index.js +2 -2
- package/esm/ExternalTokenModel/model.d.ts +49 -63
- package/esm/ExternalTokenModel/model.js +11 -54
- package/esm/GoogleDriveOAuthModel/GoogleDriveFilehandle.d.ts +2 -9
- package/esm/GoogleDriveOAuthModel/GoogleDriveFilehandle.js +27 -6
- package/esm/GoogleDriveOAuthModel/GoogleDriveIcon.d.ts +1 -1
- package/esm/GoogleDriveOAuthModel/configSchema.d.ts +152 -47
- package/esm/GoogleDriveOAuthModel/configSchema.js +32 -3
- package/esm/GoogleDriveOAuthModel/index.js +2 -2
- package/esm/GoogleDriveOAuthModel/model.d.ts +296 -128
- package/esm/GoogleDriveOAuthModel/model.js +45 -22
- package/esm/GoogleDriveOAuthModel/util.d.ts +1 -1
- package/esm/GoogleDriveOAuthModel/util.js +2 -11
- package/esm/HTTPBasicModel/HTTPBasicLoginForm.d.ts +1 -1
- package/esm/HTTPBasicModel/HTTPBasicLoginForm.js +17 -22
- package/esm/HTTPBasicModel/configSchema.d.ts +78 -21
- package/esm/HTTPBasicModel/configSchema.js +26 -1
- package/esm/HTTPBasicModel/index.js +2 -2
- package/esm/HTTPBasicModel/model.d.ts +57 -68
- package/esm/HTTPBasicModel/model.js +21 -51
- package/esm/OAuthModel/OAuthLoginPrompt.d.ts +4 -0
- package/esm/OAuthModel/OAuthLoginPrompt.js +12 -0
- package/esm/OAuthModel/configSchema.d.ts +81 -38
- package/esm/OAuthModel/configSchema.js +30 -1
- package/esm/OAuthModel/index.js +2 -2
- package/esm/OAuthModel/model.d.ts +231 -77
- package/esm/OAuthModel/model.js +361 -217
- package/esm/OAuthModel/util.d.ts +46 -7
- package/esm/OAuthModel/util.js +159 -16
- package/esm/index.d.ts +0 -1020
- package/esm/index.js +24 -57
- package/esm/lazyLoginForms.d.ts +18 -0
- package/esm/lazyLoginForms.js +25 -0
- package/esm/tokenEntryModelFactory.d.ts +135 -0
- package/esm/tokenEntryModelFactory.js +85 -0
- package/esm/util.d.ts +10 -0
- package/esm/util.js +24 -2
- package/package.json +10 -13
package/esm/index.js
CHANGED
|
@@ -1,64 +1,31 @@
|
|
|
1
1
|
import Plugin from '@jbrowse/core/Plugin';
|
|
2
2
|
import InternetAccountType from '@jbrowse/core/pluggableElementTypes/InternetAccountType';
|
|
3
|
-
import { configSchema as DropboxOAuthConfigSchema, modelFactory as DropboxOAuthInternetAccountModelFactory, } from
|
|
4
|
-
import { configSchema as ExternalTokenConfigSchema, modelFactory as ExternalTokenInternetAccountModelFactory, } from
|
|
5
|
-
import { configSchema as GoogleDriveOAuthConfigSchema, modelFactory as GoogleDriveOAuthInternetAccountModelFactory, } from
|
|
6
|
-
import { configSchema as HTTPBasicConfigSchema, modelFactory as HTTPBasicInternetAccountModelFactory, } from
|
|
7
|
-
import { configSchema as OAuthConfigSchema, modelFactory as OAuthInternetAccountModelFactory, } from
|
|
3
|
+
import { configSchema as DropboxOAuthConfigSchema, modelFactory as DropboxOAuthInternetAccountModelFactory, } from './DropboxOAuthModel/index.js';
|
|
4
|
+
import { configSchema as ExternalTokenConfigSchema, modelFactory as ExternalTokenInternetAccountModelFactory, } from './ExternalTokenModel/index.js';
|
|
5
|
+
import { configSchema as GoogleDriveOAuthConfigSchema, modelFactory as GoogleDriveOAuthInternetAccountModelFactory, } from './GoogleDriveOAuthModel/index.js';
|
|
6
|
+
import { configSchema as HTTPBasicConfigSchema, modelFactory as HTTPBasicInternetAccountModelFactory, } from './HTTPBasicModel/index.js';
|
|
7
|
+
import { configSchema as OAuthConfigSchema, modelFactory as OAuthInternetAccountModelFactory, } from './OAuthModel/index.js';
|
|
8
|
+
// Generic so each call checks its own factory against its own schema — the
|
|
9
|
+
// three vary together and a table of them would only agree on their union
|
|
10
|
+
function accountType(name, configSchema, modelFactory) {
|
|
11
|
+
return () => new InternetAccountType({
|
|
12
|
+
name,
|
|
13
|
+
configSchema,
|
|
14
|
+
stateModel: modelFactory(configSchema),
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
const internetAccountTypes = [
|
|
18
|
+
accountType('OAuthInternetAccount', OAuthConfigSchema, OAuthInternetAccountModelFactory),
|
|
19
|
+
accountType('ExternalTokenInternetAccount', ExternalTokenConfigSchema, ExternalTokenInternetAccountModelFactory),
|
|
20
|
+
accountType('HTTPBasicInternetAccount', HTTPBasicConfigSchema, HTTPBasicInternetAccountModelFactory),
|
|
21
|
+
accountType('DropboxOAuthInternetAccount', DropboxOAuthConfigSchema, DropboxOAuthInternetAccountModelFactory),
|
|
22
|
+
accountType('GoogleDriveOAuthInternetAccount', GoogleDriveOAuthConfigSchema, GoogleDriveOAuthInternetAccountModelFactory),
|
|
23
|
+
];
|
|
8
24
|
export default class AuthenticationPlugin extends Plugin {
|
|
9
25
|
name = 'AuthenticationPlugin';
|
|
10
|
-
exports = {
|
|
11
|
-
OAuthConfigSchema,
|
|
12
|
-
OAuthInternetAccountModelFactory,
|
|
13
|
-
ExternalTokenConfigSchema,
|
|
14
|
-
ExternalTokenInternetAccountModelFactory,
|
|
15
|
-
HTTPBasicConfigSchema,
|
|
16
|
-
HTTPBasicInternetAccountModelFactory,
|
|
17
|
-
DropboxOAuthConfigSchema,
|
|
18
|
-
DropboxOAuthInternetAccountModelFactory,
|
|
19
|
-
GoogleDriveOAuthConfigSchema,
|
|
20
|
-
GoogleDriveOAuthInternetAccountModelFactory,
|
|
21
|
-
};
|
|
22
26
|
install(pluginManager) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
configSchema: OAuthConfigSchema,
|
|
27
|
-
stateModel: OAuthInternetAccountModelFactory(OAuthConfigSchema),
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
|
-
pluginManager.addInternetAccountType(() => {
|
|
31
|
-
return new InternetAccountType({
|
|
32
|
-
name: 'ExternalTokenInternetAccount',
|
|
33
|
-
configSchema: ExternalTokenConfigSchema,
|
|
34
|
-
stateModel: ExternalTokenInternetAccountModelFactory(ExternalTokenConfigSchema),
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
pluginManager.addInternetAccountType(() => {
|
|
38
|
-
return new InternetAccountType({
|
|
39
|
-
name: 'HTTPBasicInternetAccount',
|
|
40
|
-
configSchema: HTTPBasicConfigSchema,
|
|
41
|
-
stateModel: HTTPBasicInternetAccountModelFactory(HTTPBasicConfigSchema),
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
pluginManager.addInternetAccountType(() => {
|
|
45
|
-
return new InternetAccountType({
|
|
46
|
-
name: 'DropboxOAuthInternetAccount',
|
|
47
|
-
configSchema: DropboxOAuthConfigSchema,
|
|
48
|
-
stateModel: DropboxOAuthInternetAccountModelFactory(DropboxOAuthConfigSchema),
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
pluginManager.addInternetAccountType(() => {
|
|
52
|
-
return new InternetAccountType({
|
|
53
|
-
name: 'GoogleDriveOAuthInternetAccount',
|
|
54
|
-
configSchema: GoogleDriveOAuthConfigSchema,
|
|
55
|
-
stateModel: GoogleDriveOAuthInternetAccountModelFactory(GoogleDriveOAuthConfigSchema),
|
|
56
|
-
});
|
|
57
|
-
});
|
|
27
|
+
for (const makeAccountType of internetAccountTypes) {
|
|
28
|
+
pluginManager.addInternetAccountType(makeAccountType);
|
|
29
|
+
}
|
|
58
30
|
}
|
|
59
31
|
}
|
|
60
|
-
export { configSchema as OAuthConfigSchema, modelFactory as OAuthInternetAccountModelFactory, } from "./OAuthModel/index.js";
|
|
61
|
-
export { configSchema as ExternalTokenConfigSchema, modelFactory as ExternalTokenInternetAccountModelFactory, } from "./ExternalTokenModel/index.js";
|
|
62
|
-
export { configSchema as HTTPBasicConfigSchema, modelFactory as HTTPBasicInternetAccountModelFactory, } from "./HTTPBasicModel/index.js";
|
|
63
|
-
export { configSchema as DropboxOAuthConfigSchema, modelFactory as DropboxOAuthInternetAccountModelFactory, } from "./DropboxOAuthModel/index.js";
|
|
64
|
-
export { configSchema as GoogleDriveOAuthConfigSchema, modelFactory as GoogleDriveOAuthInternetAccountModelFactory, } from "./GoogleDriveOAuthModel/index.js";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The forms and prompts the internet accounts ask the user for a credential
|
|
3
|
+
* with, behind their own chunks.
|
|
4
|
+
*
|
|
5
|
+
* An internet account's state model is registered when the plugin installs, and
|
|
6
|
+
* each of these models named its form at module scope — so every host shipped
|
|
7
|
+
* the form, `SubmitDialog` and the MUI text-field/dialog graph behind them
|
|
8
|
+
* before anything could possibly have asked for a credential. Most sessions
|
|
9
|
+
* never authenticate at all. See `agent-docs/reference/EAGER_BUNDLE.md`.
|
|
10
|
+
*
|
|
11
|
+
* `getTokenFromUser` passes the form to `session.queueDialog`, and `DialogQueue`
|
|
12
|
+
* renders it inside a `Suspense` boundary, so lazy needs nothing at the call
|
|
13
|
+
* site. All are named exports, hence the `.then` — `lazy` wants a module
|
|
14
|
+
* with a `default`.
|
|
15
|
+
*/
|
|
16
|
+
export declare const HTTPBasicLoginForm: import("react").LazyExoticComponent<typeof import("./HTTPBasicModel/HTTPBasicLoginForm.tsx").HTTPBasicLoginForm>;
|
|
17
|
+
export declare const ExternalTokenEntryForm: import("react").LazyExoticComponent<typeof import("./ExternalTokenModel/ExternalTokenEntryForm.tsx").ExternalTokenEntryForm>;
|
|
18
|
+
export declare const OAuthLoginPrompt: import("react").LazyExoticComponent<typeof import("./OAuthModel/OAuthLoginPrompt.tsx").OAuthLoginPrompt>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { lazy } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* The forms and prompts the internet accounts ask the user for a credential
|
|
4
|
+
* with, behind their own chunks.
|
|
5
|
+
*
|
|
6
|
+
* An internet account's state model is registered when the plugin installs, and
|
|
7
|
+
* each of these models named its form at module scope — so every host shipped
|
|
8
|
+
* the form, `SubmitDialog` and the MUI text-field/dialog graph behind them
|
|
9
|
+
* before anything could possibly have asked for a credential. Most sessions
|
|
10
|
+
* never authenticate at all. See `agent-docs/reference/EAGER_BUNDLE.md`.
|
|
11
|
+
*
|
|
12
|
+
* `getTokenFromUser` passes the form to `session.queueDialog`, and `DialogQueue`
|
|
13
|
+
* renders it inside a `Suspense` boundary, so lazy needs nothing at the call
|
|
14
|
+
* site. All are named exports, hence the `.then` — `lazy` wants a module
|
|
15
|
+
* with a `default`.
|
|
16
|
+
*/
|
|
17
|
+
export const HTTPBasicLoginForm = lazy(() => import('./HTTPBasicModel/HTTPBasicLoginForm.js').then(m => ({
|
|
18
|
+
default: m.HTTPBasicLoginForm,
|
|
19
|
+
})));
|
|
20
|
+
export const ExternalTokenEntryForm = lazy(() => import('./ExternalTokenModel/ExternalTokenEntryForm.js').then(m => ({
|
|
21
|
+
default: m.ExternalTokenEntryForm,
|
|
22
|
+
})));
|
|
23
|
+
export const OAuthLoginPrompt = lazy(() => import('./OAuthModel/OAuthLoginPrompt.js').then(m => ({
|
|
24
|
+
default: m.OAuthLoginPrompt,
|
|
25
|
+
})));
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { AnyConfigurationSchemaType } from '@jbrowse/core/configuration';
|
|
2
|
+
import type { UriLocation } from '@jbrowse/core/util/types';
|
|
3
|
+
import type React from 'react';
|
|
4
|
+
type TokenEntryForm = React.FC<{
|
|
5
|
+
internetAccountId: string;
|
|
6
|
+
handleClose: (token?: string) => void;
|
|
7
|
+
}>;
|
|
8
|
+
/**
|
|
9
|
+
* #stateModel TokenEntryInternetAccount
|
|
10
|
+
* Shared base for internet accounts whose token is supplied by the user through
|
|
11
|
+
* a dialog (HTTP Basic, external token). Such accounts differ only in their
|
|
12
|
+
* discriminating `type` and the dialog form used to collect the token, both
|
|
13
|
+
* passed here. Not registered on its own — see HTTPBasicInternetAccount and
|
|
14
|
+
* ExternalTokenInternetAccount.
|
|
15
|
+
*/
|
|
16
|
+
export declare function tokenEntryModelFactory<Type extends string>(modelName: string, typeName: Type, configSchema: AnyConfigurationSchemaType, LoginForm: TokenEntryForm): import("@jbrowse/mobx-state-tree").IModelType<Omit<{
|
|
17
|
+
id: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
18
|
+
type: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
19
|
+
configuration: import("@jbrowse/core/configuration/configurationSchema").IConfigurationReference<import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
20
|
+
readonly name: {
|
|
21
|
+
type: "string";
|
|
22
|
+
} & {
|
|
23
|
+
defaultValue: string;
|
|
24
|
+
};
|
|
25
|
+
readonly description: {
|
|
26
|
+
type: "string";
|
|
27
|
+
} & {
|
|
28
|
+
defaultValue: string;
|
|
29
|
+
};
|
|
30
|
+
readonly authHeader: {
|
|
31
|
+
type: "string";
|
|
32
|
+
} & {
|
|
33
|
+
defaultValue: string;
|
|
34
|
+
};
|
|
35
|
+
readonly tokenType: {
|
|
36
|
+
type: "string";
|
|
37
|
+
} & {
|
|
38
|
+
defaultValue: string;
|
|
39
|
+
};
|
|
40
|
+
readonly domains: {
|
|
41
|
+
type: "stringArray";
|
|
42
|
+
} & {
|
|
43
|
+
defaultValue: unknown;
|
|
44
|
+
};
|
|
45
|
+
type: {
|
|
46
|
+
type: "string";
|
|
47
|
+
} & {
|
|
48
|
+
defaultValue: string;
|
|
49
|
+
};
|
|
50
|
+
internetAccountId: {
|
|
51
|
+
type: "string";
|
|
52
|
+
} & {
|
|
53
|
+
defaultValue: string;
|
|
54
|
+
};
|
|
55
|
+
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "internetAccountId", true, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>>;
|
|
56
|
+
}, "configuration" | "type"> & {
|
|
57
|
+
/**
|
|
58
|
+
* #property
|
|
59
|
+
*/
|
|
60
|
+
type: import("@jbrowse/mobx-state-tree").ILiteralType<Type>;
|
|
61
|
+
/**
|
|
62
|
+
* #property
|
|
63
|
+
*/
|
|
64
|
+
configuration: import("@jbrowse/core/configuration/configurationSchema").IConfigurationReference<AnyConfigurationSchemaType>;
|
|
65
|
+
}, {
|
|
66
|
+
readonly name: string;
|
|
67
|
+
readonly description: string;
|
|
68
|
+
readonly internetAccountId: string;
|
|
69
|
+
readonly authHeader: string;
|
|
70
|
+
readonly tokenType: string;
|
|
71
|
+
readonly domains: string[];
|
|
72
|
+
readonly toggleContents: React.ReactNode;
|
|
73
|
+
readonly selectorLabel: string | undefined;
|
|
74
|
+
readonly showInFileSelector: boolean;
|
|
75
|
+
} & {
|
|
76
|
+
handlesLocation(location: UriLocation): boolean;
|
|
77
|
+
readonly tokenKey: string;
|
|
78
|
+
} & {
|
|
79
|
+
getTokenFromUser(_resolve: (token: string) => void, _reject: (error: Error) => void): void;
|
|
80
|
+
storeToken(token: string): void;
|
|
81
|
+
retrieveToken(): string | undefined;
|
|
82
|
+
validateToken(token: string, _loc: UriLocation): Promise<string>;
|
|
83
|
+
} & {
|
|
84
|
+
removeToken(): void;
|
|
85
|
+
getToken(location?: UriLocation): Promise<string>;
|
|
86
|
+
} & {
|
|
87
|
+
addAuthHeaderToInit(init?: RequestInit, token?: string): {
|
|
88
|
+
body?: BodyInit | null;
|
|
89
|
+
cache?: RequestCache;
|
|
90
|
+
credentials?: RequestCredentials;
|
|
91
|
+
integrity?: string;
|
|
92
|
+
keepalive?: boolean;
|
|
93
|
+
method?: string;
|
|
94
|
+
mode?: RequestMode;
|
|
95
|
+
priority?: RequestPriority;
|
|
96
|
+
redirect?: RequestRedirect;
|
|
97
|
+
referrer?: string;
|
|
98
|
+
referrerPolicy?: ReferrerPolicy;
|
|
99
|
+
signal?: AbortSignal | null;
|
|
100
|
+
window?: null;
|
|
101
|
+
headers: Headers;
|
|
102
|
+
};
|
|
103
|
+
fetchWithToken(loc: UriLocation | undefined, run: (token: string) => Promise<Response>): Promise<Response>;
|
|
104
|
+
getPreAuthorizationInformation(location: UriLocation): Promise<{
|
|
105
|
+
internetAccountType: string;
|
|
106
|
+
authInfo: {
|
|
107
|
+
token: string;
|
|
108
|
+
configuration: import("@jbrowse/mobx-state-tree").ModelSnapshotType<Record<string, any>>;
|
|
109
|
+
};
|
|
110
|
+
}>;
|
|
111
|
+
} & {
|
|
112
|
+
getFetcher(loc?: UriLocation): (input: RequestInfo, init?: RequestInit) => Promise<Response>;
|
|
113
|
+
} & {
|
|
114
|
+
openLocation(location: UriLocation): import("@gmod/range-cache-filehandle").RemoteFileWithRangeCache;
|
|
115
|
+
} & {
|
|
116
|
+
/**
|
|
117
|
+
* #getter
|
|
118
|
+
* validate the token with a HEAD request before it is used
|
|
119
|
+
*/
|
|
120
|
+
readonly validateWithHEAD: boolean;
|
|
121
|
+
} & {
|
|
122
|
+
/**
|
|
123
|
+
* #action
|
|
124
|
+
* Prompt the user for a token via the account's dialog form, resolving
|
|
125
|
+
* with the entered token or rejecting if the user cancels.
|
|
126
|
+
*/
|
|
127
|
+
getTokenFromUser(resolve: (token: string) => void, reject: (error: Error) => void): void;
|
|
128
|
+
/**
|
|
129
|
+
* #action
|
|
130
|
+
* Optionally validate the token with a HEAD request before use, per the
|
|
131
|
+
* `validateWithHEAD` config slot.
|
|
132
|
+
*/
|
|
133
|
+
validateToken(token: string, location: UriLocation): Promise<string>;
|
|
134
|
+
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>;
|
|
135
|
+
export {};
|
|
@@ -0,0 +1,85 @@
|
|
|
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 { getResponseError } from './util.js';
|
|
5
|
+
/**
|
|
6
|
+
* #stateModel TokenEntryInternetAccount
|
|
7
|
+
* Shared base for internet accounts whose token is supplied by the user through
|
|
8
|
+
* a dialog (HTTP Basic, external token). Such accounts differ only in their
|
|
9
|
+
* discriminating `type` and the dialog form used to collect the token, both
|
|
10
|
+
* passed here. Not registered on its own — see HTTPBasicInternetAccount and
|
|
11
|
+
* ExternalTokenInternetAccount.
|
|
12
|
+
*/
|
|
13
|
+
export function tokenEntryModelFactory(modelName, typeName, configSchema, LoginForm) {
|
|
14
|
+
return InternetAccount.named(modelName)
|
|
15
|
+
.props({
|
|
16
|
+
/**
|
|
17
|
+
* #property
|
|
18
|
+
*/
|
|
19
|
+
type: types.literal(typeName),
|
|
20
|
+
/**
|
|
21
|
+
* #property
|
|
22
|
+
*/
|
|
23
|
+
configuration: ConfigurationReference(configSchema),
|
|
24
|
+
})
|
|
25
|
+
.views(self => ({
|
|
26
|
+
/**
|
|
27
|
+
* #getter
|
|
28
|
+
* validate the token with a HEAD request before it is used
|
|
29
|
+
*/
|
|
30
|
+
get validateWithHEAD() {
|
|
31
|
+
return getConf(self, 'validateWithHEAD');
|
|
32
|
+
},
|
|
33
|
+
}))
|
|
34
|
+
.actions(self => ({
|
|
35
|
+
/**
|
|
36
|
+
* #action
|
|
37
|
+
* Prompt the user for a token via the account's dialog form, resolving
|
|
38
|
+
* with the entered token or rejecting if the user cancels.
|
|
39
|
+
*/
|
|
40
|
+
getTokenFromUser(resolve, reject) {
|
|
41
|
+
const { session } = getRoot(self);
|
|
42
|
+
session.queueDialog((doneCallback) => [
|
|
43
|
+
LoginForm,
|
|
44
|
+
{
|
|
45
|
+
internetAccountId: self.internetAccountId,
|
|
46
|
+
handleClose: (token) => {
|
|
47
|
+
if (token) {
|
|
48
|
+
resolve(token);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
reject(new Error('User cancelled entry'));
|
|
52
|
+
}
|
|
53
|
+
doneCallback();
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
]);
|
|
57
|
+
},
|
|
58
|
+
/**
|
|
59
|
+
* #action
|
|
60
|
+
* Optionally validate the token with a HEAD request before use, per the
|
|
61
|
+
* `validateWithHEAD` config slot.
|
|
62
|
+
*/
|
|
63
|
+
async validateToken(token, location) {
|
|
64
|
+
if (!self.validateWithHEAD) {
|
|
65
|
+
return token;
|
|
66
|
+
}
|
|
67
|
+
const response = await fetch(location.uri, self.addAuthHeaderToInit({ method: 'HEAD' }, token));
|
|
68
|
+
if (!response.ok) {
|
|
69
|
+
// The HEAD just proved this credential unusable, and there is nothing
|
|
70
|
+
// to renew it with — the only source is the user. Dropping it is what
|
|
71
|
+
// lets the next read re-open the dialog; keeping it meant a mistyped
|
|
72
|
+
// password threw the same error on every request for the rest of the
|
|
73
|
+
// session and was never asked for again. `getPreAuthorizationInform-
|
|
74
|
+
// ation` already dropped it on this path, so only the direct
|
|
75
|
+
// main-thread reads were affected.
|
|
76
|
+
self.removeToken();
|
|
77
|
+
throw new Error(await getResponseError({
|
|
78
|
+
response,
|
|
79
|
+
reason: 'Error validating token',
|
|
80
|
+
}));
|
|
81
|
+
}
|
|
82
|
+
return token;
|
|
83
|
+
},
|
|
84
|
+
}));
|
|
85
|
+
}
|
package/esm/util.d.ts
CHANGED
|
@@ -4,3 +4,13 @@ export declare function getResponseError({ response, reason, statusText, }: {
|
|
|
4
4
|
statusText?: string;
|
|
5
5
|
}): Promise<string>;
|
|
6
6
|
export declare function getError(response: Response): Promise<string>;
|
|
7
|
+
/**
|
|
8
|
+
* Builds the `describeError` a provider hands `validateTokenWithProbe` and
|
|
9
|
+
* throws from its fetcher: read the body, pull the human-readable part out of
|
|
10
|
+
* the provider's own error JSON, and fall back to the raw text when it is not
|
|
11
|
+
* that shape at all — an HTML error page from a proxy in front of the API, say.
|
|
12
|
+
*
|
|
13
|
+
* `extract` runs inside the same guard as the parse, so it may reach into the
|
|
14
|
+
* payload without checking each hop.
|
|
15
|
+
*/
|
|
16
|
+
export declare function descriptiveErrorMessage<T>(extract: (parsed: T) => string | undefined): (response: Response, reason?: string) => Promise<string>;
|
package/esm/util.js
CHANGED
|
@@ -4,14 +4,36 @@ export async function getResponseError({ response, reason, statusText, }) {
|
|
|
4
4
|
reason,
|
|
5
5
|
statusText ?? (await getError(response)),
|
|
6
6
|
]
|
|
7
|
-
.filter(
|
|
7
|
+
.filter(Boolean)
|
|
8
8
|
.join(' - ');
|
|
9
9
|
}
|
|
10
10
|
export async function getError(response) {
|
|
11
11
|
try {
|
|
12
12
|
return await response.text();
|
|
13
13
|
}
|
|
14
|
-
catch
|
|
14
|
+
catch {
|
|
15
15
|
return response.statusText;
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Builds the `describeError` a provider hands `validateTokenWithProbe` and
|
|
20
|
+
* throws from its fetcher: read the body, pull the human-readable part out of
|
|
21
|
+
* the provider's own error JSON, and fall back to the raw text when it is not
|
|
22
|
+
* that shape at all — an HTML error page from a proxy in front of the API, say.
|
|
23
|
+
*
|
|
24
|
+
* `extract` runs inside the same guard as the parse, so it may reach into the
|
|
25
|
+
* payload without checking each hop.
|
|
26
|
+
*/
|
|
27
|
+
export function descriptiveErrorMessage(extract) {
|
|
28
|
+
return async (response, reason) => {
|
|
29
|
+
const text = await response.text();
|
|
30
|
+
let statusText = text;
|
|
31
|
+
try {
|
|
32
|
+
statusText = extract(JSON.parse(text)) ?? text;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// statusText stays as raw response text
|
|
36
|
+
}
|
|
37
|
+
return getResponseError({ response, reason, statusText });
|
|
38
|
+
};
|
|
39
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/plugin-authentication",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0-beta.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "JBrowse 2 Authentication",
|
|
6
6
|
"keywords": [
|
|
@@ -21,15 +21,15 @@
|
|
|
21
21
|
"esm"
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@jbrowse/mobx-state-tree": "^
|
|
25
|
-
"@mui/material": "^
|
|
26
|
-
"generic-filehandle2": "^2.
|
|
27
|
-
"mobx": "^
|
|
28
|
-
"@jbrowse/core": "^
|
|
24
|
+
"@jbrowse/mobx-state-tree": "^6.6.1",
|
|
25
|
+
"@mui/material": "^9.4.0",
|
|
26
|
+
"generic-filehandle2": "^2.4.0",
|
|
27
|
+
"mobx": "^7.0.5",
|
|
28
|
+
"@jbrowse/core": "^5.0.0-beta.10"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
|
-
"react": ">=
|
|
32
|
-
"react-dom": ">=
|
|
31
|
+
"react": ">=19.0.0",
|
|
32
|
+
"react-dom": ">=19.0.0"
|
|
33
33
|
},
|
|
34
34
|
"publishConfig": {
|
|
35
35
|
"access": "public"
|
|
@@ -39,14 +39,11 @@
|
|
|
39
39
|
"build": "pnpm run /^build:/",
|
|
40
40
|
"test": "cd ../..; jest --passWithNoTests plugins/authentication",
|
|
41
41
|
"prebuild": "pnpm clean",
|
|
42
|
-
"build:esm": "tsc
|
|
42
|
+
"build:esm": "node ../../node_modules/typescript7/bin/tsc --build tsconfig.build.esm.json",
|
|
43
43
|
"clean": "rimraf esm *.tsbuildinfo"
|
|
44
44
|
},
|
|
45
45
|
"types": "esm/index.d.ts",
|
|
46
46
|
"exports": {
|
|
47
|
-
".":
|
|
48
|
-
"types": "./esm/index.d.ts",
|
|
49
|
-
"import": "./esm/index.js"
|
|
50
|
-
}
|
|
47
|
+
".": "./esm/index.js"
|
|
51
48
|
}
|
|
52
49
|
}
|