1 import { useState } from 'react';
3 import { c } from 'ttag';
5 import { Button } from '@proton/atoms';
6 import Alert from '@proton/components/components/alert/Alert';
7 import Form from '@proton/components/components/form/Form';
8 import type { ModalProps } from '@proton/components/components/modalTwo/Modal';
9 import Modal from '@proton/components/components/modalTwo/Modal';
10 import ModalContent from '@proton/components/components/modalTwo/ModalContent';
11 import ModalFooter from '@proton/components/components/modalTwo/ModalFooter';
12 import ModalHeader from '@proton/components/components/modalTwo/ModalHeader';
13 import useModalState from '@proton/components/components/modalTwo/useModalState';
14 import InputFieldTwo from '@proton/components/components/v2/field/InputField';
15 import PasswordInputTwo from '@proton/components/components/v2/input/PasswordInput';
16 import useFormErrors from '@proton/components/components/v2/useFormErrors';
17 import AuthModal from '@proton/components/containers/password/AuthModal';
18 import useEventManager from '@proton/components/hooks/useEventManager';
19 import useNotifications from '@proton/components/hooks/useNotifications';
20 import type { PrivateKeyReference } from '@proton/crypto';
21 import { useLoading } from '@proton/hooks';
22 import { updateBackupKey } from '@proton/shared/lib/api/organization';
23 import { confirmPasswordValidator, passwordLengthValidator } from '@proton/shared/lib/helpers/formValidators';
24 import { getBackupKeyData } from '@proton/shared/lib/keys';
25 import noop from '@proton/utils/noop';
27 interface Props extends ModalProps {
28 hasOtherAdmins: boolean;
29 organizationKey: PrivateKeyReference;
32 const ChangeOrganizationPasswordModal = ({ hasOtherAdmins, organizationKey, onClose, ...rest }: Props) => {
33 const { call } = useEventManager();
34 const [loadingPromise, withLoading] = useLoading();
35 const [newPassword, setNewPassword] = useState('');
36 const [confirmPassword, setConfirmPassword] = useState('');
37 const { createNotification } = useNotifications();
38 const { validator, onFormSubmit } = useFormErrors();
39 const [config, setConfig] = useState<any>(undefined);
40 const [authModal, setAuthModalOpen, renderAuthModal] = useModalState();
42 const handleSubmit = async () => {
43 const { backupKeySalt, backupArmoredPrivateKey } = await getBackupKeyData({
44 backupPassword: newPassword,
47 const config = updateBackupKey({ PrivateKey: backupArmoredPrivateKey, KeySalt: backupKeySalt });
49 setAuthModalOpen(true);
52 const loading = loadingPromise || renderAuthModal;
53 const handleClose = loading ? noop : onClose;
57 {renderAuthModal && config && (
62 onSuccess={async () => {
64 createNotification({ text: c('Success').t`Password updated` });
73 if (!onFormSubmit()) {
76 void withLoading(handleSubmit());
81 <ModalHeader title={c('Title').t`Change organization password`} />
84 <div className="mb-4">
86 .t`Other administrators exist in your organization, you are responsible for communicating the new password to them.`}
89 <Alert className="mb-4" type="warning">
91 .t`Do NOT forget this password. If you forget it, you will not be able to manage your organization.`}
93 {c('Info').t`Save your password somewhere safe.`}
97 id="organizationPassword"
99 label={c('Label').t`New organization password`}
100 placeholder={c('Placeholder').t`Password`}
102 onValue={setNewPassword}
103 error={validator([passwordLengthValidator(newPassword)])}
104 autoComplete="new-password"
110 as={PasswordInputTwo}
111 label={c('Label').t`Confirm organization password`}
112 placeholder={c('Placeholder').t`Confirm`}
113 value={confirmPassword}
114 onValue={setConfirmPassword}
116 passwordLengthValidator(newPassword),
117 confirmPasswordValidator(newPassword, confirmPassword),
119 autoComplete="new-password"
123 <Button onClick={handleClose} disabled={loading}>
124 {c('Action').t`Close`}
126 <Button loading={loading} type="submit" color="norm">
127 {c('Action').t`Save`}
135 export default ChangeOrganizationPasswordModal;