[MM-64425] Add configurable account deletion link (#31396)

* [MM-64425] Add configurable account deletion link

* Fix types

* PR feedback

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
Devin Binnie
2025-06-12 11:00:00 -04:00
коммит произвёл GitHub
родитель 6d7a8c6d72
Коммит 74258c3b7a
10 изменённых файлов: 70 добавлений и 13 удалений

Просмотреть файл

@@ -202,6 +202,7 @@ const defaultServerConfig: AdminConfig = {
ScheduledPosts: true,
EnableWebHubChannelIteration: false,
FrameAncestors: '',
DeleteAccountLink: '',
},
TeamSettings: {
SiteName: 'Mattermost',

Просмотреть файл

@@ -52,6 +52,7 @@ func GenerateClientConfig(c *model.Config, telemetryID string, license *model.Li
props["EnableInlineLatex"] = strconv.FormatBool(*c.ServiceSettings.EnableInlineLatex)
props["ExtendSessionLengthWithActivity"] = strconv.FormatBool(*c.ServiceSettings.ExtendSessionLengthWithActivity)
props["ManagedResourcePaths"] = *c.ServiceSettings.ManagedResourcePaths
props["DeleteAccountLink"] = *c.ServiceSettings.DeleteAccountLink
// This setting is only temporary, so keep using the old setting name for the mobile and web apps
props["ExperimentalEnablePostMetadata"] = "true"

Просмотреть файл

@@ -454,6 +454,7 @@ type ServiceSettings struct {
ScheduledPosts *bool `access:"site_posts"`
EnableWebHubChannelIteration *bool `access:"write_restrictable,cloud_restrictable"` // telemetry: none
FrameAncestors *string `access:"write_restrictable,cloud_restrictable"` // telemetry: none
DeleteAccountLink *string `access:"site_users_and_teams,write_restrictable,cloud_restrictable"`
}
var MattermostGiphySdkKey string
@@ -989,6 +990,14 @@ func (s *ServiceSettings) SetDefaults(isUpdate bool) {
if s.FrameAncestors == nil {
s.FrameAncestors = NewPointer("")
}
if !isSafeLink(s.DeleteAccountLink) {
*s.DeleteAccountLink = ""
}
if s.DeleteAccountLink == nil {
s.DeleteAccountLink = NewPointer("")
}
}
type CacheSettings struct {

Просмотреть файл

@@ -2672,6 +2672,14 @@ const AdminDefinition: AdminDefinitionType = {
placeholder: defineMessage({id: 'admin.team.refreshPostStatsRunTimeExample', defaultMessage: 'E.g.: "00:00"'}),
isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.SITE.USERS_AND_TEAMS)),
},
{
type: 'text',
key: 'ServiceSettings.DeleteAccountLink',
label: defineMessage({id: 'admin.team.deleteAccountTitle', defaultMessage: 'Delete Account Link:'}),
help_text: defineMessage({id: 'admin.team.deleteAccountDesc', defaultMessage: 'The URL for the Delete Account link in the Security tab of Profile Settings. If this field is empty, the Delete Account link is hidden from users.'}),
isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.SITE.CUSTOMIZATION)),
isHidden: it.licensedForFeature('Cloud'),
},
],
},
},

Просмотреть файл

@@ -108,7 +108,7 @@ exports[`components/user_settings/display/UserSettingsDisplay should match snaps
>
<i
aria-hidden="true"
className="fa fa-clock-o"
className="icon icon-clock-outline"
title="Access History Icon"
/>
<MemoizedFormattedMessage
@@ -131,7 +131,7 @@ exports[`components/user_settings/display/UserSettingsDisplay should match snaps
>
<i
aria-hidden="true"
className="fa fa-clock-o"
className="icon icon-clock-outline"
title="Active Sessions Icon"
/>
<MemoizedFormattedMessage
@@ -251,7 +251,7 @@ exports[`components/user_settings/display/UserSettingsDisplay should match snaps
>
<i
aria-hidden="true"
className="fa fa-clock-o"
className="icon icon-clock-outline"
title="Access History Icon"
/>
<MemoizedFormattedMessage
@@ -274,7 +274,7 @@ exports[`components/user_settings/display/UserSettingsDisplay should match snaps
>
<i
aria-hidden="true"
className="fa fa-clock-o"
className="icon icon-clock-outline"
title="Active Sessions Icon"
/>
<MemoizedFormattedMessage
@@ -394,7 +394,7 @@ exports[`components/user_settings/display/UserSettingsDisplay should match snaps
>
<i
aria-hidden="true"
className="fa fa-clock-o"
className="icon icon-clock-outline"
title="Access History Icon"
/>
<MemoizedFormattedMessage
@@ -417,7 +417,7 @@ exports[`components/user_settings/display/UserSettingsDisplay should match snaps
>
<i
aria-hidden="true"
className="fa fa-clock-o"
className="icon icon-clock-outline"
title="Active Sessions Icon"
/>
<MemoizedFormattedMessage
@@ -537,7 +537,7 @@ exports[`components/user_settings/display/UserSettingsDisplay should match snaps
>
<i
aria-hidden="true"
className="fa fa-clock-o"
className="icon icon-clock-outline"
title="Access History Icon"
/>
<MemoizedFormattedMessage
@@ -560,7 +560,7 @@ exports[`components/user_settings/display/UserSettingsDisplay should match snaps
>
<i
aria-hidden="true"
className="fa fa-clock-o"
className="icon icon-clock-outline"
title="Active Sessions Icon"
/>
<MemoizedFormattedMessage
@@ -681,7 +681,7 @@ exports[`components/user_settings/display/UserSettingsDisplay should match snaps
>
<i
aria-hidden="true"
className="fa fa-clock-o"
className="icon icon-clock-outline"
title="Access History Icon"
/>
<MemoizedFormattedMessage
@@ -704,7 +704,7 @@ exports[`components/user_settings/display/UserSettingsDisplay should match snaps
>
<i
aria-hidden="true"
className="fa fa-clock-o"
className="icon icon-clock-outline"
title="Active Sessions Icon"
/>
<MemoizedFormattedMessage

Просмотреть файл

@@ -56,6 +56,7 @@ function mapStateToProps(state: GlobalState, ownProps: Props) {
experimentalEnableAuthenticationTransfer,
passwordConfig: getPasswordConfig(state),
militaryTime: getBool(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.USE_MILITARY_TIME, false),
deleteAccountLink: config.DeleteAccountLink,
};
}

Просмотреть файл

@@ -70,6 +70,7 @@ type Props = {
militaryTime: boolean;
actions: Actions;
intl: IntlShape;
deleteAccountLink?: string;
};
type State = {
@@ -1077,7 +1078,7 @@ export class SecurityTab extends React.PureComponent<Props, State> {
id='viewAccessHistory'
>
<i
className='fa fa-clock-o'
className='icon icon-clock-outline'
title={this.props.intl.formatMessage({
id: 'user.settings.security.viewHistory.icon',
defaultMessage: 'Access History Icon',
@@ -1096,7 +1097,7 @@ export class SecurityTab extends React.PureComponent<Props, State> {
id='viewAndLogOutOfActiveSessions'
>
<i
className='fa fa-clock-o'
className='icon icon-clock-outline'
title={this.props.intl.formatMessage({
id: 'user.settings.security.logoutActiveSessions.icon',
defaultMessage: 'Active Sessions Icon',
@@ -1108,6 +1109,30 @@ export class SecurityTab extends React.PureComponent<Props, State> {
defaultMessage='View and Log Out of Active Sessions'
/>
</ToggleModalButton>
{this.props.deleteAccountLink && (
<>
<p/>
<ExternalLink
className='security-links color--link mt-2 danger'
href={this.props.deleteAccountLink}
id='deleteAccountLink'
location={window.location.href}
>
<i
className='icon icon-trash-can-outline'
title={this.props.intl.formatMessage({
id: 'user.settings.security.deleteAccountLink.icon',
defaultMessage: 'Delete Account Icon',
})}
aria-hidden='true'
/>
<FormattedMessage
id='user.settings.security.deleteAccountLink'
defaultMessage='Delete Your Account'
/>
</ExternalLink>
</>
)}
</div>
</div>
);

Просмотреть файл

@@ -2981,6 +2981,8 @@
"admin.team.customUserGroupsTitle": "Enable Custom User Groups: ",
"admin.team.customUserStatusesDescription": "When true, users can set a descriptive status message and status emoji visible to all users.",
"admin.team.customUserStatusesTitle": "Enable Custom Statuses: ",
"admin.team.deleteAccountDesc": "The URL for the Delete Account link in the Security tab of Profile Settings. If this field is empty, the Delete Account link is hidden from users.",
"admin.team.deleteAccountTitle": "Delete Account Link:",
"admin.team.emailInvitationsDescription": "When true users can invite others to the system using email.",
"admin.team.emailInvitationsTitle": "Enable Email Invitations: ",
"admin.team.enableJoinLeaveMessageDescription": "Choose the default configuration of system messages displayed when users join or leave channels. Users can override this default by configuring Join/Leave messages in Account Settings > Advanced.",
@@ -6074,6 +6076,8 @@
"user.settings.security.currentPassword": "Current Password",
"user.settings.security.currentPasswordError": "Please enter your current password.",
"user.settings.security.deauthorize": "Deauthorize",
"user.settings.security.deleteAccountLink": "Delete Your Account",
"user.settings.security.deleteAccountLink.icon": "Delete Account Icon",
"user.settings.security.emailPwd": "Email and Password",
"user.settings.security.gitlab": "GitLab",
"user.settings.security.google": "Google",

Просмотреть файл

@@ -210,9 +210,15 @@
.security-links {
margin-right: 20px;
text-decoration: none;
.fa {
.icon {
margin-right: 6px;
font-size: inherit;
}
&.danger {
color: variables.$red;
}
}

Просмотреть файл

@@ -222,6 +222,7 @@ export type ClientConfig = {
UsersStatusAndProfileFetchingPollIntervalMilliseconds: string;
YoutubeReferrerPolicy: 'true' | 'false';
ScheduledPosts: string;
DeleteAccountLink: string;
};
export type License = {
@@ -410,6 +411,7 @@ export type ServiceSettings = {
ScheduledPosts: boolean;
EnableWebHubChannelIteration: boolean;
FrameAncestors: string;
DeleteAccountLink: string;
};
export type TeamSettings = {