Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Disable 3pid fields in settings when m.3pid_changes capability is disabled #11430

Merged
merged 5 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions src/components/views/settings/account/EmailAddresses.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ that is available.
interface IExistingEmailAddressProps {
email: ThirdPartyIdentifier;
onRemoved: (emails: ThirdPartyIdentifier) => void;
/**
* Disallow removal of this email address when truthy
*/
disabled?: boolean;
}

interface IExistingEmailAddressState {
Expand Down Expand Up @@ -121,7 +125,7 @@ export class ExistingEmailAddress extends React.Component<IExistingEmailAddressP
<span className="mx_GeneralUserSettingsTab_section--discovery_existing_address">
{this.props.email.address}
</span>
<AccessibleButton onClick={this.onRemove} kind="danger_sm">
<AccessibleButton onClick={this.onRemove} kind="danger_sm" disabled={this.props.disabled}>
{_t("Remove")}
</AccessibleButton>
</div>
Expand All @@ -132,6 +136,10 @@ export class ExistingEmailAddress extends React.Component<IExistingEmailAddressP
interface IProps {
emails: ThirdPartyIdentifier[];
onEmailsChange: (emails: ThirdPartyIdentifier[]) => void;
/**
* Adding or removing emails is disabled when truthy
*/
disabled?: boolean;
}

interface IState {
Expand Down Expand Up @@ -248,11 +256,18 @@ export default class EmailAddresses extends React.Component<IProps, IState> {

public render(): React.ReactNode {
const existingEmailElements = this.props.emails.map((e) => {
return <ExistingEmailAddress email={e} onRemoved={this.onRemoved} key={e.address} />;
return (
<ExistingEmailAddress
email={e}
onRemoved={this.onRemoved}
key={e.address}
disabled={this.props.disabled}
/>
);
});

let addButton = (
<AccessibleButton onClick={this.onAddClick} kind="primary">
<AccessibleButton onClick={this.onAddClick} kind="primary" disabled={this.props.disabled}>
{_t("Add")}
</AccessibleButton>
);
Expand Down Expand Up @@ -283,7 +298,7 @@ export default class EmailAddresses extends React.Component<IProps, IState> {
type="text"
label={_t("Email Address")}
autoComplete="email"
disabled={this.state.verifying}
disabled={this.props.disabled || this.state.verifying}
value={this.state.newEmailAddress}
onChange={this.onChangeNewEmailAddress}
/>
Expand Down
31 changes: 25 additions & 6 deletions src/components/views/settings/account/PhoneNumbers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ This is a copy/paste of EmailAddresses, mostly.
interface IExistingPhoneNumberProps {
msisdn: ThirdPartyIdentifier;
onRemoved: (phoneNumber: ThirdPartyIdentifier) => void;
/**
* Disable removing phone number
*/
disabled?: boolean;
}

interface IExistingPhoneNumberState {
Expand Down Expand Up @@ -116,7 +120,7 @@ export class ExistingPhoneNumber extends React.Component<IExistingPhoneNumberPro
<span className="mx_GeneralUserSettingsTab_section--discovery_existing_address">
+{this.props.msisdn.address}
</span>
<AccessibleButton onClick={this.onRemove} kind="danger_sm">
<AccessibleButton onClick={this.onRemove} kind="danger_sm" disabled={this.props.disabled}>
{_t("Remove")}
</AccessibleButton>
</div>
Expand All @@ -127,6 +131,10 @@ export class ExistingPhoneNumber extends React.Component<IExistingPhoneNumberPro
interface IProps {
msisdns: ThirdPartyIdentifier[];
onMsisdnsChange: (phoneNumbers: ThirdPartyIdentifier[]) => void;
/**
* Adding or removing phone numbers is disabled when truthy
*/
disabled?: boolean;
}

interface IState {
Expand Down Expand Up @@ -251,11 +259,18 @@ export default class PhoneNumbers extends React.Component<IProps, IState> {

public render(): React.ReactNode {
const existingPhoneElements = this.props.msisdns.map((p) => {
return <ExistingPhoneNumber msisdn={p} onRemoved={this.onRemoved} key={p.address} />;
return (
<ExistingPhoneNumber
msisdn={p}
onRemoved={this.onRemoved}
key={p.address}
disabled={this.props.disabled}
/>
);
});

let addVerifySection = (
<AccessibleButton onClick={this.onAddClick} kind="primary">
<AccessibleButton onClick={this.onAddClick} kind="primary" disabled={this.props.disabled}>
{_t("Add")}
</AccessibleButton>
);
Expand All @@ -277,14 +292,18 @@ export default class PhoneNumbers extends React.Component<IProps, IState> {
type="text"
label={_t("Verification code")}
autoComplete="off"
disabled={this.state.continueDisabled}
disabled={this.props.disabled || this.state.continueDisabled}
value={this.state.newPhoneNumberCode}
onChange={this.onChangeNewPhoneNumberCode}
/>
<AccessibleButton
onClick={this.onContinueClick}
kind="primary"
disabled={this.state.continueDisabled || this.state.newPhoneNumberCode.length === 0}
disabled={
this.props.disabled ||
this.state.continueDisabled ||
this.state.newPhoneNumberCode.length === 0
}
>
{_t("Continue")}
</AccessibleButton>
Expand Down Expand Up @@ -313,7 +332,7 @@ export default class PhoneNumbers extends React.Component<IProps, IState> {
type="text"
label={_t("Phone Number")}
autoComplete="tel-national"
disabled={this.state.verifying}
disabled={this.props.disabled || this.state.verifying}
prefixComponent={phoneCountry}
value={this.state.newPhoneNumber}
onChange={this.onChangeNewPhoneNumber}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ TODO: Reduce all the copying between account vs. discovery components.

interface IEmailAddressProps {
email: ThirdPartyIdentifier;
disabled?: boolean;
}

interface IEmailAddressState {
Expand Down Expand Up @@ -194,6 +195,7 @@ export class EmailAddress extends React.Component<IEmailAddressProps, IEmailAddr
className="mx_GeneralUserSettingsTab_section--discovery_existing_button"
kind="danger_sm"
onClick={this.onRevokeClick}
disabled={this.props.disabled}
>
{_t("Revoke")}
</AccessibleButton>
Expand All @@ -204,6 +206,7 @@ export class EmailAddress extends React.Component<IEmailAddressProps, IEmailAddr
className="mx_GeneralUserSettingsTab_section--discovery_existing_button"
kind="primary_sm"
onClick={this.onShareClick}
disabled={this.props.disabled}
>
{_t("Share")}
</AccessibleButton>
Expand All @@ -221,6 +224,7 @@ export class EmailAddress extends React.Component<IEmailAddressProps, IEmailAddr
interface IProps {
emails: ThirdPartyIdentifier[];
isLoading?: boolean;
disabled?: boolean;
}

export default class EmailAddresses extends React.Component<IProps> {
Expand All @@ -230,7 +234,7 @@ export default class EmailAddresses extends React.Component<IProps> {
content = <InlineSpinner />;
} else if (this.props.emails.length > 0) {
content = this.props.emails.map((e) => {
return <EmailAddress email={e} key={e.address} />;
return <EmailAddress email={e} key={e.address} disabled={this.props.disabled} />;
});
}

Expand Down
6 changes: 5 additions & 1 deletion src/components/views/settings/discovery/PhoneNumbers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ This is a copy/paste of EmailAddresses, mostly.

interface IPhoneNumberProps {
msisdn: ThirdPartyIdentifier;
disabled?: boolean;
}

interface IPhoneNumberState {
Expand Down Expand Up @@ -202,6 +203,7 @@ export class PhoneNumber extends React.Component<IPhoneNumberProps, IPhoneNumber
className="mx_GeneralUserSettingsTab_section--discovery_existing_button"
kind="danger_sm"
onClick={this.onRevokeClick}
disabled={this.props.disabled}
>
{_t("Revoke")}
</AccessibleButton>
Expand All @@ -212,6 +214,7 @@ export class PhoneNumber extends React.Component<IPhoneNumberProps, IPhoneNumber
className="mx_GeneralUserSettingsTab_section--discovery_existing_button"
kind="primary_sm"
onClick={this.onShareClick}
disabled={this.props.disabled}
>
{_t("Share")}
</AccessibleButton>
Expand All @@ -230,6 +233,7 @@ export class PhoneNumber extends React.Component<IPhoneNumberProps, IPhoneNumber
interface IProps {
msisdns: ThirdPartyIdentifier[];
isLoading?: boolean;
disabled?: boolean;
}

export default class PhoneNumbers extends React.Component<IProps> {
Expand All @@ -239,7 +243,7 @@ export default class PhoneNumbers extends React.Component<IProps> {
content = <InlineSpinner />;
} else if (this.props.msisdns.length > 0) {
content = this.props.msisdns.map((e) => {
return <PhoneNumber msisdn={e} key={e.address} />;
return <PhoneNumber msisdn={e} key={e.address} disabled={this.props.disabled} />;
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ interface IState {
canChangePassword: boolean;
idServerName?: string;
externalAccountManagementUrl?: string;
canMake3pidChanges: boolean;
}

export default class GeneralUserSettingsTab extends React.Component<IProps, IState> {
Expand Down Expand Up @@ -120,6 +121,7 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
msisdns: [],
loading3pids: true, // whether or not the emails and msisdns have been loaded
canChangePassword: false,
canMake3pidChanges: false,
};

this.dispatcherRef = dis.register(this.onAction);
Expand Down Expand Up @@ -174,8 +176,12 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
const canChangePassword = !changePasswordCap || changePasswordCap["enabled"] !== false;

const externalAccountManagementUrl = getDelegatedAuthAccountUrl(cli.getClientWellKnown());
// https://spec.matrix.org/v1.7/client-server-api/#m3pid_changes-capability
// We support as far back as v1.1 which doesn't have m.3pid_changes
// so the behaviour for when it is missing has to be assume true
const canMake3pidChanges = !capabilities["m.3pid_changes"] || capabilities["m.3pid_changes"].enabled === true;

this.setState({ canChangePassword, externalAccountManagementUrl });
this.setState({ canChangePassword, externalAccountManagementUrl, canMake3pidChanges });
}

private async getThreepidState(): Promise<void> {
Expand Down Expand Up @@ -323,12 +329,20 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
const emails = this.state.loading3pids ? (
<InlineSpinner />
) : (
<AccountEmailAddresses emails={this.state.emails} onEmailsChange={this.onEmailsChange} />
<AccountEmailAddresses
emails={this.state.emails}
onEmailsChange={this.onEmailsChange}
disabled={!this.state.canMake3pidChanges}
/>
);
const msisdns = this.state.loading3pids ? (
<InlineSpinner />
) : (
<AccountPhoneNumbers msisdns={this.state.msisdns} onMsisdnsChange={this.onMsisdnsChange} />
<AccountPhoneNumbers
msisdns={this.state.msisdns}
onMsisdnsChange={this.onMsisdnsChange}
disabled={!this.state.canMake3pidChanges}
/>
);
threepidSection = (
<>
Expand Down Expand Up @@ -463,8 +477,16 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta

const threepidSection = this.state.haveIdServer ? (
<>
<DiscoveryEmailAddresses emails={this.state.emails} isLoading={this.state.loading3pids} />
<DiscoveryPhoneNumbers msisdns={this.state.msisdns} isLoading={this.state.loading3pids} />
<DiscoveryEmailAddresses
emails={this.state.emails}
isLoading={this.state.loading3pids}
disabled={!this.state.canMake3pidChanges}
/>
<DiscoveryPhoneNumbers
msisdns={this.state.msisdns}
isLoading={this.state.loading3pids}
disabled={!this.state.canMake3pidChanges}
/>
</>
) : null;

Expand Down
Loading
Loading