UNPKG

@deephaven/auth-plugins

Version:
216 lines (215 loc) 7.84 kB
function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); } function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; } import React, { useCallback, useEffect, useRef, useState } from 'react'; import { FadeTransition, LoadingOverlay } from '@deephaven/components'; import { useClient } from '@deephaven/jsapi-bootstrap'; import { useBroadcastLoginListener } from '@deephaven/jsapi-components'; import Log from '@deephaven/log'; import { getErrorMessage } from '@deephaven/utils'; import Cookies from 'js-cookie'; import LoginForm from "./LoginForm.js"; import Login from "./Login.js"; import AuthenticationError from "./AuthenticationError.js"; import { jsx as _jsx } from "react/jsx-runtime"; import { jsxs as _jsxs } from "react/jsx-runtime"; import { Fragment as _Fragment } from "react/jsx-runtime"; var AUTH_TYPE = 'io.deephaven.authentication.psk.PskAuthenticationHandler'; var PSK_QUERY_PARAM_KEY = 'psk'; var PSK_TOKEN_KEY = 'io.deephaven.web.client.auth.psk.token'; var log = Log.module('AuthPluginPsk'); function getWindowToken() { return new URLSearchParams(window.location.search).get(PSK_QUERY_PARAM_KEY); } function clearWindowToken() { log.debug2('clearWindowToken'); var url = new URL(window.location.href); url.searchParams.delete(PSK_QUERY_PARAM_KEY); window.history.replaceState(null, '', url.href); } function readCookieToken() { var _Cookies$get; return (_Cookies$get = Cookies.get(PSK_TOKEN_KEY)) !== null && _Cookies$get !== void 0 ? _Cookies$get : null; } function storeCookieToken(token) { log.debug2('Storing token in cookie', token); if (token != null) { Cookies.set(PSK_TOKEN_KEY, token, { secure: true, sameSite: 'strict' }); } else { Cookies.remove(PSK_TOKEN_KEY); } } /** * AuthPlugin that tries to login using a pre-shared key. * Add the `psk=<token>` parameter to your URL string to set the token. */ function Component(_ref) { var { children, logoPath } = _ref; var client = useClient(); var inputField = useRef(null); var loginPromise = useRef(null); var [error, setError] = useState(); var [isInputRequired, setIsInputRequired] = useState(false); var [isLoggedIn, setIsLoggedIn] = useState(false); var [isLoggingIn, setIsLoggingIn] = useState(false); var [token, setToken] = useState(''); var login = useCallback( /*#__PURE__*/ // eslint-disable-next-line @typescript-eslint/no-inferrable-types function () { var _ref2 = _asyncToGenerator(function* (loginToken) { var showError = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; log.info('Logging in...'); setIsLoggingIn(true); var newLoginPromise = null; try { newLoginPromise = client.login({ type: AUTH_TYPE, token: loginToken }); loginPromise.current = newLoginPromise; yield newLoginPromise; log.info('Logged in successfully'); if (loginPromise.current !== newLoginPromise) { return; } storeCookieToken(loginToken); setIsLoggedIn(true); } catch (e) { if (loginPromise.current !== newLoginPromise) { return; } setIsInputRequired(true); if (showError) { var _getErrorMessage; log.error('Unable to login', e); var message = (_getErrorMessage = getErrorMessage(e)) !== null && _getErrorMessage !== void 0 ? _getErrorMessage : 'Unable to login: Verify credentials.'; setError(new AuthenticationError(message)); } } setIsLoggingIn(false); }); return function (_x) { return _ref2.apply(this, arguments); }; }(), [client]); var cancelLogin = useCallback(() => { loginPromise.current = null; setIsLoggingIn(false); }, []); var onLogin = useCallback( /*#__PURE__*/_asyncToGenerator(function* () { log.debug('onLogin'); // User logged in successfully in another tab, we should be able to read the token from the cookie and login var newToken = readCookieToken(); if (isLoggedIn || isLoggingIn || newToken == null) { return; } login(newToken, false); }), [isLoggedIn, isLoggingIn, login]); var onLogout = useCallback(() => { storeCookieToken(null); }, []); useBroadcastLoginListener(onLogin, onLogout); useEffect(() => { var isCanceled = false; function initialLogin() { return _initialLogin.apply(this, arguments); } function _initialLogin() { _initialLogin = _asyncToGenerator(function* () { var _getWindowToken; var initialToken = (_getWindowToken = getWindowToken()) !== null && _getWindowToken !== void 0 ? _getWindowToken : readCookieToken(); clearWindowToken(); if (initialToken == null) { setIsInputRequired(true); return; } setIsLoggingIn(true); try { yield client.login({ type: AUTH_TYPE, token: initialToken }); if (!isCanceled) { storeCookieToken(initialToken); setIsLoggedIn(true); setIsLoggingIn(false); } } catch (e) { if (!isCanceled) { setIsInputRequired(true); setIsLoggingIn(false); } } }); return _initialLogin.apply(this, arguments); } initialLogin(); return () => { isCanceled = true; }; }, [client]); var handleSubmit = useCallback(() => { if (!isLoggingIn) { login(token); } else { cancelLogin(); } }, [cancelLogin, isLoggingIn, login, token]); useEffect(function autoFocusInput() { var _inputField$current; (_inputField$current = inputField.current) === null || _inputField$current === void 0 ? void 0 : _inputField$current.focus(); }, [inputField, isInputRequired]); return /*#__PURE__*/_jsxs(_Fragment, { children: [isLoggedIn && children, isInputRequired && /*#__PURE__*/_jsx(FadeTransition, { in: !isLoggedIn, mountOnEnter: true, unmountOnExit: true, children: /*#__PURE__*/_jsx(Login, { logoPath: logoPath, children: /*#__PURE__*/_jsx(LoginForm, { errorMessage: getErrorMessage(error), isLoggingIn: isLoggingIn, onSubmit: handleSubmit, children: /*#__PURE__*/_jsxs("div", { className: "form-group", children: [/*#__PURE__*/_jsx("label", { htmlFor: "auth-psk-token-input", children: "Token" }), /*#__PURE__*/_jsx("input", { id: "auth-psk-token-input", name: "token", className: "input-token form-control", type: "text", autoComplete: "username", autoCapitalize: "none", autoCorrect: "off", spellCheck: "false", ref: inputField, value: token, onChange: event => { setError(undefined); setToken(event.target.value); } })] }) }) }) }), /*#__PURE__*/_jsx(LoadingOverlay, { "data-testid": "auth-psk-loading", isLoaded: isLoggedIn || isInputRequired, isLoading: !isLoggedIn && !isInputRequired })] }); } var AuthPluginPsk = { Component, isAvailable: authHandlers => authHandlers.includes(AUTH_TYPE) }; export default AuthPluginPsk; //# sourceMappingURL=AuthPluginPsk.js.map