diff --git a/package.json b/package.json index f8cd8fc5..ad9ab7c8 100644 --- a/package.json +++ b/package.json @@ -47,8 +47,7 @@ "postbuild": "yarn copy-files", "test:ci": "jest --passWithNoTests --ci src", "test:coverage": "jest --coverage src", - "test:watch": "jest --watch src", - "test": "jest src", + "test": "jest --watch src", "lint:ts": "eslint --ignore-path .gitignore \"src/**/*.+(ts|js|tsx)\"", "lint:css": "stylelint \"src/**/*.css\"", "lint": "yarn lint:ts && yarn lint:css", diff --git a/src/components/Auth/Auth.stories.tsx b/src/components/Auth/Auth.stories.tsx index d90667a5..0f27a904 100644 --- a/src/components/Auth/Auth.stories.tsx +++ b/src/components/Auth/Auth.stories.tsx @@ -26,8 +26,8 @@ const meta: Meta = { export default meta; const Template: Story = args => { - const [pwdOrTokens, setPwdOrTokens] = useState<'password' | 'tokens'>( - args.pwdOrTokens as 'password' | 'tokens' + const [pwdOrTokens, setPwdOrTokens] = useState( + args.pwdOrTokens as 'password' | 'tokens' | null ); return ( @@ -40,8 +40,8 @@ const Template: Story = args => { }; const TemplateWithModal: Story = args => { - const [pwdOrTokens, setPwdOrTokens] = useState<'password' | 'tokens'>( - args.pwdOrTokens as 'password' | 'tokens' + const [pwdOrTokens, setPwdOrTokens] = useState( + args.pwdOrTokens as 'password' | 'tokens' | null ); return ( diff --git a/src/components/Auth/Auth.test.tsx b/src/components/Auth/Auth.test.tsx index 0bb30b8f..3099348b 100644 --- a/src/components/Auth/Auth.test.tsx +++ b/src/components/Auth/Auth.test.tsx @@ -11,6 +11,7 @@ it('renders Auth unchanged', () => { showTokens={false} onFinish={() => Promise.resolve()} withModal={false} + openModal /> ); expect(container).toMatchSnapshot(); @@ -25,6 +26,7 @@ it('renders Auth with tokens unchanged', () => { showTokens={true} onFinish={() => Promise.resolve()} withModal={false} + openModal /> ); expect(container).toMatchSnapshot(); @@ -39,6 +41,7 @@ it('renders Auth on tokens unchanged', () => { showTokens={true} onFinish={() => Promise.resolve()} withModal={false} + openModal /> ); expect(container).toMatchSnapshot(); @@ -53,6 +56,7 @@ it('renders Auth with modal unchanged', () => { showTokens={true} onFinish={() => Promise.resolve()} withModal={true} + openModal /> ); expect(container).toMatchSnapshot(); diff --git a/src/components/Auth/Auth.tsx b/src/components/Auth/Auth.tsx index 9e1b18fd..f5198084 100644 --- a/src/components/Auth/Auth.tsx +++ b/src/components/Auth/Auth.tsx @@ -9,11 +9,12 @@ import './Auth.css'; export interface Props { pwdOrTokens: null | 'password' | 'tokens'; - setPwdOrTokens: (state: 'password' | 'tokens') => void; + setPwdOrTokens: (state: null | 'password' | 'tokens') => void; onFinish?: (values: AuthInputs) => Promise; minimumNumberOfRecoveryTokens?: number; showTokens?: boolean; withModal?: boolean; + openModal?: boolean; } type AuthInputs = { @@ -31,6 +32,7 @@ export const AuthWidget = ({ onFinish, minimumNumberOfRecoveryTokens = 1, showTokens = true, + openModal = false, withModal = false, }: Props) => { const { t } = useTranslation(); @@ -42,7 +44,7 @@ export const AuthWidget = ({ } = useForm(); const [numTokens, setNumTokens] = useState(1); - const [showModal, setShowModal] = useState(true); + const [showModal, setShowModal] = useState(!!pwdOrTokens); const onSubmit: SubmitHandler = data => { if ( @@ -134,33 +136,18 @@ export const AuthWidget = ({ )} - {!withModal && ( - - )} + ); return withModal ? ( {}} + onClose={() => setPwdOrTokens(null)} closable={false} - footer={ - - } > {form} diff --git a/src/components/MemoriWidget/MemoriWidget.tsx b/src/components/MemoriWidget/MemoriWidget.tsx index 90dc224a..7c6543d8 100644 --- a/src/components/MemoriWidget/MemoriWidget.tsx +++ b/src/components/MemoriWidget/MemoriWidget.tsx @@ -200,6 +200,11 @@ const MemoriWidget = ({ }: Props) => { const { t, i18n } = useTranslation(); + const [isClient, setIsClient] = useState(false); + useEffect(() => { + setIsClient(true); + }, []); + // API calls methods const client = memoriApiClient(apiUrl); const { @@ -538,8 +543,14 @@ const MemoriWidget = ({ dialogState: DialogState; sessionID: string; } | void> => { - if (memori.privacyType !== 'PUBLIC' && !memori.secretToken) { + if ( + memori.privacyType !== 'PUBLIC' && + !memori.secretToken && + !memoriPwd && + !memoriTokens + ) { setAuthModalState('password'); + return; } setLoading(true); @@ -1626,12 +1637,15 @@ const MemoriWidget = ({ initializeTTS(); if ( (!sessionID && - ((memori.privacyType === 'SECRET' && !memori.secretToken) || - (memori.privacyType === 'PRIVATE' && !memori.secretToken))) || + memori.privacyType !== 'PUBLIC' && + !memori.secretToken && + !memoriPwd && + !memoriTokens) || (!sessionID && gotErrorInOpening) ) { setAuthModalState('password'); setClickedStart(false); + return; } else if (!sessionID) { setClickedStart(false); setGotErrorInOpening(false); @@ -1956,6 +1970,41 @@ const MemoriWidget = ({ showInstruct={showInstruct} loading={loading} /> + + {isClient && ( + { + if (values['password']) setMemoriPwd(values['password']); + if (values['tokens']) setMemoriTokens(values['tokens']); + + reopenSession( + !sessionId, + values['password'], + values['tokens'], + instruct ? memori.giverTag : undefined, + instruct ? memori.giverPIN : undefined, + initialContextVars, + initialQuestion + ) + .then(() => { + setAuthModalState(null); + setHasUserActivatedSpeak(true); + }) + .catch(() => { + setAuthModalState(null); + setGotErrorInOpening(true); + }); + }} + minimumNumberOfRecoveryTokens={ + memori?.minimumNumberOfRecoveryTokens ?? 1 + } + /> + )} ); }; diff --git a/src/components/ui/Modal.css b/src/components/ui/Modal.css index 506ae7cc..f9658ae9 100644 --- a/src/components/ui/Modal.css +++ b/src/components/ui/Modal.css @@ -1,6 +1,6 @@ .memori-modal { position: relative; - z-index: 60; + z-index: 1000; } .memori-modal--backdrop {