@deephaven/auth-plugins 0.37.4-beta.0 → 0.37.4-logout.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,4 @@
1
1
  import React from 'react';
2
- import { CoreClient } from '@deephaven/jsapi-types';
3
2
  /**
4
3
  * Map from auth config keys to their values
5
4
  * E.g. Map { AuthHandlers → "io.deephaven.auth.AnonymousAuthenticationHandler" }
@@ -11,18 +10,16 @@ export type AuthConfigMap = Map<string, string>;
11
10
  export type AuthPluginProps = {
12
11
  /** Map from config keys to their values */
13
12
  authConfigValues: AuthConfigMap;
14
- /** Client to check auth configuration on */
15
- client: CoreClient;
16
- /** Called when authentication is sucessful */
17
- onSuccess(): void;
18
- /** Called when authentication fails */
19
- onFailure(error: unknown): void;
13
+ /**
14
+ * The children to render after authentication is completed.
15
+ */
16
+ children: React.ReactNode;
20
17
  };
21
18
  export type AuthPluginComponent = React.FunctionComponent<AuthPluginProps>;
22
19
  /**
23
20
  * Whether the auth plugin is available given the current configuration
24
21
  */
25
- export type AuthPluginIsAvailableFunction = (authHandlers: string[]) => boolean;
22
+ export type AuthPluginIsAvailableFunction = (authHandlers: string[], authConfig: AuthConfigMap) => boolean;
26
23
  export type AuthPlugin = {
27
24
  Component: AuthPluginComponent;
28
25
  isAvailable: AuthPluginIsAvailableFunction;
@@ -1 +1 @@
1
- {"version":3,"file":"AuthPlugin.d.ts","sourceRoot":"","sources":["../src/AuthPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEhD;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,2CAA2C;IAC3C,gBAAgB,EAAE,aAAa,CAAC;IAEhC,4CAA4C;IAC5C,MAAM,EAAE,UAAU,CAAC;IAEnB,8CAA8C;IAC9C,SAAS,IAAI,IAAI,CAAC;IAElB,uCAAuC;IACvC,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,KAAK,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC;AAE3E;;GAEG;AACH,MAAM,MAAM,6BAA6B,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC;AAEhF,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,mBAAmB,CAAC;IAC/B,WAAW,EAAE,6BAA6B,CAAC;CAC5C,CAAC;AAEF,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,IAAI,UAAU,CAOnE"}
1
+ {"version":3,"file":"AuthPlugin.d.ts","sourceRoot":"","sources":["../src/AuthPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEhD;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,2CAA2C;IAC3C,gBAAgB,EAAE,aAAa,CAAC;IAEhC;;OAEG;IACH,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,KAAK,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC;AAE3E;;GAEG;AACH,MAAM,MAAM,6BAA6B,GAAG,CAC1C,YAAY,EAAE,MAAM,EAAE,EACtB,UAAU,EAAE,aAAa,KACtB,OAAO,CAAC;AAEb,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,mBAAmB,CAAC;IAC/B,WAAW,EAAE,6BAA6B,CAAC;CAC5C,CAAC;AAEF,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,IAAI,UAAU,CAOnE"}
@@ -1 +1 @@
1
- {"version":3,"file":"AuthPlugin.js","names":["isAuthPlugin","plugin","authPlugin","Component","undefined","isAvailable"],"sources":["../src/AuthPlugin.ts"],"sourcesContent":["import React from 'react';\nimport { CoreClient } from '@deephaven/jsapi-types';\n\n/**\n * Map from auth config keys to their values\n * E.g. Map { AuthHandlers → \"io.deephaven.auth.AnonymousAuthenticationHandler\" }\n */\nexport type AuthConfigMap = Map<string, string>;\n\n/**\n * Props for the auth plugin component to render\n */\nexport type AuthPluginProps = {\n /** Map from config keys to their values */\n authConfigValues: AuthConfigMap;\n\n /** Client to check auth configuration on */\n client: CoreClient;\n\n /** Called when authentication is sucessful */\n onSuccess(): void;\n\n /** Called when authentication fails */\n onFailure(error: unknown): void;\n};\n\nexport type AuthPluginComponent = React.FunctionComponent<AuthPluginProps>;\n\n/**\n * Whether the auth plugin is available given the current configuration\n */\nexport type AuthPluginIsAvailableFunction = (authHandlers: string[]) => boolean;\n\nexport type AuthPlugin = {\n Component: AuthPluginComponent;\n isAvailable: AuthPluginIsAvailableFunction;\n};\n\nexport function isAuthPlugin(plugin?: unknown): plugin is AuthPlugin {\n if (plugin == null) return false;\n const authPlugin = plugin as AuthPlugin;\n return (\n authPlugin.Component !== undefined &&\n typeof authPlugin.isAvailable === 'function'\n );\n}\n"],"mappings":"AAGA;AACA;AACA;AACA;;AAGA;AACA;AACA;;AAiBA;AACA;AACA;;AAQA,OAAO,SAASA,YAAY,CAACC,MAAgB,EAAwB;EACnE,IAAIA,MAAM,IAAI,IAAI,EAAE,OAAO,KAAK;EAChC,IAAMC,UAAU,GAAGD,MAAoB;EACvC,OACEC,UAAU,CAACC,SAAS,KAAKC,SAAS,IAClC,OAAOF,UAAU,CAACG,WAAW,KAAK,UAAU;AAEhD"}
1
+ {"version":3,"file":"AuthPlugin.js","names":["isAuthPlugin","plugin","authPlugin","Component","undefined","isAvailable"],"sources":["../src/AuthPlugin.ts"],"sourcesContent":["import React from 'react';\n\n/**\n * Map from auth config keys to their values\n * E.g. Map { AuthHandlers → \"io.deephaven.auth.AnonymousAuthenticationHandler\" }\n */\nexport type AuthConfigMap = Map<string, string>;\n\n/**\n * Props for the auth plugin component to render\n */\nexport type AuthPluginProps = {\n /** Map from config keys to their values */\n authConfigValues: AuthConfigMap;\n\n /**\n * The children to render after authentication is completed.\n */\n children: React.ReactNode;\n};\n\nexport type AuthPluginComponent = React.FunctionComponent<AuthPluginProps>;\n\n/**\n * Whether the auth plugin is available given the current configuration\n */\nexport type AuthPluginIsAvailableFunction = (\n authHandlers: string[],\n authConfig: AuthConfigMap\n) => boolean;\n\nexport type AuthPlugin = {\n Component: AuthPluginComponent;\n isAvailable: AuthPluginIsAvailableFunction;\n};\n\nexport function isAuthPlugin(plugin?: unknown): plugin is AuthPlugin {\n if (plugin == null) return false;\n const authPlugin = plugin as AuthPlugin;\n return (\n authPlugin.Component !== undefined &&\n typeof authPlugin.isAvailable === 'function'\n );\n}\n"],"mappings":"AAEA;AACA;AACA;AACA;;AAGA;AACA;AACA;;AAaA;AACA;AACA;;AAWA,OAAO,SAASA,YAAY,CAACC,MAAgB,EAAwB;EACnE,IAAIA,MAAM,IAAI,IAAI,EAAE,OAAO,KAAK;EAChC,IAAMC,UAAU,GAAGD,MAAoB;EACvC,OACEC,UAAU,CAACC,SAAS,KAAKC,SAAS,IAClC,OAAOF,UAAU,CAACG,WAAW,KAAK,UAAU;AAEhD"}
@@ -1 +1 @@
1
- {"version":3,"file":"AuthPluginAnonymous.d.ts","sourceRoot":"","sources":["../src/AuthPluginAnonymous.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAmB,MAAM,cAAc,CAAC;AAoD3D,QAAA,MAAM,mBAAmB,EAAE,UAI1B,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"AuthPluginAnonymous.d.ts","sourceRoot":"","sources":["../src/AuthPluginAnonymous.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAmB,MAAM,cAAc,CAAC;AA6B3D,QAAA,MAAM,mBAAmB,EAAE,UAI1B,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -1,64 +1,32 @@
1
1
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
2
2
  function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
3
- import React, { useEffect, useState } from 'react';
3
+ import React, { useCallback } from 'react';
4
4
  import { useApi } from '@deephaven/jsapi-bootstrap';
5
- import Log from '@deephaven/log';
6
- import { LoadingOverlay } from '@deephaven/components';
7
5
  import { AUTH_HANDLER_TYPE_ANONYMOUS } from "./AuthHandlerTypes.js";
8
- var log = Log.module('AuthPluginAnonymous');
6
+ import AuthPluginBase from "./AuthPluginBase.js";
7
+ import { UserPermissionsOverrideContext } from "./UserContexts.js";
8
+ var permissionsOverrides = {
9
+ canLogout: false
10
+ };
9
11
 
10
12
  /**
11
13
  * AuthPlugin that tries to login anonymously. Fails if anonymous login fails
12
14
  */
13
15
  function Component(_ref) {
14
16
  var {
15
- client,
16
- onSuccess,
17
- onFailure
17
+ children
18
18
  } = _ref;
19
- var [error, setError] = useState();
20
19
  var dh = useApi();
21
- useEffect(() => {
22
- var isCanceled = false;
23
- function login() {
24
- return _login.apply(this, arguments);
25
- }
26
- function _login() {
27
- _login = _asyncToGenerator(function* () {
28
- try {
29
- log.info('Logging in...');
30
- yield client.login({
31
- type: dh.CoreClient.LOGIN_TYPE_ANONYMOUS
32
- });
33
- if (isCanceled) {
34
- log.info('Previous login result canceled');
35
- return;
36
- }
37
- log.info('Logged in successfully.');
38
- onSuccess();
39
- } catch (e) {
40
- if (isCanceled) {
41
- log.info('Previous login failure canceled');
42
- return;
43
- }
44
- log.error('Unable to login:', e);
45
- setError(e);
46
- onFailure(e);
47
- }
48
- });
49
- return _login.apply(this, arguments);
50
- }
51
- login();
52
- return () => {
53
- isCanceled = true;
20
+ var getLoginOptions = useCallback( /*#__PURE__*/_asyncToGenerator(function* () {
21
+ return {
22
+ type: dh.CoreClient.LOGIN_TYPE_ANONYMOUS
54
23
  };
55
- }, [client, dh, onFailure, onSuccess]);
56
- return /*#__PURE__*/React.createElement(LoadingOverlay, {
57
- "data-testid": "auth-anonymous-loading",
58
- isLoading: true,
59
- isLoaded: false,
60
- errorMessage: error != null ? "".concat(error) : null
61
- });
24
+ }), [dh]);
25
+ return /*#__PURE__*/React.createElement(AuthPluginBase, {
26
+ getLoginOptions: getLoginOptions
27
+ }, /*#__PURE__*/React.createElement(UserPermissionsOverrideContext.Provider, {
28
+ value: permissionsOverrides
29
+ }, children));
62
30
  }
63
31
  var AuthPluginAnonymous = {
64
32
  Component,
@@ -1 +1 @@
1
- {"version":3,"file":"AuthPluginAnonymous.js","names":["React","useEffect","useState","useApi","Log","LoadingOverlay","AUTH_HANDLER_TYPE_ANONYMOUS","log","module","Component","client","onSuccess","onFailure","error","setError","dh","isCanceled","login","info","type","CoreClient","LOGIN_TYPE_ANONYMOUS","e","AuthPluginAnonymous","isAvailable","authHandlers","includes"],"sources":["../src/AuthPluginAnonymous.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react';\nimport { useApi } from '@deephaven/jsapi-bootstrap';\nimport Log from '@deephaven/log';\nimport { LoadingOverlay } from '@deephaven/components';\nimport { AUTH_HANDLER_TYPE_ANONYMOUS } from './AuthHandlerTypes';\nimport { AuthPlugin, AuthPluginProps } from './AuthPlugin';\n\nconst log = Log.module('AuthPluginAnonymous');\n\n/**\n * AuthPlugin that tries to login anonymously. Fails if anonymous login fails\n */\nfunction Component({\n client,\n onSuccess,\n onFailure,\n}: AuthPluginProps): JSX.Element {\n const [error, setError] = useState<unknown>();\n const dh = useApi();\n\n useEffect(() => {\n let isCanceled = false;\n async function login() {\n try {\n log.info('Logging in...');\n await client.login({ type: dh.CoreClient.LOGIN_TYPE_ANONYMOUS });\n if (isCanceled) {\n log.info('Previous login result canceled');\n return;\n }\n log.info('Logged in successfully.');\n onSuccess();\n } catch (e) {\n if (isCanceled) {\n log.info('Previous login failure canceled');\n return;\n }\n log.error('Unable to login:', e);\n setError(e);\n onFailure(e);\n }\n }\n login();\n return () => {\n isCanceled = true;\n };\n }, [client, dh, onFailure, onSuccess]);\n return (\n <LoadingOverlay\n data-testid=\"auth-anonymous-loading\"\n isLoading\n isLoaded={false}\n errorMessage={error != null ? `${error}` : null}\n />\n );\n}\n\nconst AuthPluginAnonymous: AuthPlugin = {\n Component,\n isAvailable: authHandlers =>\n authHandlers.includes(AUTH_HANDLER_TYPE_ANONYMOUS),\n};\n\nexport default AuthPluginAnonymous;\n"],"mappings":";;AAAA,OAAOA,KAAK,IAAIC,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AAClD,SAASC,MAAM,QAAQ,4BAA4B;AACnD,OAAOC,GAAG,MAAM,gBAAgB;AAChC,SAASC,cAAc,QAAQ,uBAAuB;AAAC,SAC9CC,2BAA2B;AAGpC,IAAMC,GAAG,GAAGH,GAAG,CAACI,MAAM,CAAC,qBAAqB,CAAC;;AAE7C;AACA;AACA;AACA,SAASC,SAAS,OAIe;EAAA,IAJd;IACjBC,MAAM;IACNC,SAAS;IACTC;EACe,CAAC;EAChB,IAAM,CAACC,KAAK,EAAEC,QAAQ,CAAC,GAAGZ,QAAQ,EAAW;EAC7C,IAAMa,EAAE,GAAGZ,MAAM,EAAE;EAEnBF,SAAS,CAAC,MAAM;IACd,IAAIe,UAAU,GAAG,KAAK;IAAC,SACRC,KAAK;MAAA;IAAA;IAAA;MAAA,2BAApB,aAAuB;QACrB,IAAI;UACFV,GAAG,CAACW,IAAI,CAAC,eAAe,CAAC;UACzB,MAAMR,MAAM,CAACO,KAAK,CAAC;YAAEE,IAAI,EAAEJ,EAAE,CAACK,UAAU,CAACC;UAAqB,CAAC,CAAC;UAChE,IAAIL,UAAU,EAAE;YACdT,GAAG,CAACW,IAAI,CAAC,gCAAgC,CAAC;YAC1C;UACF;UACAX,GAAG,CAACW,IAAI,CAAC,yBAAyB,CAAC;UACnCP,SAAS,EAAE;QACb,CAAC,CAAC,OAAOW,CAAC,EAAE;UACV,IAAIN,UAAU,EAAE;YACdT,GAAG,CAACW,IAAI,CAAC,iCAAiC,CAAC;YAC3C;UACF;UACAX,GAAG,CAACM,KAAK,CAAC,kBAAkB,EAAES,CAAC,CAAC;UAChCR,QAAQ,CAACQ,CAAC,CAAC;UACXV,SAAS,CAACU,CAAC,CAAC;QACd;MACF,CAAC;MAAA;IAAA;IACDL,KAAK,EAAE;IACP,OAAO,MAAM;MACXD,UAAU,GAAG,IAAI;IACnB,CAAC;EACH,CAAC,EAAE,CAACN,MAAM,EAAEK,EAAE,EAAEH,SAAS,EAAED,SAAS,CAAC,CAAC;EACtC,oBACE,oBAAC,cAAc;IACb,eAAY,wBAAwB;IACpC,SAAS;IACT,QAAQ,EAAE,KAAM;IAChB,YAAY,EAAEE,KAAK,IAAI,IAAI,aAAMA,KAAK,IAAK;EAAK,EAChD;AAEN;AAEA,IAAMU,mBAA+B,GAAG;EACtCd,SAAS;EACTe,WAAW,EAAEC,YAAY,IACvBA,YAAY,CAACC,QAAQ,CAACpB,2BAA2B;AACrD,CAAC;AAED,eAAeiB,mBAAmB"}
1
+ {"version":3,"file":"AuthPluginAnonymous.js","names":["React","useCallback","useApi","AUTH_HANDLER_TYPE_ANONYMOUS","AuthPluginBase","UserPermissionsOverrideContext","permissionsOverrides","canLogout","Component","children","dh","getLoginOptions","type","CoreClient","LOGIN_TYPE_ANONYMOUS","AuthPluginAnonymous","isAvailable","authHandlers","includes"],"sources":["../src/AuthPluginAnonymous.tsx"],"sourcesContent":["import React, { useCallback } from 'react';\nimport { useApi } from '@deephaven/jsapi-bootstrap';\nimport { AUTH_HANDLER_TYPE_ANONYMOUS } from './AuthHandlerTypes';\nimport { AuthPlugin, AuthPluginProps } from './AuthPlugin';\nimport AuthPluginBase from './AuthPluginBase';\nimport {\n UserPermissionsOverride,\n UserPermissionsOverrideContext,\n} from './UserContexts';\n\nconst permissionsOverrides: UserPermissionsOverride = { canLogout: false };\n\n/**\n * AuthPlugin that tries to login anonymously. Fails if anonymous login fails\n */\nfunction Component({ children }: AuthPluginProps): JSX.Element {\n const dh = useApi();\n\n const getLoginOptions = useCallback(\n async () => ({ type: dh.CoreClient.LOGIN_TYPE_ANONYMOUS }),\n [dh]\n );\n\n return (\n <AuthPluginBase getLoginOptions={getLoginOptions}>\n <UserPermissionsOverrideContext.Provider value={permissionsOverrides}>\n {children}\n </UserPermissionsOverrideContext.Provider>\n </AuthPluginBase>\n );\n}\n\nconst AuthPluginAnonymous: AuthPlugin = {\n Component,\n isAvailable: authHandlers =>\n authHandlers.includes(AUTH_HANDLER_TYPE_ANONYMOUS),\n};\n\nexport default AuthPluginAnonymous;\n"],"mappings":";;AAAA,OAAOA,KAAK,IAAIC,WAAW,QAAQ,OAAO;AAC1C,SAASC,MAAM,QAAQ,4BAA4B;AAAC,SAC3CC,2BAA2B;AAAA,OAE7BC,cAAc;AAAA,SAGnBC,8BAA8B;AAGhC,IAAMC,oBAA6C,GAAG;EAAEC,SAAS,EAAE;AAAM,CAAC;;AAE1E;AACA;AACA;AACA,SAASC,SAAS,OAA6C;EAAA,IAA5C;IAAEC;EAA0B,CAAC;EAC9C,IAAMC,EAAE,GAAGR,MAAM,EAAE;EAEnB,IAAMS,eAAe,GAAGV,WAAW,iCACjC;IAAA,OAAa;MAAEW,IAAI,EAAEF,EAAE,CAACG,UAAU,CAACC;IAAqB,CAAC;EAAA,CAAC,GAC1D,CAACJ,EAAE,CAAC,CACL;EAED,oBACE,oBAAC,cAAc;IAAC,eAAe,EAAEC;EAAgB,gBAC/C,oBAAC,8BAA8B,CAAC,QAAQ;IAAC,KAAK,EAAEL;EAAqB,GAClEG,QAAQ,CAC+B,CAC3B;AAErB;AAEA,IAAMM,mBAA+B,GAAG;EACtCP,SAAS;EACTQ,WAAW,EAAEC,YAAY,IACvBA,YAAY,CAACC,QAAQ,CAACf,2BAA2B;AACrD,CAAC;AAED,eAAeY,mBAAmB"}
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import { LoginOptions } from '@deephaven/jsapi-types';
3
+ export type AuthPluginBaseProps = {
4
+ /**
5
+ * The children to render after authentication is completed.
6
+ */
7
+ children: React.ReactNode;
8
+ /**
9
+ * Retrieve the login options for logging in to the client
10
+ * @returns A promise for the login options
11
+ */
12
+ getLoginOptions: () => Promise<LoginOptions>;
13
+ };
14
+ /**
15
+ * Base AuthPlugin that gets passed a function for retrieving the login options, and then attempting to login with them.
16
+ * @param getLoginOptions Function that returns a promise for the login options
17
+ */
18
+ declare function AuthPluginBase({ children, getLoginOptions, }: AuthPluginBaseProps): JSX.Element;
19
+ export default AuthPluginBase;
20
+ //# sourceMappingURL=AuthPluginBase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthPluginBase.d.ts","sourceRoot":"","sources":["../src/AuthPluginBase.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAInD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAKtD,MAAM,MAAM,mBAAmB,GAAG;IAChC;;OAEG;IACH,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAE1B;;;OAGG;IACH,eAAe,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;CAC9C,CAAC;AAEF;;;GAGG;AACH,iBAAS,cAAc,CAAC,EACtB,QAAQ,EACR,eAAe,GAChB,EAAE,mBAAmB,GAAG,GAAG,CAAC,OAAO,CAiDnC;AAED,eAAe,cAAc,CAAC"}
@@ -0,0 +1,68 @@
1
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
2
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
3
+ import React, { useEffect, useState } from 'react';
4
+ import { LoadingOverlay } from '@deephaven/components';
5
+ import { useClient } from '@deephaven/jsapi-bootstrap';
6
+ import Log from '@deephaven/log';
7
+ import { CanceledPromiseError } from '@deephaven/utils';
8
+ var log = Log.module('AuthPluginBase');
9
+ /**
10
+ * Base AuthPlugin that gets passed a function for retrieving the login options, and then attempting to login with them.
11
+ * @param getLoginOptions Function that returns a promise for the login options
12
+ */
13
+ function AuthPluginBase(_ref) {
14
+ var {
15
+ children,
16
+ getLoginOptions
17
+ } = _ref;
18
+ var client = useClient();
19
+ var [error, setError] = useState();
20
+ var [isLoggedIn, setIsLoggedIn] = useState(false);
21
+ useEffect(() => {
22
+ var isCanceled = false;
23
+ function verifyNotCanceled() {
24
+ if (isCanceled) {
25
+ throw new CanceledPromiseError('Login canceled.');
26
+ }
27
+ }
28
+ function login() {
29
+ return _login.apply(this, arguments);
30
+ }
31
+ function _login() {
32
+ _login = _asyncToGenerator(function* () {
33
+ try {
34
+ var loginOptions = yield getLoginOptions();
35
+ verifyNotCanceled();
36
+ log.info('Logging in...');
37
+ yield client.login(loginOptions);
38
+ verifyNotCanceled();
39
+ setIsLoggedIn(true);
40
+ } catch (e) {
41
+ if (!isCanceled) {
42
+ log.error('Unable to login:', e);
43
+ setError(e);
44
+ setIsLoggedIn(false);
45
+ }
46
+ }
47
+ });
48
+ return _login.apply(this, arguments);
49
+ }
50
+ login();
51
+ return () => {
52
+ isCanceled = true;
53
+ };
54
+ }, [client, getLoginOptions]);
55
+ if (!isLoggedIn) {
56
+ return /*#__PURE__*/React.createElement(LoadingOverlay, {
57
+ "data-testid": "auth-base-loading",
58
+ isLoading: error == null,
59
+ isLoaded: false,
60
+ errorMessage: error != null ? "".concat(error) : null
61
+ });
62
+ }
63
+
64
+ // eslint-disable-next-line react/jsx-no-useless-fragment
65
+ return /*#__PURE__*/React.createElement(React.Fragment, null, children);
66
+ }
67
+ export default AuthPluginBase;
68
+ //# sourceMappingURL=AuthPluginBase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthPluginBase.js","names":["React","useEffect","useState","LoadingOverlay","useClient","Log","CanceledPromiseError","log","module","AuthPluginBase","children","getLoginOptions","client","error","setError","isLoggedIn","setIsLoggedIn","isCanceled","verifyNotCanceled","login","loginOptions","info","e"],"sources":["../src/AuthPluginBase.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react';\nimport { LoadingOverlay } from '@deephaven/components';\nimport { useClient } from '@deephaven/jsapi-bootstrap';\nimport Log from '@deephaven/log';\nimport { LoginOptions } from '@deephaven/jsapi-types';\nimport { CanceledPromiseError } from '@deephaven/utils';\n\nconst log = Log.module('AuthPluginBase');\n\nexport type AuthPluginBaseProps = {\n /**\n * The children to render after authentication is completed.\n */\n children: React.ReactNode;\n\n /**\n * Retrieve the login options for logging in to the client\n * @returns A promise for the login options\n */\n getLoginOptions: () => Promise<LoginOptions>;\n};\n\n/**\n * Base AuthPlugin that gets passed a function for retrieving the login options, and then attempting to login with them.\n * @param getLoginOptions Function that returns a promise for the login options\n */\nfunction AuthPluginBase({\n children,\n getLoginOptions,\n}: AuthPluginBaseProps): JSX.Element {\n const client = useClient();\n const [error, setError] = useState<unknown>();\n const [isLoggedIn, setIsLoggedIn] = useState(false);\n\n useEffect(() => {\n let isCanceled = false;\n function verifyNotCanceled() {\n if (isCanceled) {\n throw new CanceledPromiseError('Login canceled.');\n }\n }\n async function login() {\n try {\n const loginOptions = await getLoginOptions();\n verifyNotCanceled();\n\n log.info('Logging in...');\n await client.login(loginOptions);\n verifyNotCanceled();\n\n setIsLoggedIn(true);\n } catch (e) {\n if (!isCanceled) {\n log.error('Unable to login:', e);\n setError(e);\n setIsLoggedIn(false);\n }\n }\n }\n login();\n return () => {\n isCanceled = true;\n };\n }, [client, getLoginOptions]);\n\n if (!isLoggedIn) {\n return (\n <LoadingOverlay\n data-testid=\"auth-base-loading\"\n isLoading={error == null}\n isLoaded={false}\n errorMessage={error != null ? `${error}` : null}\n />\n );\n }\n\n // eslint-disable-next-line react/jsx-no-useless-fragment\n return <>{children}</>;\n}\n\nexport default AuthPluginBase;\n"],"mappings":";;AAAA,OAAOA,KAAK,IAAIC,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AAClD,SAASC,cAAc,QAAQ,uBAAuB;AACtD,SAASC,SAAS,QAAQ,4BAA4B;AACtD,OAAOC,GAAG,MAAM,gBAAgB;AAEhC,SAASC,oBAAoB,QAAQ,kBAAkB;AAEvD,IAAMC,GAAG,GAAGF,GAAG,CAACG,MAAM,CAAC,gBAAgB,CAAC;AAexC;AACA;AACA;AACA;AACA,SAASC,cAAc,OAGc;EAAA,IAHb;IACtBC,QAAQ;IACRC;EACmB,CAAC;EACpB,IAAMC,MAAM,GAAGR,SAAS,EAAE;EAC1B,IAAM,CAACS,KAAK,EAAEC,QAAQ,CAAC,GAAGZ,QAAQ,EAAW;EAC7C,IAAM,CAACa,UAAU,EAAEC,aAAa,CAAC,GAAGd,QAAQ,CAAC,KAAK,CAAC;EAEnDD,SAAS,CAAC,MAAM;IACd,IAAIgB,UAAU,GAAG,KAAK;IACtB,SAASC,iBAAiB,GAAG;MAC3B,IAAID,UAAU,EAAE;QACd,MAAM,IAAIX,oBAAoB,CAAC,iBAAiB,CAAC;MACnD;IACF;IAAC,SACca,KAAK;MAAA;IAAA;IAAA;MAAA,2BAApB,aAAuB;QACrB,IAAI;UACF,IAAMC,YAAY,SAAST,eAAe,EAAE;UAC5CO,iBAAiB,EAAE;UAEnBX,GAAG,CAACc,IAAI,CAAC,eAAe,CAAC;UACzB,MAAMT,MAAM,CAACO,KAAK,CAACC,YAAY,CAAC;UAChCF,iBAAiB,EAAE;UAEnBF,aAAa,CAAC,IAAI,CAAC;QACrB,CAAC,CAAC,OAAOM,CAAC,EAAE;UACV,IAAI,CAACL,UAAU,EAAE;YACfV,GAAG,CAACM,KAAK,CAAC,kBAAkB,EAAES,CAAC,CAAC;YAChCR,QAAQ,CAACQ,CAAC,CAAC;YACXN,aAAa,CAAC,KAAK,CAAC;UACtB;QACF;MACF,CAAC;MAAA;IAAA;IACDG,KAAK,EAAE;IACP,OAAO,MAAM;MACXF,UAAU,GAAG,IAAI;IACnB,CAAC;EACH,CAAC,EAAE,CAACL,MAAM,EAAED,eAAe,CAAC,CAAC;EAE7B,IAAI,CAACI,UAAU,EAAE;IACf,oBACE,oBAAC,cAAc;MACb,eAAY,mBAAmB;MAC/B,SAAS,EAAEF,KAAK,IAAI,IAAK;MACzB,QAAQ,EAAE,KAAM;MAChB,YAAY,EAAEA,KAAK,IAAI,IAAI,aAAMA,KAAK,IAAK;IAAK,EAChD;EAEN;;EAEA;EACA,oBAAO,0CAAGH,QAAQ,CAAI;AACxB;AAEA,eAAeD,cAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"AuthPluginParent.d.ts","sourceRoot":"","sources":["../src/AuthPluginParent.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAE,UAAU,EAAmB,MAAM,cAAc,CAAC;AA8C3D,QAAA,MAAM,gBAAgB,EAAE,UAIvB,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"AuthPluginParent.d.ts","sourceRoot":"","sources":["../src/AuthPluginParent.tsx"],"names":[],"mappings":"AAOA,OAAO,EAAE,UAAU,EAAmB,MAAM,cAAc,CAAC;AAiC3D,QAAA,MAAM,gBAAgB,EAAE,UAIvB,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -1,10 +1,16 @@
1
- function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
2
- function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
3
- import React, { useEffect, useState } from 'react';
1
+ import React from 'react';
4
2
  import { LOGIN_OPTIONS_REQUEST, requestParentResponse } from '@deephaven/jsapi-utils';
5
3
  import Log from '@deephaven/log';
6
- import { LoadingOverlay } from '@deephaven/components';
4
+ import AuthPluginBase from "./AuthPluginBase.js";
5
+ import { UserPermissionsOverrideContext } from "./UserContexts.js";
7
6
  var log = Log.module('AuthPluginParent');
7
+ var permissionsOverrides = {
8
+ canLogout: false
9
+ };
10
+ function getLoginOptions() {
11
+ log.info('Logging in by delegating to parent window...');
12
+ return requestParentResponse(LOGIN_OPTIONS_REQUEST);
13
+ }
8
14
  function getWindowAuthProvider() {
9
15
  var _URLSearchParams$get;
10
16
  return (_URLSearchParams$get = new URLSearchParams(window.location.search).get('authProvider')) !== null && _URLSearchParams$get !== void 0 ? _URLSearchParams$get : '';
@@ -15,39 +21,13 @@ function getWindowAuthProvider() {
15
21
  */
16
22
  function Component(_ref) {
17
23
  var {
18
- client,
19
- onSuccess,
20
- onFailure
24
+ children
21
25
  } = _ref;
22
- var [error, setError] = useState();
23
- useEffect(() => {
24
- function login() {
25
- return _login.apply(this, arguments);
26
- }
27
- function _login() {
28
- _login = _asyncToGenerator(function* () {
29
- try {
30
- log.info('Logging in by delegating to parent window...');
31
- var loginOptions = yield requestParentResponse(LOGIN_OPTIONS_REQUEST);
32
- yield client.login(loginOptions);
33
- log.info('Logged in successfully.');
34
- onSuccess();
35
- } catch (e) {
36
- log.error('Unable to login:', e);
37
- setError(e);
38
- onFailure(e);
39
- }
40
- });
41
- return _login.apply(this, arguments);
42
- }
43
- login();
44
- }, [client, onFailure, onSuccess]);
45
- return /*#__PURE__*/React.createElement(LoadingOverlay, {
46
- "data-testid": "auth-parent-loading",
47
- isLoading: true,
48
- isLoaded: false,
49
- errorMessage: error != null ? "".concat(error) : null
50
- });
26
+ return /*#__PURE__*/React.createElement(AuthPluginBase, {
27
+ getLoginOptions: getLoginOptions
28
+ }, /*#__PURE__*/React.createElement(UserPermissionsOverrideContext.Provider, {
29
+ value: permissionsOverrides
30
+ }, children));
51
31
  }
52
32
  var AuthPluginParent = {
53
33
  Component,
@@ -1 +1 @@
1
- {"version":3,"file":"AuthPluginParent.js","names":["React","useEffect","useState","LOGIN_OPTIONS_REQUEST","requestParentResponse","Log","LoadingOverlay","log","module","getWindowAuthProvider","URLSearchParams","window","location","search","get","Component","client","onSuccess","onFailure","error","setError","login","info","loginOptions","e","AuthPluginParent","isAvailable","opener"],"sources":["../src/AuthPluginParent.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react';\nimport { LoginOptions } from '@deephaven/jsapi-types';\nimport {\n LOGIN_OPTIONS_REQUEST,\n requestParentResponse,\n} from '@deephaven/jsapi-utils';\nimport Log from '@deephaven/log';\nimport { LoadingOverlay } from '@deephaven/components';\nimport { AuthPlugin, AuthPluginProps } from './AuthPlugin';\n\nconst log = Log.module('AuthPluginParent');\n\nfunction getWindowAuthProvider(): string {\n return new URLSearchParams(window.location.search).get('authProvider') ?? '';\n}\n\n/**\n * AuthPlugin that tries to delegate to the parent window for authentication. Fails if there is no parent window.\n */\nfunction Component({\n client,\n onSuccess,\n onFailure,\n}: AuthPluginProps): JSX.Element {\n const [error, setError] = useState<unknown>();\n useEffect(() => {\n async function login() {\n try {\n log.info('Logging in by delegating to parent window...');\n const loginOptions = await requestParentResponse<LoginOptions>(\n LOGIN_OPTIONS_REQUEST\n );\n\n await client.login(loginOptions);\n log.info('Logged in successfully.');\n onSuccess();\n } catch (e) {\n log.error('Unable to login:', e);\n setError(e);\n onFailure(e);\n }\n }\n login();\n }, [client, onFailure, onSuccess]);\n return (\n <LoadingOverlay\n data-testid=\"auth-parent-loading\"\n isLoading\n isLoaded={false}\n errorMessage={error != null ? `${error}` : null}\n />\n );\n}\n\nconst AuthPluginParent: AuthPlugin = {\n Component,\n isAvailable: () =>\n window.opener != null && getWindowAuthProvider() === 'parent',\n};\n\nexport default AuthPluginParent;\n"],"mappings":";;AAAA,OAAOA,KAAK,IAAIC,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AAElD,SACEC,qBAAqB,EACrBC,qBAAqB,QAChB,wBAAwB;AAC/B,OAAOC,GAAG,MAAM,gBAAgB;AAChC,SAASC,cAAc,QAAQ,uBAAuB;AAGtD,IAAMC,GAAG,GAAGF,GAAG,CAACG,MAAM,CAAC,kBAAkB,CAAC;AAE1C,SAASC,qBAAqB,GAAW;EAAA;EACvC,+BAAO,IAAIC,eAAe,CAACC,MAAM,CAACC,QAAQ,CAACC,MAAM,CAAC,CAACC,GAAG,CAAC,cAAc,CAAC,uEAAI,EAAE;AAC9E;;AAEA;AACA;AACA;AACA,SAASC,SAAS,OAIe;EAAA,IAJd;IACjBC,MAAM;IACNC,SAAS;IACTC;EACe,CAAC;EAChB,IAAM,CAACC,KAAK,EAAEC,QAAQ,CAAC,GAAGlB,QAAQ,EAAW;EAC7CD,SAAS,CAAC,MAAM;IAAA,SACCoB,KAAK;MAAA;IAAA;IAAA;MAAA,2BAApB,aAAuB;QACrB,IAAI;UACFd,GAAG,CAACe,IAAI,CAAC,8CAA8C,CAAC;UACxD,IAAMC,YAAY,SAASnB,qBAAqB,CAC9CD,qBAAqB,CACtB;UAED,MAAMa,MAAM,CAACK,KAAK,CAACE,YAAY,CAAC;UAChChB,GAAG,CAACe,IAAI,CAAC,yBAAyB,CAAC;UACnCL,SAAS,EAAE;QACb,CAAC,CAAC,OAAOO,CAAC,EAAE;UACVjB,GAAG,CAACY,KAAK,CAAC,kBAAkB,EAAEK,CAAC,CAAC;UAChCJ,QAAQ,CAACI,CAAC,CAAC;UACXN,SAAS,CAACM,CAAC,CAAC;QACd;MACF,CAAC;MAAA;IAAA;IACDH,KAAK,EAAE;EACT,CAAC,EAAE,CAACL,MAAM,EAAEE,SAAS,EAAED,SAAS,CAAC,CAAC;EAClC,oBACE,oBAAC,cAAc;IACb,eAAY,qBAAqB;IACjC,SAAS;IACT,QAAQ,EAAE,KAAM;IAChB,YAAY,EAAEE,KAAK,IAAI,IAAI,aAAMA,KAAK,IAAK;EAAK,EAChD;AAEN;AAEA,IAAMM,gBAA4B,GAAG;EACnCV,SAAS;EACTW,WAAW,EAAE,MACXf,MAAM,CAACgB,MAAM,IAAI,IAAI,IAAIlB,qBAAqB,EAAE,KAAK;AACzD,CAAC;AAED,eAAegB,gBAAgB"}
1
+ {"version":3,"file":"AuthPluginParent.js","names":["React","LOGIN_OPTIONS_REQUEST","requestParentResponse","Log","AuthPluginBase","UserPermissionsOverrideContext","log","module","permissionsOverrides","canLogout","getLoginOptions","info","getWindowAuthProvider","URLSearchParams","window","location","search","get","Component","children","AuthPluginParent","isAvailable","opener"],"sources":["../src/AuthPluginParent.tsx"],"sourcesContent":["import React from 'react';\nimport { LoginOptions } from '@deephaven/jsapi-types';\nimport {\n LOGIN_OPTIONS_REQUEST,\n requestParentResponse,\n} from '@deephaven/jsapi-utils';\nimport Log from '@deephaven/log';\nimport { AuthPlugin, AuthPluginProps } from './AuthPlugin';\nimport AuthPluginBase from './AuthPluginBase';\nimport {\n UserPermissionsOverride,\n UserPermissionsOverrideContext,\n} from './UserContexts';\n\nconst log = Log.module('AuthPluginParent');\n\nconst permissionsOverrides: UserPermissionsOverride = { canLogout: false };\n\nfunction getLoginOptions(): Promise<LoginOptions> {\n log.info('Logging in by delegating to parent window...');\n return requestParentResponse<LoginOptions>(LOGIN_OPTIONS_REQUEST);\n}\n\nfunction getWindowAuthProvider(): string {\n return new URLSearchParams(window.location.search).get('authProvider') ?? '';\n}\n\n/**\n * AuthPlugin that tries to delegate to the parent window for authentication. Fails if there is no parent window.\n */\nfunction Component({ children }: AuthPluginProps): JSX.Element {\n return (\n <AuthPluginBase getLoginOptions={getLoginOptions}>\n <UserPermissionsOverrideContext.Provider value={permissionsOverrides}>\n {children}\n </UserPermissionsOverrideContext.Provider>\n </AuthPluginBase>\n );\n}\n\nconst AuthPluginParent: AuthPlugin = {\n Component,\n isAvailable: () =>\n window.opener != null && getWindowAuthProvider() === 'parent',\n};\n\nexport default AuthPluginParent;\n"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AAEzB,SACEC,qBAAqB,EACrBC,qBAAqB,QAChB,wBAAwB;AAC/B,OAAOC,GAAG,MAAM,gBAAgB;AAAC,OAE1BC,cAAc;AAAA,SAGnBC,8BAA8B;AAGhC,IAAMC,GAAG,GAAGH,GAAG,CAACI,MAAM,CAAC,kBAAkB,CAAC;AAE1C,IAAMC,oBAA6C,GAAG;EAAEC,SAAS,EAAE;AAAM,CAAC;AAE1E,SAASC,eAAe,GAA0B;EAChDJ,GAAG,CAACK,IAAI,CAAC,8CAA8C,CAAC;EACxD,OAAOT,qBAAqB,CAAeD,qBAAqB,CAAC;AACnE;AAEA,SAASW,qBAAqB,GAAW;EAAA;EACvC,+BAAO,IAAIC,eAAe,CAACC,MAAM,CAACC,QAAQ,CAACC,MAAM,CAAC,CAACC,GAAG,CAAC,cAAc,CAAC,uEAAI,EAAE;AAC9E;;AAEA;AACA;AACA;AACA,SAASC,SAAS,OAA6C;EAAA,IAA5C;IAAEC;EAA0B,CAAC;EAC9C,oBACE,oBAAC,cAAc;IAAC,eAAe,EAAET;EAAgB,gBAC/C,oBAAC,8BAA8B,CAAC,QAAQ;IAAC,KAAK,EAAEF;EAAqB,GAClEW,QAAQ,CAC+B,CAC3B;AAErB;AAEA,IAAMC,gBAA4B,GAAG;EACnCF,SAAS;EACTG,WAAW,EAAE,MACXP,MAAM,CAACQ,MAAM,IAAI,IAAI,IAAIV,qBAAqB,EAAE,KAAK;AACzD,CAAC;AAED,eAAeQ,gBAAgB"}
@@ -1 +1 @@
1
- {"version":3,"file":"AuthPluginPsk.d.ts","sourceRoot":"","sources":["../src/AuthPluginPsk.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAmB,MAAM,cAAc,CAAC;AA+D3D,QAAA,MAAM,aAAa,EAAE,UAGpB,CAAC;AAEF,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"AuthPluginPsk.d.ts","sourceRoot":"","sources":["../src/AuthPluginPsk.tsx"],"names":[],"mappings":"AAOA,OAAO,EAAE,UAAU,EAAmB,MAAM,cAAc,CAAC;AA8M3D,QAAA,MAAM,aAAa,EAAE,UAGpB,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -1,13 +1,46 @@
1
1
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
2
2
  function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
3
- import React, { useEffect, useState } from 'react';
3
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
4
+ import { CSSTransition } from 'react-transition-group';
5
+ import { LoadingOverlay, ThemeExport } from '@deephaven/components';
6
+ import { useClient } from '@deephaven/jsapi-bootstrap';
7
+ import { useBroadcastLoginListener } from '@deephaven/jsapi-components';
4
8
  import Log from '@deephaven/log';
5
- import { LoadingOverlay } from '@deephaven/components';
6
- var log = Log.module('AuthPluginPsk');
9
+ import Cookies from 'js-cookie';
10
+ import LoginForm from "./LoginForm.js";
11
+ import Login from "./Login.js";
7
12
  var AUTH_TYPE = 'io.deephaven.authentication.psk.PskAuthenticationHandler';
13
+ var PSK_QUERY_PARAM_KEY = 'psk';
14
+ var PSK_TOKEN_KEY = 'io.deephaven.web.client.auth.psk.token';
15
+ var log = Log.module('AuthPluginPsk');
8
16
  function getWindowToken() {
9
- var _URLSearchParams$get;
10
- return (_URLSearchParams$get = new URLSearchParams(window.location.search).get('psk')) !== null && _URLSearchParams$get !== void 0 ? _URLSearchParams$get : '';
17
+ return new URLSearchParams(window.location.search).get(PSK_QUERY_PARAM_KEY);
18
+ }
19
+ function clearWindowToken() {
20
+ log.debug2('clearWindowToken');
21
+ var params = new URLSearchParams(window.location.search);
22
+ params.delete(PSK_QUERY_PARAM_KEY);
23
+ var queryString = "".concat(params);
24
+ if (queryString.length > 0) {
25
+ queryString = "?".concat(queryString);
26
+ }
27
+ var newPath = "".concat(window.location.pathname).concat(queryString).concat(window.location.hash);
28
+ window.history.replaceState(null, '', newPath);
29
+ }
30
+ function readCookieToken() {
31
+ var _Cookies$get;
32
+ return (_Cookies$get = Cookies.get(PSK_TOKEN_KEY)) !== null && _Cookies$get !== void 0 ? _Cookies$get : null;
33
+ }
34
+ function storeCookieToken(token) {
35
+ log.debug2('Storing token in cookie', token);
36
+ if (token != null) {
37
+ Cookies.set(PSK_TOKEN_KEY, token, {
38
+ secure: true,
39
+ sameSite: 'strict'
40
+ });
41
+ } else {
42
+ Cookies.remove(PSK_TOKEN_KEY);
43
+ }
11
44
  }
12
45
 
13
46
  /**
@@ -16,57 +49,156 @@ function getWindowToken() {
16
49
  */
17
50
  function Component(_ref) {
18
51
  var {
19
- client,
20
- onSuccess,
21
- onFailure
52
+ children
22
53
  } = _ref;
54
+ var client = useClient();
55
+ var inputField = useRef(null);
56
+ var loginPromise = useRef(null);
23
57
  var [error, setError] = useState();
24
- var [token] = useState(() => getWindowToken());
58
+ var [isInputRequired, setIsInputRequired] = useState(false);
59
+ var [isLoggedIn, setIsLoggedIn] = useState(false);
60
+ var [isLoggingIn, setIsLoggingIn] = useState(false);
61
+ var [token, setToken] = useState('');
62
+ var login = useCallback(
63
+ /*#__PURE__*/
64
+ // eslint-disable-next-line @typescript-eslint/no-inferrable-types
65
+ function () {
66
+ var _ref2 = _asyncToGenerator(function* (loginToken) {
67
+ var showError = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
68
+ log.info('Logging in...');
69
+ setIsLoggingIn(true);
70
+ var newLoginPromise = null;
71
+ try {
72
+ newLoginPromise = client.login({
73
+ type: AUTH_TYPE,
74
+ token: loginToken
75
+ });
76
+ loginPromise.current = newLoginPromise;
77
+ yield newLoginPromise;
78
+ log.info('Logged in successfully');
79
+ if (loginPromise.current !== newLoginPromise) {
80
+ return;
81
+ }
82
+ storeCookieToken(loginToken);
83
+ setIsLoggedIn(true);
84
+ } catch (e) {
85
+ if (loginPromise.current !== newLoginPromise) {
86
+ return;
87
+ }
88
+ setIsInputRequired(true);
89
+ if (showError) {
90
+ var _detail;
91
+ setError((_detail = e === null || e === void 0 ? void 0 : e.detail) !== null && _detail !== void 0 ? _detail : 'Unable to login: Verify credentials.');
92
+ }
93
+ }
94
+ setIsLoggingIn(false);
95
+ });
96
+ return function (_x) {
97
+ return _ref2.apply(this, arguments);
98
+ };
99
+ }(), [client]);
100
+ var cancelLogin = useCallback(() => {
101
+ loginPromise.current = null;
102
+ setIsLoggingIn(false);
103
+ }, []);
104
+ var onLogin = useCallback( /*#__PURE__*/_asyncToGenerator(function* () {
105
+ log.debug('onLogin');
106
+
107
+ // User logged in successfully in another tab, we should be able to read the token from the cookie and login
108
+ var newToken = readCookieToken();
109
+ if (isLoggedIn || isLoggingIn || newToken == null) {
110
+ return;
111
+ }
112
+ login(newToken, false);
113
+ }), [isLoggedIn, isLoggingIn, login]);
114
+ var onLogout = useCallback(() => {
115
+ storeCookieToken(null);
116
+ }, []);
117
+ useBroadcastLoginListener(onLogin, onLogout);
25
118
  useEffect(() => {
26
119
  var isCanceled = false;
27
- function login() {
28
- return _login.apply(this, arguments);
120
+ function initialLogin() {
121
+ return _initialLogin.apply(this, arguments);
29
122
  }
30
- function _login() {
31
- _login = _asyncToGenerator(function* () {
123
+ function _initialLogin() {
124
+ _initialLogin = _asyncToGenerator(function* () {
125
+ var _getWindowToken;
126
+ var initialToken = (_getWindowToken = getWindowToken()) !== null && _getWindowToken !== void 0 ? _getWindowToken : readCookieToken();
127
+ clearWindowToken();
128
+ if (initialToken == null) {
129
+ setIsInputRequired(true);
130
+ return;
131
+ }
132
+ setIsLoggingIn(true);
32
133
  try {
33
- if (!token) {
34
- throw new Error('No Pre-shared key token found. Add `psk=<token>` parameter to your URL');
35
- }
36
- log.info('Logging in with found token...');
37
134
  yield client.login({
38
135
  type: AUTH_TYPE,
39
- token
136
+ token: initialToken
40
137
  });
41
- if (isCanceled) {
42
- log.info('Previous login result canceled');
43
- return;
138
+ if (!isCanceled) {
139
+ storeCookieToken(initialToken);
140
+ setIsLoggedIn(true);
141
+ setIsLoggingIn(false);
44
142
  }
45
- log.info('Logged in successfully.');
46
- onSuccess();
47
143
  } catch (e) {
48
- if (isCanceled) {
49
- log.info('Previous login failure canceled');
50
- return;
144
+ if (!isCanceled) {
145
+ setIsInputRequired(true);
146
+ setIsLoggingIn(false);
51
147
  }
52
- log.error('Unable to login:', e);
53
- setError(e);
54
- onFailure(e);
55
148
  }
56
149
  });
57
- return _login.apply(this, arguments);
150
+ return _initialLogin.apply(this, arguments);
58
151
  }
59
- login();
152
+ initialLogin();
60
153
  return () => {
61
154
  isCanceled = true;
62
155
  };
63
- }, [client, onFailure, onSuccess, token]);
64
- return /*#__PURE__*/React.createElement(LoadingOverlay, {
156
+ }, [client]);
157
+ var handleSubmit = useCallback(() => {
158
+ if (!isLoggingIn) {
159
+ login(token);
160
+ } else {
161
+ cancelLogin();
162
+ }
163
+ }, [cancelLogin, isLoggingIn, login, token]);
164
+ useEffect(function autoFocusInput() {
165
+ var _inputField$current;
166
+ (_inputField$current = inputField.current) === null || _inputField$current === void 0 ? void 0 : _inputField$current.focus();
167
+ }, [inputField, isInputRequired]);
168
+ return /*#__PURE__*/React.createElement(React.Fragment, null, isLoggedIn && children, isInputRequired && /*#__PURE__*/React.createElement(CSSTransition, {
169
+ in: !isLoggedIn,
170
+ timeout: ThemeExport.transitionMs,
171
+ classNames: "fade",
172
+ mountOnEnter: true,
173
+ unmountOnExit: true
174
+ }, /*#__PURE__*/React.createElement(Login, null, /*#__PURE__*/React.createElement(LoginForm, {
175
+ errorMessage: error != null ? "".concat(error) : undefined,
176
+ isLoggingIn: isLoggingIn,
177
+ onSubmit: handleSubmit
178
+ }, /*#__PURE__*/React.createElement("div", {
179
+ className: "form-group"
180
+ }, /*#__PURE__*/React.createElement("label", {
181
+ htmlFor: "auth-psk-token-input"
182
+ }, "Token"), /*#__PURE__*/React.createElement("input", {
183
+ id: "auth-psk-token-input",
184
+ name: "token",
185
+ className: "input-token form-control",
186
+ type: "text",
187
+ autoComplete: "username",
188
+ autoCapitalize: "none",
189
+ autoCorrect: "off",
190
+ spellCheck: "false",
191
+ ref: inputField,
192
+ value: token,
193
+ onChange: event => {
194
+ setError(undefined);
195
+ setToken(event.target.value);
196
+ }
197
+ }))))), /*#__PURE__*/React.createElement(LoadingOverlay, {
65
198
  "data-testid": "auth-psk-loading",
66
- isLoading: true,
67
- isLoaded: false,
68
- errorMessage: error != null ? "".concat(error) : null
69
- });
199
+ isLoaded: isLoggedIn || isInputRequired,
200
+ isLoading: !isLoggedIn && !isInputRequired
201
+ }));
70
202
  }
71
203
  var AuthPluginPsk = {
72
204
  Component,
@@ -1 +1 @@
1
- {"version":3,"file":"AuthPluginPsk.js","names":["React","useEffect","useState","Log","LoadingOverlay","log","module","AUTH_TYPE","getWindowToken","URLSearchParams","window","location","search","get","Component","client","onSuccess","onFailure","error","setError","token","isCanceled","login","Error","info","type","e","AuthPluginPsk","isAvailable","authHandlers","includes"],"sources":["../src/AuthPluginPsk.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react';\nimport Log from '@deephaven/log';\nimport { LoadingOverlay } from '@deephaven/components';\nimport { AuthPlugin, AuthPluginProps } from './AuthPlugin';\n\nconst log = Log.module('AuthPluginPsk');\n\nconst AUTH_TYPE = 'io.deephaven.authentication.psk.PskAuthenticationHandler';\n\nfunction getWindowToken(): string {\n return new URLSearchParams(window.location.search).get('psk') ?? '';\n}\n\n/**\n * AuthPlugin that tries to login using a pre-shared key.\n * Add the `psk=<token>` parameter to your URL string to set the token.\n */\nfunction Component({\n client,\n onSuccess,\n onFailure,\n}: AuthPluginProps): JSX.Element {\n const [error, setError] = useState<unknown>();\n const [token] = useState(() => getWindowToken());\n useEffect(() => {\n let isCanceled = false;\n async function login() {\n try {\n if (!token) {\n throw new Error(\n 'No Pre-shared key token found. Add `psk=<token>` parameter to your URL'\n );\n }\n log.info('Logging in with found token...');\n await client.login({ type: AUTH_TYPE, token });\n if (isCanceled) {\n log.info('Previous login result canceled');\n return;\n }\n log.info('Logged in successfully.');\n onSuccess();\n } catch (e) {\n if (isCanceled) {\n log.info('Previous login failure canceled');\n return;\n }\n log.error('Unable to login:', e);\n setError(e);\n onFailure(e);\n }\n }\n login();\n return () => {\n isCanceled = true;\n };\n }, [client, onFailure, onSuccess, token]);\n return (\n <LoadingOverlay\n data-testid=\"auth-psk-loading\"\n isLoading\n isLoaded={false}\n errorMessage={error != null ? `${error}` : null}\n />\n );\n}\n\nconst AuthPluginPsk: AuthPlugin = {\n Component,\n isAvailable: authHandlers => authHandlers.includes(AUTH_TYPE),\n};\n\nexport default AuthPluginPsk;\n"],"mappings":";;AAAA,OAAOA,KAAK,IAAIC,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AAClD,OAAOC,GAAG,MAAM,gBAAgB;AAChC,SAASC,cAAc,QAAQ,uBAAuB;AAGtD,IAAMC,GAAG,GAAGF,GAAG,CAACG,MAAM,CAAC,eAAe,CAAC;AAEvC,IAAMC,SAAS,GAAG,0DAA0D;AAE5E,SAASC,cAAc,GAAW;EAAA;EAChC,+BAAO,IAAIC,eAAe,CAACC,MAAM,CAACC,QAAQ,CAACC,MAAM,CAAC,CAACC,GAAG,CAAC,KAAK,CAAC,uEAAI,EAAE;AACrE;;AAEA;AACA;AACA;AACA;AACA,SAASC,SAAS,OAIe;EAAA,IAJd;IACjBC,MAAM;IACNC,SAAS;IACTC;EACe,CAAC;EAChB,IAAM,CAACC,KAAK,EAAEC,QAAQ,CAAC,GAAGjB,QAAQ,EAAW;EAC7C,IAAM,CAACkB,KAAK,CAAC,GAAGlB,QAAQ,CAAC,MAAMM,cAAc,EAAE,CAAC;EAChDP,SAAS,CAAC,MAAM;IACd,IAAIoB,UAAU,GAAG,KAAK;IAAC,SACRC,KAAK;MAAA;IAAA;IAAA;MAAA,2BAApB,aAAuB;QACrB,IAAI;UACF,IAAI,CAACF,KAAK,EAAE;YACV,MAAM,IAAIG,KAAK,CACb,wEAAwE,CACzE;UACH;UACAlB,GAAG,CAACmB,IAAI,CAAC,gCAAgC,CAAC;UAC1C,MAAMT,MAAM,CAACO,KAAK,CAAC;YAAEG,IAAI,EAAElB,SAAS;YAAEa;UAAM,CAAC,CAAC;UAC9C,IAAIC,UAAU,EAAE;YACdhB,GAAG,CAACmB,IAAI,CAAC,gCAAgC,CAAC;YAC1C;UACF;UACAnB,GAAG,CAACmB,IAAI,CAAC,yBAAyB,CAAC;UACnCR,SAAS,EAAE;QACb,CAAC,CAAC,OAAOU,CAAC,EAAE;UACV,IAAIL,UAAU,EAAE;YACdhB,GAAG,CAACmB,IAAI,CAAC,iCAAiC,CAAC;YAC3C;UACF;UACAnB,GAAG,CAACa,KAAK,CAAC,kBAAkB,EAAEQ,CAAC,CAAC;UAChCP,QAAQ,CAACO,CAAC,CAAC;UACXT,SAAS,CAACS,CAAC,CAAC;QACd;MACF,CAAC;MAAA;IAAA;IACDJ,KAAK,EAAE;IACP,OAAO,MAAM;MACXD,UAAU,GAAG,IAAI;IACnB,CAAC;EACH,CAAC,EAAE,CAACN,MAAM,EAAEE,SAAS,EAAED,SAAS,EAAEI,KAAK,CAAC,CAAC;EACzC,oBACE,oBAAC,cAAc;IACb,eAAY,kBAAkB;IAC9B,SAAS;IACT,QAAQ,EAAE,KAAM;IAChB,YAAY,EAAEF,KAAK,IAAI,IAAI,aAAMA,KAAK,IAAK;EAAK,EAChD;AAEN;AAEA,IAAMS,aAAyB,GAAG;EAChCb,SAAS;EACTc,WAAW,EAAEC,YAAY,IAAIA,YAAY,CAACC,QAAQ,CAACvB,SAAS;AAC9D,CAAC;AAED,eAAeoB,aAAa"}
1
+ {"version":3,"file":"AuthPluginPsk.js","names":["React","useCallback","useEffect","useRef","useState","CSSTransition","LoadingOverlay","ThemeExport","useClient","useBroadcastLoginListener","Log","Cookies","LoginForm","Login","AUTH_TYPE","PSK_QUERY_PARAM_KEY","PSK_TOKEN_KEY","log","module","getWindowToken","URLSearchParams","window","location","search","get","clearWindowToken","debug2","params","delete","queryString","length","newPath","pathname","hash","history","replaceState","readCookieToken","storeCookieToken","token","set","secure","sameSite","remove","Component","children","client","inputField","loginPromise","error","setError","isInputRequired","setIsInputRequired","isLoggedIn","setIsLoggedIn","isLoggingIn","setIsLoggingIn","setToken","login","loginToken","showError","info","newLoginPromise","type","current","e","detail","cancelLogin","onLogin","debug","newToken","onLogout","isCanceled","initialLogin","initialToken","handleSubmit","autoFocusInput","focus","transitionMs","undefined","event","target","value","AuthPluginPsk","isAvailable","authHandlers","includes"],"sources":["../src/AuthPluginPsk.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { CSSTransition } from 'react-transition-group';\nimport { LoadingOverlay, ThemeExport } from '@deephaven/components';\nimport { useClient } from '@deephaven/jsapi-bootstrap';\nimport { useBroadcastLoginListener } from '@deephaven/jsapi-components';\nimport Log from '@deephaven/log';\nimport Cookies from 'js-cookie';\nimport { AuthPlugin, AuthPluginProps } from './AuthPlugin';\nimport LoginForm from './LoginForm';\nimport Login from './Login';\n\nconst AUTH_TYPE = 'io.deephaven.authentication.psk.PskAuthenticationHandler';\n\nconst PSK_QUERY_PARAM_KEY = 'psk';\n\nconst PSK_TOKEN_KEY = 'io.deephaven.web.client.auth.psk.token';\n\nconst log = Log.module('AuthPluginPsk');\n\nfunction getWindowToken(): string | null {\n return new URLSearchParams(window.location.search).get(PSK_QUERY_PARAM_KEY);\n}\n\nfunction clearWindowToken() {\n log.debug2('clearWindowToken');\n const params = new URLSearchParams(window.location.search);\n params.delete(PSK_QUERY_PARAM_KEY);\n\n let queryString = `${params}`;\n if (queryString.length > 0) {\n queryString = `?${queryString}`;\n }\n const newPath = `${window.location.pathname}${queryString}${window.location.hash}`;\n window.history.replaceState(null, '', newPath);\n}\n\nfunction readCookieToken(): string | null {\n return Cookies.get(PSK_TOKEN_KEY) ?? null;\n}\n\nfunction storeCookieToken(token: string | null): void {\n log.debug2('Storing token in cookie', token);\n if (token != null) {\n Cookies.set(PSK_TOKEN_KEY, token, { secure: true, sameSite: 'strict' });\n } else {\n Cookies.remove(PSK_TOKEN_KEY);\n }\n}\n\n/**\n * AuthPlugin that tries to login using a pre-shared key.\n * Add the `psk=<token>` parameter to your URL string to set the token.\n */\nfunction Component({ children }: AuthPluginProps): JSX.Element {\n const client = useClient();\n const inputField = useRef<HTMLInputElement>(null);\n const loginPromise = useRef<Promise<void> | null>(null);\n const [error, setError] = useState<unknown>();\n const [isInputRequired, setIsInputRequired] = useState(false);\n const [isLoggedIn, setIsLoggedIn] = useState(false);\n const [isLoggingIn, setIsLoggingIn] = useState(false);\n const [token, setToken] = useState('');\n\n const login = useCallback(\n // eslint-disable-next-line @typescript-eslint/no-inferrable-types\n async (loginToken: string, showError: boolean = true) => {\n log.info('Logging in...');\n setIsLoggingIn(true);\n let newLoginPromise: Promise<void> | null = null;\n try {\n newLoginPromise = client.login({ type: AUTH_TYPE, token: loginToken });\n loginPromise.current = newLoginPromise;\n await newLoginPromise;\n\n log.info('Logged in successfully');\n if (loginPromise.current !== newLoginPromise) {\n return;\n }\n storeCookieToken(loginToken);\n setIsLoggedIn(true);\n } catch (e) {\n if (loginPromise.current !== newLoginPromise) {\n return;\n }\n setIsInputRequired(true);\n if (showError) {\n setError(\n (e as CustomEvent)?.detail ?? 'Unable to login: Verify credentials.'\n );\n }\n }\n setIsLoggingIn(false);\n },\n [client]\n );\n\n const cancelLogin = useCallback(() => {\n loginPromise.current = null;\n setIsLoggingIn(false);\n }, []);\n\n const onLogin = useCallback(async () => {\n log.debug('onLogin');\n\n // User logged in successfully in another tab, we should be able to read the token from the cookie and login\n const newToken = readCookieToken();\n if (isLoggedIn || isLoggingIn || newToken == null) {\n return;\n }\n\n login(newToken, false);\n }, [isLoggedIn, isLoggingIn, login]);\n const onLogout = useCallback(() => {\n storeCookieToken(null);\n }, []);\n useBroadcastLoginListener(onLogin, onLogout);\n\n useEffect(() => {\n let isCanceled = false;\n async function initialLogin() {\n const initialToken = getWindowToken() ?? readCookieToken();\n clearWindowToken();\n\n if (initialToken == null) {\n setIsInputRequired(true);\n return;\n }\n\n setIsLoggingIn(true);\n try {\n await client.login({ type: AUTH_TYPE, token: initialToken });\n if (!isCanceled) {\n storeCookieToken(initialToken);\n setIsLoggedIn(true);\n setIsLoggingIn(false);\n }\n } catch (e) {\n if (!isCanceled) {\n setIsInputRequired(true);\n setIsLoggingIn(false);\n }\n }\n }\n initialLogin();\n return () => {\n isCanceled = true;\n };\n }, [client]);\n\n const handleSubmit = useCallback(() => {\n if (!isLoggingIn) {\n login(token);\n } else {\n cancelLogin();\n }\n }, [cancelLogin, isLoggingIn, login, token]);\n\n useEffect(\n function autoFocusInput() {\n inputField.current?.focus();\n },\n [inputField, isInputRequired]\n );\n\n return (\n <>\n {isLoggedIn && children}\n {isInputRequired && (\n <CSSTransition\n in={!isLoggedIn}\n timeout={ThemeExport.transitionMs}\n classNames=\"fade\"\n mountOnEnter\n unmountOnExit\n >\n <Login>\n <LoginForm\n errorMessage={error != null ? `${error}` : undefined}\n isLoggingIn={isLoggingIn}\n onSubmit={handleSubmit}\n >\n <div className=\"form-group\">\n <label htmlFor=\"auth-psk-token-input\">Token</label>\n <input\n id=\"auth-psk-token-input\"\n name=\"token\"\n className=\"input-token form-control\"\n type=\"text\"\n autoComplete=\"username\"\n autoCapitalize=\"none\"\n autoCorrect=\"off\"\n spellCheck=\"false\"\n ref={inputField}\n value={token}\n onChange={event => {\n setError(undefined);\n setToken(event.target.value);\n }}\n />\n </div>\n </LoginForm>\n </Login>\n </CSSTransition>\n )}\n <LoadingOverlay\n data-testid=\"auth-psk-loading\"\n isLoaded={isLoggedIn || isInputRequired}\n isLoading={!isLoggedIn && !isInputRequired}\n />\n </>\n );\n}\n\nconst AuthPluginPsk: AuthPlugin = {\n Component,\n isAvailable: authHandlers => authHandlers.includes(AUTH_TYPE),\n};\n\nexport default AuthPluginPsk;\n"],"mappings":"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"}
package/dist/Login.css ADDED
@@ -0,0 +1,74 @@
1
+ /* stylelint-disable scss/at-import-no-partial-leading-underscore */
2
+ .login-container {
3
+ position: absolute;
4
+ height: 100%;
5
+ width: 100%;
6
+ top: 0;
7
+ left: 0;
8
+ display: flex;
9
+ align-items: center;
10
+ justify-content: center;
11
+ }
12
+ .login-container .login-box {
13
+ position: relative;
14
+ display: flex;
15
+ width: 605px;
16
+ box-shadow: 0 0.1rem 1rem rgba(26, 23, 26, 0.45);
17
+ opacity: 0;
18
+ animation: 0.3s ease-out 0s 1 forwards animateLoginBox;
19
+ }
20
+ .login-container .login-box .logo {
21
+ background-color: #fcfcfa;
22
+ border-radius: 4px 0 0 4px;
23
+ display: flex;
24
+ justify-content: center;
25
+ align-items: center;
26
+ min-height: 310px;
27
+ min-width: 302.5px;
28
+ pointer-events: none;
29
+ user-select: none;
30
+ }
31
+ .login-container .login-box .logo img {
32
+ max-width: 225px;
33
+ }
34
+ .login-container .login-box .footer {
35
+ padding: 1rem 0;
36
+ position: absolute;
37
+ width: 100%;
38
+ bottom: 0;
39
+ margin: 0;
40
+ transform: translateY(100%);
41
+ text-align: center;
42
+ color: #c0bfbf;
43
+ font-size: 12px;
44
+ }
45
+
46
+ @keyframes animateLoginBox {
47
+ 0% {
48
+ opacity: 0;
49
+ }
50
+ 100% {
51
+ opacity: 1;
52
+ }
53
+ }
54
+ @media (max-width: 767.98px) {
55
+ .login-container .login-box {
56
+ flex-direction: column;
57
+ margin: 3rem;
58
+ }
59
+ .login-container .login-box .logo {
60
+ width: 100%;
61
+ min-height: 165px;
62
+ border-radius: 4px 4px 0 0;
63
+ }
64
+ .login-container .login-box .logo img {
65
+ width: 80%;
66
+ max-width: 350px;
67
+ }
68
+ .login-container .login-box .form {
69
+ max-width: 100%;
70
+ border-radius: 0 0 4px 4px;
71
+ }
72
+ }
73
+
74
+ /*# sourceMappingURL=Login.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sourceRoot":"","sources":["../../../node_modules/@deephaven/components/scss/custom.scss","../src/Login.scss","../../../node_modules/@deephaven/components/scss/bootstrap_overrides.scss","../../../node_modules/bootstrap/scss/mixins/_breakpoints.scss","../../../node_modules/@deephaven/components/scss/new_variables.scss"],"names":[],"mappings":"AAAA;ACQA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA,OAnBc;EAoBd,YCoGS;EDnGT;EACA;;AAEA;EACE,kBCTK;EDUL;EACA;EACA;EACA;EACA,YA7BiB;EA8BjB;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA,OC9BK;ED+BL;;;AAKN;EACE;IACE;;EAEF;IACE;;;AEYA;EFNA;IACE;IACA,QG/DK;;EHgEL;IACE;IACA;IACA;;EACA;IACE;IACA;;EAGJ;IACE;IACA","file":"Login.css","sourcesContent":["/* stylelint-disable scss/at-import-no-partial-leading-underscore */\n// Consumers should be able to resolve bootstrap/ to node_modules/bootstrap\n\n//Make bootstrap functions available for use in overrides\n@import 'bootstrap/scss/_functions.scss';\n@import './bootstrap_overrides.scss';\n\n//_variable imports come after bootstrap default overrides,\n// makes all other variables and mixins from bootstrap available\n/// with just importing customer.scss\n@import 'bootstrap/scss/_variables.scss';\n@import 'bootstrap/scss/_mixins.scss';\n\n//New variables come after imports\n@import './new_variables.scss';\n","@import '@deephaven/components/scss/custom.scss';\n\n$login-box-width: 605px;\n$login-box-min-height: 310px;\n$logo-background-color: $gray-100;\n$footer-color: $gray-300;\n$login-box-animation-scale: 0.8;\n\n.login-container {\n position: absolute;\n height: 100%;\n width: 100%;\n top: 0;\n left: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n\n .login-box {\n position: relative;\n display: flex;\n width: $login-box-width;\n box-shadow: $box-shadow;\n opacity: 0;\n animation: $transition-long ease-out 0s 1 forwards animateLoginBox;\n\n .logo {\n background-color: $logo-background-color;\n border-radius: $border-radius 0 0 $border-radius;\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: $login-box-min-height;\n min-width: $login-box-width * 0.5;\n pointer-events: none;\n user-select: none;\n\n img {\n max-width: 225px;\n }\n }\n\n .footer {\n padding: $spacer-3 0;\n position: absolute;\n width: 100%;\n bottom: 0;\n margin: 0;\n transform: translateY(100%);\n text-align: center;\n color: $footer-color;\n font-size: 12px;\n }\n }\n}\n\n@keyframes animateLoginBox {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n\n@include media-breakpoint-down(sm) {\n .login-container {\n .login-box {\n flex-direction: column;\n margin: $spacer-5;\n .logo {\n width: 100%;\n min-height: 165px;\n border-radius: $border-radius $border-radius 0 0;\n img {\n width: 80%;\n max-width: 350px;\n }\n }\n .form {\n max-width: 100%;\n border-radius: 0 0 $border-radius $border-radius;\n }\n }\n }\n}\n","// Styling overrides for bootstrap\n\n// Override / set color variables\n$red: #f95d84;\n$orange: #f37e3f;\n$yellow: #fcd65b;\n$green: #9edc6f;\n$blue: #76d9e4;\n$purple: #aa9af4;\n\n//Define some UI colors\n$interfacegray: #2d2a2e;\n$interfaceblue: #4878ea;\n$interfacewhite: #f0f0ee; //same as gray-200\n$interfaceblack: #1a171a;\n\n//Define our Gray scale\n$white: $interfacewhite;\n$gray-100: #fcfcfa;\n$gray-200: $interfacewhite;\n$gray-300: #c0bfbf;\n$gray-400: #929192;\n$gray-500: #5b5a5c;\n$gray-600: #555356;\n$gray-700: #403e41;\n$gray-800: #373438;\n$gray-850: #322f33;\n$gray-900: #211f22;\n$black: $interfaceblack;\n$content-bg: $interfacegray;\n$background: $interfaceblack;\n$foreground: $interfacewhite;\n\n//Load colors into map\n$colors: ();\n$colors: map-merge(\n (\n 'red': $red,\n 'orange': $orange,\n 'yellow': $yellow,\n 'green': $green,\n 'blue': $blue,\n 'purple': $purple,\n 'white': $white,\n 'black': $black,\n ),\n $colors\n);\n\n//Set default colors\n$body-bg: $black;\n$body-color: $interfacewhite;\n\n// Set brand colors\n$primary: $interfaceblue;\n$primary-hover: darken($primary, 8%);\n$primary-dark: mix($primary, $content-bg, 25%);\n$primary-light: scale-color($primary, $lightness: -25%);\n$secondary: $gray-500;\n$secondary-hover: darken($secondary, 8%);\n$success: $green;\n$info: $yellow;\n$warning: $orange;\n$danger: $red;\n$danger-hover: darken($danger, 8%);\n$light: $gray-100;\n$mid: $gray-400; //Added a mid color, useful for input styling\n$dark: $gray-800;\n$green-dark: scale-color($green, $lightness: -45%, $saturation: -10%);\n\n$theme-colors: () !default;\n$theme-colors: map-merge(\n (\n 'primary': $primary,\n 'primary-hover': $primary-hover,\n 'primary-light': $primary-light,\n 'primary-dark': $primary-dark,\n 'secondary': $secondary,\n 'success': $success,\n 'info': $info,\n 'warning': $warning,\n 'danger': $danger,\n 'light': $light,\n 'dark': $dark,\n 'mid': $mid,\n 'content-bg': $interfacegray,\n 'background': $interfaceblack,\n 'foreground': $interfacewhite,\n ),\n $theme-colors\n);\n\n$component-active-bg: $primary;\n$theme-color-interval: 9%;\n$yiq-contrasted-threshold: 180;\n\n// Override fonts\n$font-family-sans-serif: 'Fira Sans', -apple-system, blinkmacsystemfont,\n 'Segoe UI', 'Roboto', 'Helvetica Neue', arial, sans-serif; //fira sans then native system ui fallbacks\n$font-family-monospace: 'Fira Mono', menlo, monaco, consolas, 'Liberation Mono',\n 'Courier New', monospace;\n$font-family-base: $font-family-sans-serif;\n\n$headings-font-weight: 400;\n\n//Text overides\n$text-muted: $gray-400;\n\n//Style Selection highlight color\n//so browsers add alpha to your color by default, ignoring opacity 1\n//by setting rgba with 0.99 it tricks browser into thinking there is alpha applied\n$text-select-color: $primary-hover;\n$text-select-color-editor: lighten(\n $gray-700,\n 15%\n); //we lighten it abit to account for that 0.01 loss, and because it needs some anyways.\n\n//Grid variables, same value as default just making easily accessible\n$grid-gutter-width: 30px;\n\n//Visual Overrides\n$border-radius: 4px;\n$box-shadow: 0 0.1rem 1rem rgba($black, 45%); //because our UI is so dark, we need darker default shadows\n$box-shadow-900: 0 0.1rem 1rem rgba(0, 0, 0, 45%); //darkest shadow for $black popups over $black UI\n\n//Override Btn\n$btn-border-radius: 4rem;\n$btn-padding-x: 1.5rem;\n$btn-transition: color 0.12s ease-in-out, background-color 0.12s ease-in-out,\n border-color 0.12s ease-in-out, box-shadow 0.12s ease-in-out; //default 0.15 is too long\n$btn-border-width: 2px;\n\n//Override Inputs\n$input-bg: $gray-600;\n$input-disabled-bg: $gray-800;\n$input-color: $foreground;\n$input-border-color: $gray-400;\n$input-placeholder-color: $gray-400;\n$input-focus-border-color: rgba($primary, 85%);\n\n$input-btn-focus-width: 0.2rem;\n$input-btn-focus-color: rgba($component-active-bg, 35%);\n$input-btn-focus-box-shadow: 0 0 0 $input-btn-focus-width $input-btn-focus-color;\n\n//checkbox\n$custom-control-indicator-bg: $gray-600;\n$custom-control-indicator-bg-size: 75% 75%;\n$custom-control-indicator-disabled-bg: $gray-800;\n$custom-control-indicator-checked-disabled-bg: $gray-800;\n$custom-control-label-disabled-color: $gray-400;\n\n//Custom Select\n$custom-select-indicator-color: $gray-400;\n$custom-select-bg-size: 16px 16px;\n//dhSort icon encoded\n$custom-select-indicator: str-replace(\n url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='#{$custom-select-indicator-color}' d='M4 7l-.4-.8 4-3.7h.8l4 3.7-.4.8H4zm0 2l-.4.8 4 3.7h.8l4-3.7L12 9H4z'/%3E%3C/svg%3E\"),\n '#',\n '%23'\n);\n$custom-select-focus-box-shadow: $input-btn-focus-box-shadow;\n$custom-select-disabled-color: darken($gray-400, 5%);\n$custom-select-disabled-bg: $gray-800;\n\n//modal\n$modal-content-bg: $gray-200;\n$modal-content-border-width: 0;\n$modal-md: 550px;\n\n// Toast notification\n$toast-bg: $primary-dark;\n$toast-color: $foreground;\n$toast-error-bg: mix($danger, $content-bg, 15%);\n$toast-error-color: $foreground;\n\n//tooltips\n$tooltip-bg: $gray-700;\n$tooltip-color: $foreground;\n$tooltip-box-shadow: 0 0.1rem 1.5rem 0.1rem rgba($black, 80%);\n\n//drowdowns\n$dropdown-bg: $gray-600;\n$dropdown-link-color: $foreground;\n$dropdown-link-hover-color: $foreground;\n$dropdown-link-hover-bg: $primary;\n$dropdown-divider-bg: $gray-700;\n\n//context menus\n$contextmenu-bg: $gray-600;\n$contextmenu-color: $foreground;\n$contextmenu-disabled-color: $text-muted;\n$contextmenu-keyboard-selected-bg: rgba($primary, 50%);\n$contextmenu-selected-bg: $primary;\n$contextmenu-selected-color: $foreground;\n\n//links\n$link-color: $gray-400;\n$link-hover-color: $foreground;\n\n//progress-bar\n$progress-bg: $gray-600;\n$progress-border-radius: 1rem;\n\n// Set global options\n$enable-shadows: false;\n$enable-gradients: false;\n$enable-print-styles: false; //I don't think anyone should expect to \"print\" this app.\n\n// Transition times\n$transition: 0.15s;\n$transition-mid: 0.2s;\n$transition-long: 0.3s;\n$transition-slow: 0.6s;\n\n//form-validation icon, uses vsWarning icon encoded here as svg\n$form-feedback-icon-invalid-color: theme-color('danger');\n$form-feedback-icon-invalid: str-replace(\n url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cg fill='none'%3E%3Cg fill='#{$form-feedback-icon-invalid-color}'%3E%3Cpath d='M7.56 1h.88l6.54 12.26-.44.74H1.44L1 13.26 7.56 1zM8 2.28 2.28 13H13.7L8 2.28zM8.625 12v-1h-1.25v1h1.25zm-1.25-2V6h1.25v4h-1.25z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E \"),\n '#',\n '%23'\n);\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n// >> breakpoint-next(sm)\n// md\n// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// md\n// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))\n// md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n $n: index($breakpoint-names, $name);\n @return if($n != null and $n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n $min: map-get($breakpoints, $name);\n @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width. Null for the largest (last) breakpoint.\n// The maximum value is calculated as the minimum of the next one less 0.02px\n// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n $next: breakpoint-next($name, $breakpoints);\n @return if($next, breakpoint-min($next, $breakpoints) - .02, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"\" (Returns a blank string)\n// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n @if $min {\n @media (min-width: $min) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n $max: breakpoint-max($name, $breakpoints);\n @if $max {\n @media (max-width: $max) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($lower, $breakpoints);\n $max: breakpoint-max($upper, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($lower, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($upper, $breakpoints) {\n @content;\n }\n }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n $max: breakpoint-max($name, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($name, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($name, $breakpoints) {\n @content;\n }\n }\n}\n","//Set of spacer variables from the spacer map\n$spacer-0: map-get($spacers, 0); //0\n$spacer-1: map-get($spacers, 1);\n$spacer-2: map-get($spacers, 2);\n$spacer-3: map-get($spacers, 3);\n$spacer-4: map-get($spacers, 4);\n$spacer-5: map-get($spacers, 5);\n\n//Marching Ants for golden layout dropzone and drag and drop\n//top bottom, left right.\n//create 4 background images that are 50% color 1, 50% color 2 using graidents, two veritical, two horizontal\n//size them to ant-size and thickness\n//position those images along the egdes and make top/bottom repeat-x and left/right repeat-y\n//then offest each of those background positions by ant-size in animation to make them march.\n$ant-size: 8px;\n$ant-thickness: 1px;\n\n@mixin ants-base($color-1: black, $color-2: white) {\n background-image: linear-gradient(to right, $color-2 50%, $color-1 50%),\n linear-gradient(to right, $color-2 50%, $color-1 50%),\n linear-gradient(to bottom, $color-2 50%, $color-1 50%),\n linear-gradient(to bottom, $color-2 50%, $color-1 50%);\n background-size: $ant-size $ant-thickness, $ant-size $ant-thickness,\n $ant-thickness $ant-size, $ant-thickness $ant-size;\n background-position: 0 top, 0 bottom, left 0, right 0;\n background-repeat: repeat-x, repeat-x, repeat-y, repeat-y;\n animation: march 0.5s;\n animation-timing-function: linear;\n animation-iteration-count: infinite;\n}\n\n@mixin drag-stack($pseudo-element) {\n &::#{$pseudo-element} {\n content: ' ';\n background: $primary;\n box-shadow: $box-shadow;\n border-radius: $border-radius;\n position: absolute;\n height: 100%;\n width: 100%;\n @content;\n }\n}\n\n$focus-bg-transparency: 0.12;\n$hover-bg-transparency: 0.14;\n$active-bg-transparency: 0.28;\n$exception-transparency: 0.13;\n"]}
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import './Login.scss';
3
+ interface LoginProps {
4
+ /** What to show in the login input part of the login form. */
5
+ children: React.ReactNode;
6
+ }
7
+ export declare function Login({ children }: LoginProps): JSX.Element;
8
+ export default Login;
9
+ //# sourceMappingURL=Login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Login.d.ts","sourceRoot":"","sources":["../src/Login.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,cAAc,CAAC;AAEtB,UAAU,UAAU;IAClB,8DAA8D;IAC9D,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,KAAK,CAAC,EAAE,QAAQ,EAAE,EAAE,UAAU,eAgB7C;AAED,eAAe,KAAK,CAAC"}
package/dist/Login.js ADDED
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import { RandomAreaPlotAnimation } from '@deephaven/components';
3
+ import "./Login.css";
4
+ export function Login(_ref) {
5
+ var {
6
+ children
7
+ } = _ref;
8
+ return /*#__PURE__*/React.createElement("div", {
9
+ className: "login-container"
10
+ }, /*#__PURE__*/React.createElement(RandomAreaPlotAnimation, null), /*#__PURE__*/React.createElement("div", {
11
+ className: "login-box"
12
+ }, /*#__PURE__*/React.createElement("div", {
13
+ className: "logo"
14
+ }, /*#__PURE__*/React.createElement("img", {
15
+ src: "/logo",
16
+ alt: "Deephaven Data Labs"
17
+ })), children, /*#__PURE__*/React.createElement("p", {
18
+ className: "footer"
19
+ }, "\xA9 2016-", new Date().getFullYear(), " Deephaven Data Labs LLC. Patent Pending.")));
20
+ }
21
+ export default Login;
22
+ //# sourceMappingURL=Login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Login.js","names":["React","RandomAreaPlotAnimation","Login","children","Date","getFullYear"],"sources":["../src/Login.tsx"],"sourcesContent":["import React from 'react';\nimport { RandomAreaPlotAnimation } from '@deephaven/components';\nimport './Login.scss';\n\ninterface LoginProps {\n /** What to show in the login input part of the login form. */\n children: React.ReactNode;\n}\n\nexport function Login({ children }: LoginProps) {\n return (\n <div className=\"login-container\">\n <RandomAreaPlotAnimation />\n <div className=\"login-box\">\n <div className=\"logo\">\n <img src=\"/logo\" alt=\"Deephaven Data Labs\" />\n </div>\n {children}\n <p className=\"footer\">\n © 2016-{new Date().getFullYear()} Deephaven Data Labs LLC. Patent\n Pending.\n </p>\n </div>\n </div>\n );\n}\n\nexport default Login;\n"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,uBAAuB,QAAQ,uBAAuB;AAAC;AAQhE,OAAO,SAASC,KAAK,OAA2B;EAAA,IAA1B;IAAEC;EAAqB,CAAC;EAC5C,oBACE;IAAK,SAAS,EAAC;EAAiB,gBAC9B,oBAAC,uBAAuB,OAAG,eAC3B;IAAK,SAAS,EAAC;EAAW,gBACxB;IAAK,SAAS,EAAC;EAAM,gBACnB;IAAK,GAAG,EAAC,OAAO;IAAC,GAAG,EAAC;EAAqB,EAAG,CACzC,EACLA,QAAQ,eACT;IAAG,SAAS,EAAC;EAAQ,GAAC,YACb,EAAC,IAAIC,IAAI,EAAE,CAACC,WAAW,EAAE,EAAC,2CAEnC,CAAI,CACA,CACF;AAEV;AAEA,eAAeH,KAAK"}
@@ -0,0 +1,57 @@
1
+ /* stylelint-disable scss/at-import-no-partial-leading-underscore */
2
+ .login-form {
3
+ max-width: 302.5px;
4
+ min-height: 310px;
5
+ background: #403e41;
6
+ border-radius: 0 4px 4px 0;
7
+ display: flex;
8
+ flex-grow: 1;
9
+ flex-direction: column;
10
+ align-items: center;
11
+ justify-content: space-between;
12
+ padding: 1rem 0;
13
+ }
14
+ .login-form fieldset {
15
+ padding: 0;
16
+ margin: 0;
17
+ }
18
+ .login-form .flex-wrapper {
19
+ width: 85%;
20
+ }
21
+ .login-form .flex-spacer {
22
+ display: flex;
23
+ justify-content: center;
24
+ align-items: center;
25
+ flex-grow: 1;
26
+ width: 85%;
27
+ }
28
+ .login-form .flex-spacer:empty {
29
+ content: "";
30
+ }
31
+ .login-form .status-message {
32
+ color: #929192;
33
+ }
34
+ .login-form .error-message {
35
+ color: #f95d84;
36
+ width: 100%;
37
+ word-break: break-word;
38
+ margin-top: 0.25rem;
39
+ margin-bottom: 0.25rem;
40
+ }
41
+ .login-form .btn-primary {
42
+ min-width: 118px;
43
+ }
44
+ @keyframes fade-in {
45
+ from {
46
+ opacity: 0;
47
+ }
48
+ to {
49
+ opacity: 1;
50
+ }
51
+ }
52
+ .login-form .is-initializing {
53
+ opacity: 0;
54
+ animation: fade-in 0.15s 1s forwards;
55
+ }
56
+
57
+ /*# sourceMappingURL=LoginForm.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sourceRoot":"","sources":["../../../node_modules/@deephaven/components/scss/custom.scss","../src/LoginForm.scss","../../../node_modules/@deephaven/components/scss/bootstrap_overrides.scss","../../../node_modules/@deephaven/components/scss/new_variables.scss"],"names":[],"mappings":"AAAA;ACKA;EACE;EACA,YAJqB;EAKrB,YCgBS;EDfT;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE,OClBO;;ADqBT;EACE,OCxCE;EDyCF;EACA;EACA,YE5CO;EF6CP,eE7CO;;AFgDT;EACE;;AAGF;EACE;IACE;;EAEF;IACE;;;AAIJ;EACE;EACA","file":"LoginForm.css","sourcesContent":["/* stylelint-disable scss/at-import-no-partial-leading-underscore */\n// Consumers should be able to resolve bootstrap/ to node_modules/bootstrap\n\n//Make bootstrap functions available for use in overrides\n@import 'bootstrap/scss/_functions.scss';\n@import './bootstrap_overrides.scss';\n\n//_variable imports come after bootstrap default overrides,\n// makes all other variables and mixins from bootstrap available\n/// with just importing customer.scss\n@import 'bootstrap/scss/_variables.scss';\n@import 'bootstrap/scss/_mixins.scss';\n\n//New variables come after imports\n@import './new_variables.scss';\n","@import '@deephaven/components/scss/custom.scss';\n\n$login-box-width: 605px;\n$login-box-min-height: 310px;\n\n.login-form {\n max-width: $login-box-width * 0.5;\n min-height: $login-box-min-height;\n background: $gray-700;\n border-radius: 0 $border-radius $border-radius 0;\n display: flex;\n flex-grow: 1;\n flex-direction: column;\n align-items: center;\n justify-content: space-between;\n padding: $spacer 0;\n\n fieldset {\n padding: 0;\n margin: 0;\n }\n\n .flex-wrapper {\n width: 85%;\n }\n\n .flex-spacer {\n display: flex;\n justify-content: center;\n align-items: center;\n flex-grow: 1;\n width: 85%;\n }\n\n .flex-spacer:empty {\n content: ''; // just to make a empty div to have height\n }\n\n .status-message {\n color: $gray-400;\n }\n\n .error-message {\n color: $danger;\n width: 100%;\n word-break: break-word;\n margin-top: $spacer-1;\n margin-bottom: $spacer-1;\n }\n\n .btn-primary {\n min-width: 118px;\n }\n\n @keyframes fade-in {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n\n .is-initializing {\n opacity: 0;\n animation: fade-in $transition 1s forwards;\n }\n}\n","// Styling overrides for bootstrap\n\n// Override / set color variables\n$red: #f95d84;\n$orange: #f37e3f;\n$yellow: #fcd65b;\n$green: #9edc6f;\n$blue: #76d9e4;\n$purple: #aa9af4;\n\n//Define some UI colors\n$interfacegray: #2d2a2e;\n$interfaceblue: #4878ea;\n$interfacewhite: #f0f0ee; //same as gray-200\n$interfaceblack: #1a171a;\n\n//Define our Gray scale\n$white: $interfacewhite;\n$gray-100: #fcfcfa;\n$gray-200: $interfacewhite;\n$gray-300: #c0bfbf;\n$gray-400: #929192;\n$gray-500: #5b5a5c;\n$gray-600: #555356;\n$gray-700: #403e41;\n$gray-800: #373438;\n$gray-850: #322f33;\n$gray-900: #211f22;\n$black: $interfaceblack;\n$content-bg: $interfacegray;\n$background: $interfaceblack;\n$foreground: $interfacewhite;\n\n//Load colors into map\n$colors: ();\n$colors: map-merge(\n (\n 'red': $red,\n 'orange': $orange,\n 'yellow': $yellow,\n 'green': $green,\n 'blue': $blue,\n 'purple': $purple,\n 'white': $white,\n 'black': $black,\n ),\n $colors\n);\n\n//Set default colors\n$body-bg: $black;\n$body-color: $interfacewhite;\n\n// Set brand colors\n$primary: $interfaceblue;\n$primary-hover: darken($primary, 8%);\n$primary-dark: mix($primary, $content-bg, 25%);\n$primary-light: scale-color($primary, $lightness: -25%);\n$secondary: $gray-500;\n$secondary-hover: darken($secondary, 8%);\n$success: $green;\n$info: $yellow;\n$warning: $orange;\n$danger: $red;\n$danger-hover: darken($danger, 8%);\n$light: $gray-100;\n$mid: $gray-400; //Added a mid color, useful for input styling\n$dark: $gray-800;\n$green-dark: scale-color($green, $lightness: -45%, $saturation: -10%);\n\n$theme-colors: () !default;\n$theme-colors: map-merge(\n (\n 'primary': $primary,\n 'primary-hover': $primary-hover,\n 'primary-light': $primary-light,\n 'primary-dark': $primary-dark,\n 'secondary': $secondary,\n 'success': $success,\n 'info': $info,\n 'warning': $warning,\n 'danger': $danger,\n 'light': $light,\n 'dark': $dark,\n 'mid': $mid,\n 'content-bg': $interfacegray,\n 'background': $interfaceblack,\n 'foreground': $interfacewhite,\n ),\n $theme-colors\n);\n\n$component-active-bg: $primary;\n$theme-color-interval: 9%;\n$yiq-contrasted-threshold: 180;\n\n// Override fonts\n$font-family-sans-serif: 'Fira Sans', -apple-system, blinkmacsystemfont,\n 'Segoe UI', 'Roboto', 'Helvetica Neue', arial, sans-serif; //fira sans then native system ui fallbacks\n$font-family-monospace: 'Fira Mono', menlo, monaco, consolas, 'Liberation Mono',\n 'Courier New', monospace;\n$font-family-base: $font-family-sans-serif;\n\n$headings-font-weight: 400;\n\n//Text overides\n$text-muted: $gray-400;\n\n//Style Selection highlight color\n//so browsers add alpha to your color by default, ignoring opacity 1\n//by setting rgba with 0.99 it tricks browser into thinking there is alpha applied\n$text-select-color: $primary-hover;\n$text-select-color-editor: lighten(\n $gray-700,\n 15%\n); //we lighten it abit to account for that 0.01 loss, and because it needs some anyways.\n\n//Grid variables, same value as default just making easily accessible\n$grid-gutter-width: 30px;\n\n//Visual Overrides\n$border-radius: 4px;\n$box-shadow: 0 0.1rem 1rem rgba($black, 45%); //because our UI is so dark, we need darker default shadows\n$box-shadow-900: 0 0.1rem 1rem rgba(0, 0, 0, 45%); //darkest shadow for $black popups over $black UI\n\n//Override Btn\n$btn-border-radius: 4rem;\n$btn-padding-x: 1.5rem;\n$btn-transition: color 0.12s ease-in-out, background-color 0.12s ease-in-out,\n border-color 0.12s ease-in-out, box-shadow 0.12s ease-in-out; //default 0.15 is too long\n$btn-border-width: 2px;\n\n//Override Inputs\n$input-bg: $gray-600;\n$input-disabled-bg: $gray-800;\n$input-color: $foreground;\n$input-border-color: $gray-400;\n$input-placeholder-color: $gray-400;\n$input-focus-border-color: rgba($primary, 85%);\n\n$input-btn-focus-width: 0.2rem;\n$input-btn-focus-color: rgba($component-active-bg, 35%);\n$input-btn-focus-box-shadow: 0 0 0 $input-btn-focus-width $input-btn-focus-color;\n\n//checkbox\n$custom-control-indicator-bg: $gray-600;\n$custom-control-indicator-bg-size: 75% 75%;\n$custom-control-indicator-disabled-bg: $gray-800;\n$custom-control-indicator-checked-disabled-bg: $gray-800;\n$custom-control-label-disabled-color: $gray-400;\n\n//Custom Select\n$custom-select-indicator-color: $gray-400;\n$custom-select-bg-size: 16px 16px;\n//dhSort icon encoded\n$custom-select-indicator: str-replace(\n url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='#{$custom-select-indicator-color}' d='M4 7l-.4-.8 4-3.7h.8l4 3.7-.4.8H4zm0 2l-.4.8 4 3.7h.8l4-3.7L12 9H4z'/%3E%3C/svg%3E\"),\n '#',\n '%23'\n);\n$custom-select-focus-box-shadow: $input-btn-focus-box-shadow;\n$custom-select-disabled-color: darken($gray-400, 5%);\n$custom-select-disabled-bg: $gray-800;\n\n//modal\n$modal-content-bg: $gray-200;\n$modal-content-border-width: 0;\n$modal-md: 550px;\n\n// Toast notification\n$toast-bg: $primary-dark;\n$toast-color: $foreground;\n$toast-error-bg: mix($danger, $content-bg, 15%);\n$toast-error-color: $foreground;\n\n//tooltips\n$tooltip-bg: $gray-700;\n$tooltip-color: $foreground;\n$tooltip-box-shadow: 0 0.1rem 1.5rem 0.1rem rgba($black, 80%);\n\n//drowdowns\n$dropdown-bg: $gray-600;\n$dropdown-link-color: $foreground;\n$dropdown-link-hover-color: $foreground;\n$dropdown-link-hover-bg: $primary;\n$dropdown-divider-bg: $gray-700;\n\n//context menus\n$contextmenu-bg: $gray-600;\n$contextmenu-color: $foreground;\n$contextmenu-disabled-color: $text-muted;\n$contextmenu-keyboard-selected-bg: rgba($primary, 50%);\n$contextmenu-selected-bg: $primary;\n$contextmenu-selected-color: $foreground;\n\n//links\n$link-color: $gray-400;\n$link-hover-color: $foreground;\n\n//progress-bar\n$progress-bg: $gray-600;\n$progress-border-radius: 1rem;\n\n// Set global options\n$enable-shadows: false;\n$enable-gradients: false;\n$enable-print-styles: false; //I don't think anyone should expect to \"print\" this app.\n\n// Transition times\n$transition: 0.15s;\n$transition-mid: 0.2s;\n$transition-long: 0.3s;\n$transition-slow: 0.6s;\n\n//form-validation icon, uses vsWarning icon encoded here as svg\n$form-feedback-icon-invalid-color: theme-color('danger');\n$form-feedback-icon-invalid: str-replace(\n url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cg fill='none'%3E%3Cg fill='#{$form-feedback-icon-invalid-color}'%3E%3Cpath d='M7.56 1h.88l6.54 12.26-.44.74H1.44L1 13.26 7.56 1zM8 2.28 2.28 13H13.7L8 2.28zM8.625 12v-1h-1.25v1h1.25zm-1.25-2V6h1.25v4h-1.25z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E \"),\n '#',\n '%23'\n);\n","//Set of spacer variables from the spacer map\n$spacer-0: map-get($spacers, 0); //0\n$spacer-1: map-get($spacers, 1);\n$spacer-2: map-get($spacers, 2);\n$spacer-3: map-get($spacers, 3);\n$spacer-4: map-get($spacers, 4);\n$spacer-5: map-get($spacers, 5);\n\n//Marching Ants for golden layout dropzone and drag and drop\n//top bottom, left right.\n//create 4 background images that are 50% color 1, 50% color 2 using graidents, two veritical, two horizontal\n//size them to ant-size and thickness\n//position those images along the egdes and make top/bottom repeat-x and left/right repeat-y\n//then offest each of those background positions by ant-size in animation to make them march.\n$ant-size: 8px;\n$ant-thickness: 1px;\n\n@mixin ants-base($color-1: black, $color-2: white) {\n background-image: linear-gradient(to right, $color-2 50%, $color-1 50%),\n linear-gradient(to right, $color-2 50%, $color-1 50%),\n linear-gradient(to bottom, $color-2 50%, $color-1 50%),\n linear-gradient(to bottom, $color-2 50%, $color-1 50%);\n background-size: $ant-size $ant-thickness, $ant-size $ant-thickness,\n $ant-thickness $ant-size, $ant-thickness $ant-size;\n background-position: 0 top, 0 bottom, left 0, right 0;\n background-repeat: repeat-x, repeat-x, repeat-y, repeat-y;\n animation: march 0.5s;\n animation-timing-function: linear;\n animation-iteration-count: infinite;\n}\n\n@mixin drag-stack($pseudo-element) {\n &::#{$pseudo-element} {\n content: ' ';\n background: $primary;\n box-shadow: $box-shadow;\n border-radius: $border-radius;\n position: absolute;\n height: 100%;\n width: 100%;\n @content;\n }\n}\n\n$focus-bg-transparency: 0.12;\n$hover-bg-transparency: 0.14;\n$active-bg-transparency: 0.28;\n$exception-transparency: 0.13;\n"]}
@@ -0,0 +1,15 @@
1
+ import React, { FormEventHandler } from 'react';
2
+ import './LoginForm.scss';
3
+ export interface LoginFormProps {
4
+ /** What to display inside the form */
5
+ children: React.ReactNode;
6
+ /** Error message to display */
7
+ errorMessage?: string;
8
+ /** Whether currently logging in */
9
+ isLoggingIn?: boolean;
10
+ /** Triggered when the form is submitting */
11
+ onSubmit?: FormEventHandler;
12
+ }
13
+ export declare function LoginForm({ children, errorMessage, isLoggingIn, onSubmit, }: LoginFormProps): JSX.Element;
14
+ export default LoginForm;
15
+ //# sourceMappingURL=LoginForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoginForm.d.ts","sourceRoot":"","sources":["../src/LoginForm.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAChD,OAAO,kBAAkB,CAAC;AAE1B,MAAM,WAAW,cAAc;IAC7B,sCAAsC;IACtC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAE1B,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,mCAAmC;IACnC,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B;AAED,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,YAAY,EACZ,WAAmB,EACnB,QAAQ,GACT,EAAE,cAAc,eA2ChB;AAED,eAAe,SAAS,CAAC"}
@@ -0,0 +1,48 @@
1
+ import { LoadingSpinner } from '@deephaven/components';
2
+ import classNames from 'classnames';
3
+ import React from 'react';
4
+ import "./LoginForm.css";
5
+ export function LoginForm(_ref) {
6
+ var {
7
+ children,
8
+ errorMessage,
9
+ isLoggingIn = false,
10
+ onSubmit: _onSubmit
11
+ } = _ref;
12
+ return /*#__PURE__*/React.createElement("form", {
13
+ className: "login-form",
14
+ onSubmit: event => {
15
+ event.preventDefault();
16
+ event.stopPropagation();
17
+ _onSubmit === null || _onSubmit === void 0 ? void 0 : _onSubmit(event);
18
+ }
19
+ }, /*#__PURE__*/React.createElement("div", {
20
+ className: "flex-spacer"
21
+ }), /*#__PURE__*/React.createElement("div", {
22
+ className: "flex-wrapper"
23
+ }, /*#__PURE__*/React.createElement("fieldset", {
24
+ disabled: isLoggingIn,
25
+ className: "container-fluid"
26
+ }, children), /*#__PURE__*/React.createElement("div", {
27
+ className: "form-group d-flex justify-content-end align-items-center mb-0"
28
+ }, /*#__PURE__*/React.createElement("button", {
29
+ type: "submit",
30
+ className: classNames('btn btn-primary', {
31
+ 'btn-spinner': isLoggingIn
32
+ }, {
33
+ 'btn-cancelable': isLoggingIn
34
+ }),
35
+ "data-testid": "btn-login"
36
+ }, isLoggingIn && /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(LoadingSpinner, null), /*#__PURE__*/React.createElement("span", {
37
+ className: "btn-normal-content"
38
+ }, "Logging in"), /*#__PURE__*/React.createElement("span", {
39
+ className: "btn-hover-content"
40
+ }, "Cancel")), !isLoggingIn && 'Login'))), /*#__PURE__*/React.createElement("div", {
41
+ className: "flex-spacer"
42
+ }, errorMessage != null && /*#__PURE__*/React.createElement("p", {
43
+ className: "error-message mb-0",
44
+ role: "alert"
45
+ }, "".concat(errorMessage))));
46
+ }
47
+ export default LoginForm;
48
+ //# sourceMappingURL=LoginForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoginForm.js","names":["LoadingSpinner","classNames","React","LoginForm","children","errorMessage","isLoggingIn","onSubmit","event","preventDefault","stopPropagation"],"sources":["../src/LoginForm.tsx"],"sourcesContent":["import { LoadingSpinner } from '@deephaven/components';\nimport classNames from 'classnames';\nimport React, { FormEventHandler } from 'react';\nimport './LoginForm.scss';\n\nexport interface LoginFormProps {\n /** What to display inside the form */\n children: React.ReactNode;\n\n /** Error message to display */\n errorMessage?: string;\n\n /** Whether currently logging in */\n isLoggingIn?: boolean;\n\n /** Triggered when the form is submitting */\n onSubmit?: FormEventHandler;\n}\n\nexport function LoginForm({\n children,\n errorMessage,\n isLoggingIn = false,\n onSubmit,\n}: LoginFormProps) {\n return (\n <form\n className=\"login-form\"\n onSubmit={event => {\n event.preventDefault();\n event.stopPropagation();\n onSubmit?.(event);\n }}\n >\n <div className=\"flex-spacer\" />\n <div className=\"flex-wrapper\">\n <fieldset disabled={isLoggingIn} className=\"container-fluid\">\n {children}\n </fieldset>\n <div className=\"form-group d-flex justify-content-end align-items-center mb-0\">\n <button\n type=\"submit\"\n className={classNames(\n 'btn btn-primary',\n { 'btn-spinner': isLoggingIn },\n { 'btn-cancelable': isLoggingIn }\n )}\n data-testid=\"btn-login\"\n >\n {isLoggingIn && (\n <span>\n <LoadingSpinner />\n <span className=\"btn-normal-content\">Logging in</span>\n <span className=\"btn-hover-content\">Cancel</span>\n </span>\n )}\n {!isLoggingIn && 'Login'}\n </button>\n </div>\n </div>\n <div className=\"flex-spacer\">\n {errorMessage != null && (\n <p className=\"error-message mb-0\" role=\"alert\">{`${errorMessage}`}</p>\n )}\n </div>\n </form>\n );\n}\n\nexport default LoginForm;\n"],"mappings":"AAAA,SAASA,cAAc,QAAQ,uBAAuB;AACtD,OAAOC,UAAU,MAAM,YAAY;AACnC,OAAOC,KAAK,MAA4B,OAAO;AAAC;AAiBhD,OAAO,SAASC,SAAS,OAKN;EAAA,IALO;IACxBC,QAAQ;IACRC,YAAY;IACZC,WAAW,GAAG,KAAK;IACnBC,QAAQ,EAARA;EACc,CAAC;EACf,oBACE;IACE,SAAS,EAAC,YAAY;IACtB,QAAQ,EAAEC,KAAK,IAAI;MACjBA,KAAK,CAACC,cAAc,EAAE;MACtBD,KAAK,CAACE,eAAe,EAAE;MACvBH,SAAQ,aAARA,SAAQ,uBAARA,SAAQ,CAAGC,KAAK,CAAC;IACnB;EAAE,gBAEF;IAAK,SAAS,EAAC;EAAa,EAAG,eAC/B;IAAK,SAAS,EAAC;EAAc,gBAC3B;IAAU,QAAQ,EAAEF,WAAY;IAAC,SAAS,EAAC;EAAiB,GACzDF,QAAQ,CACA,eACX;IAAK,SAAS,EAAC;EAA+D,gBAC5E;IACE,IAAI,EAAC,QAAQ;IACb,SAAS,EAAEH,UAAU,CACnB,iBAAiB,EACjB;MAAE,aAAa,EAAEK;IAAY,CAAC,EAC9B;MAAE,gBAAgB,EAAEA;IAAY,CAAC,CACjC;IACF,eAAY;EAAW,GAEtBA,WAAW,iBACV,+CACE,oBAAC,cAAc,OAAG,eAClB;IAAM,SAAS,EAAC;EAAoB,GAAC,YAAU,CAAO,eACtD;IAAM,SAAS,EAAC;EAAmB,GAAC,QAAM,CAAO,CAEpD,EACA,CAACA,WAAW,IAAI,OAAO,CACjB,CACL,CACF,eACN;IAAK,SAAS,EAAC;EAAa,GACzBD,YAAY,IAAI,IAAI,iBACnB;IAAG,SAAS,EAAC,oBAAoB;IAAC,IAAI,EAAC;EAAO,aAAKA,YAAY,EAChE,CACG,CACD;AAEX;AAEA,eAAeF,SAAS"}
@@ -0,0 +1,7 @@
1
+ /// <reference types="react" />
2
+ import { User, UserPermissions } from '@deephaven/redux';
3
+ export type UserOverride = Partial<Omit<User, 'permissions'>>;
4
+ export type UserPermissionsOverride = Partial<UserPermissions>;
5
+ export declare const UserOverrideContext: import("react").Context<Partial<Omit<User, "permissions">>>;
6
+ export declare const UserPermissionsOverrideContext: import("react").Context<Partial<UserPermissions>>;
7
+ //# sourceMappingURL=UserContexts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserContexts.d.ts","sourceRoot":"","sources":["../src/UserContexts.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEzD,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC;AAE9D,MAAM,MAAM,uBAAuB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AAE/D,eAAO,MAAM,mBAAmB,6DAAkC,CAAC;AAEnE,eAAO,MAAM,8BAA8B,mDAE1C,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { createContext } from 'react';
2
+ export var UserOverrideContext = /*#__PURE__*/createContext({});
3
+ export var UserPermissionsOverrideContext = /*#__PURE__*/createContext({});
4
+ //# sourceMappingURL=UserContexts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserContexts.js","names":["createContext","UserOverrideContext","UserPermissionsOverrideContext"],"sources":["../src/UserContexts.ts"],"sourcesContent":["import { createContext } from 'react';\nimport { User, UserPermissions } from '@deephaven/redux';\n\nexport type UserOverride = Partial<Omit<User, 'permissions'>>;\n\nexport type UserPermissionsOverride = Partial<UserPermissions>;\n\nexport const UserOverrideContext = createContext<UserOverride>({});\n\nexport const UserPermissionsOverrideContext = createContext<UserPermissionsOverride>(\n {}\n);\n"],"mappings":"AAAA,SAASA,aAAa,QAAQ,OAAO;AAOrC,OAAO,IAAMC,mBAAmB,gBAAGD,aAAa,CAAe,CAAC,CAAC,CAAC;AAElE,OAAO,IAAME,8BAA8B,gBAAGF,aAAa,CACzD,CAAC,CAAC,CACH"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,10 @@
1
1
  export * from './AuthPlugin';
2
2
  export * from './AuthHandlerTypes';
3
3
  export { default as AuthPluginAnonymous } from './AuthPluginAnonymous';
4
+ export { default as AuthPluginBase } from './AuthPluginBase';
4
5
  export { default as AuthPluginParent } from './AuthPluginParent';
5
6
  export { default as AuthPluginPsk } from './AuthPluginPsk';
7
+ export * from './Login';
8
+ export * from './LoginForm';
9
+ export * from './UserContexts';
6
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC3D,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,10 @@
1
1
  export * from "./AuthPlugin.js";
2
2
  export * from "./AuthHandlerTypes.js";
3
3
  export { default as AuthPluginAnonymous } from "./AuthPluginAnonymous.js";
4
+ export { default as AuthPluginBase } from "./AuthPluginBase.js";
4
5
  export { default as AuthPluginParent } from "./AuthPluginParent.js";
5
6
  export { default as AuthPluginPsk } from "./AuthPluginPsk.js";
7
+ export * from "./Login.js";
8
+ export * from "./LoginForm.js";
9
+ export * from "./UserContexts.js";
6
10
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["default","AuthPluginAnonymous","AuthPluginParent","AuthPluginPsk"],"sources":["../src/index.ts"],"sourcesContent":["export * from './AuthPlugin';\nexport * from './AuthHandlerTypes';\nexport { default as AuthPluginAnonymous } from './AuthPluginAnonymous';\nexport { default as AuthPluginParent } from './AuthPluginParent';\nexport { default as AuthPluginPsk } from './AuthPluginPsk';\n"],"mappings":";;SAESA,OAAO,IAAIC,mBAAmB;AAAA,SAC9BD,OAAO,IAAIE,gBAAgB;AAAA,SAC3BF,OAAO,IAAIG,aAAa"}
1
+ {"version":3,"file":"index.js","names":["default","AuthPluginAnonymous","AuthPluginBase","AuthPluginParent","AuthPluginPsk"],"sources":["../src/index.ts"],"sourcesContent":["export * from './AuthPlugin';\nexport * from './AuthHandlerTypes';\nexport { default as AuthPluginAnonymous } from './AuthPluginAnonymous';\nexport { default as AuthPluginBase } from './AuthPluginBase';\nexport { default as AuthPluginParent } from './AuthPluginParent';\nexport { default as AuthPluginPsk } from './AuthPluginPsk';\nexport * from './Login';\nexport * from './LoginForm';\nexport * from './UserContexts';\n"],"mappings":";;SAESA,OAAO,IAAIC,mBAAmB;AAAA,SAC9BD,OAAO,IAAIE,cAAc;AAAA,SACzBF,OAAO,IAAIG,gBAAgB;AAAA,SAC3BH,OAAO,IAAII,aAAa;AAAA;AAAA;AAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deephaven/auth-plugins",
3
- "version": "0.37.4-beta.0+33c9673e",
3
+ "version": "0.37.4-logout.1+055523d8",
4
4
  "description": "Deephaven Auth Plugins",
5
5
  "keywords": [
6
6
  "Deephaven",
@@ -29,17 +29,24 @@
29
29
  },
30
30
  "scripts": {
31
31
  "build": "cross-env NODE_ENV=production run-p build:*",
32
- "build:babel": "babel ./src --out-dir ./dist --extensions \".ts,.tsx,.js,.jsx\" --source-maps --root-mode upward"
32
+ "build:babel": "babel ./src --out-dir ./dist --extensions \".ts,.tsx,.js,.jsx\" --source-maps --root-mode upward",
33
+ "build:sass": "sass --embed-sources --load-path=../../node_modules ./src:./dist"
33
34
  },
34
35
  "dependencies": {
35
- "@deephaven/components": "^0.37.4-beta.0+33c9673e",
36
- "@deephaven/jsapi-bootstrap": "^0.37.4-beta.0+33c9673e",
37
- "@deephaven/jsapi-types": "^0.37.4-beta.0+33c9673e",
38
- "@deephaven/jsapi-utils": "^0.37.4-beta.0+33c9673e",
39
- "@deephaven/log": "^0.37.4-beta.0+33c9673e"
36
+ "@deephaven/components": "^0.37.4-logout.1+055523d8",
37
+ "@deephaven/jsapi-bootstrap": "^0.37.4-logout.1+055523d8",
38
+ "@deephaven/jsapi-components": "^0.37.4-logout.1+055523d8",
39
+ "@deephaven/jsapi-types": "^0.37.4-logout.1+055523d8",
40
+ "@deephaven/jsapi-utils": "^0.37.4-logout.1+055523d8",
41
+ "@deephaven/log": "^0.37.4-logout.1+055523d8",
42
+ "@deephaven/redux": "^0.37.4-logout.1+055523d8",
43
+ "@deephaven/utils": "^0.37.4-logout.1+055523d8",
44
+ "classnames": "^2.3.1",
45
+ "js-cookie": "^3.0.5",
46
+ "react-transition-group": "^4.4.2"
40
47
  },
41
48
  "devDependencies": {
42
- "@deephaven/tsconfig": "^0.37.4-beta.0+33c9673e",
49
+ "@deephaven/tsconfig": "^0.37.4-logout.1+055523d8",
43
50
  "@types/react": "^17.0.2"
44
51
  },
45
52
  "peerDependencies": {
@@ -52,5 +59,5 @@
52
59
  "publishConfig": {
53
60
  "access": "public"
54
61
  },
55
- "gitHead": "33c9673e1f523f9dba1f06d13b4a2aa5441c0679"
62
+ "gitHead": "055523d81e65b5f0ef2d2515bcfe091f4a3391de"
56
63
  }