123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- import {cloneElement} from 'react';
- import {RouteComponentProps} from 'react-router';
- import {addErrorMessage} from 'sentry/actionCreators/indicator';
- import AsyncComponent from 'sentry/components/asyncComponent';
- import {t} from 'sentry/locale';
- import {Authenticator, OrganizationSummary, UserEmail} from 'sentry/types';
- import {defined} from 'sentry/utils';
- const ENDPOINT = '/users/me/authenticators/';
- type Props = {
- children: React.ReactElement;
- } & RouteComponentProps<{authId: string}, {}> &
- AsyncComponent['props'];
- type State = {
- emails: UserEmail[];
- authenticators?: Authenticator[] | null;
- organizations?: OrganizationSummary[];
- } & AsyncComponent['state'];
- class AccountSecurityWrapper extends AsyncComponent<Props, State> {
- getEndpoints(): ReturnType<AsyncComponent['getEndpoints']> {
- return [
- ['authenticators', ENDPOINT],
- ['organizations', '/organizations/'],
- ['emails', '/users/me/emails/'],
- ];
- }
- handleDisable = async (auth: Authenticator) => {
- if (!auth || !auth.authId) {
- return;
- }
- this.setState({loading: true});
- try {
- await this.api.requestPromise(`${ENDPOINT}${auth.authId}/`, {method: 'DELETE'});
- this.remountComponent();
- } catch (_err) {
- this.setState({loading: false});
- addErrorMessage(t('Error disabling %s', auth.name));
- }
- };
- handleRegenerateBackupCodes = async () => {
- this.setState({loading: true});
- try {
- await this.api.requestPromise(`${ENDPOINT}${this.props.params.authId}/`, {
- method: 'PUT',
- });
- this.remountComponent();
- } catch (_err) {
- this.setState({loading: false});
- addErrorMessage(t('Error regenerating backup codes'));
- }
- };
- handleRefresh = () => {
- this.fetchData();
- };
- renderBody() {
- const {children} = this.props;
- const {authenticators, organizations, emails} = this.state;
- const enrolled =
- authenticators?.filter(auth => auth.isEnrolled && !auth.isBackupInterface) || [];
- const countEnrolled = enrolled.length;
- const orgsRequire2fa = organizations?.filter(org => org.require2FA) || [];
- const deleteDisabled = orgsRequire2fa.length > 0 && countEnrolled === 1;
- const hasVerifiedEmail = !!emails?.find(({isVerified}) => isVerified);
- // This happens when you switch between children views and the next child
- // view is lazy loaded, it can potentially be `null` while the code split
- // package is being fetched
- if (!defined(children)) {
- return null;
- }
- return cloneElement(this.props.children, {
- onDisable: this.handleDisable,
- onRegenerateBackupCodes: this.handleRegenerateBackupCodes,
- authenticators,
- deleteDisabled,
- orgsRequire2fa,
- countEnrolled,
- hasVerifiedEmail,
- handleRefresh: this.handleRefresh,
- });
- }
- }
- export default AccountSecurityWrapper;
|