From fc4e6e7e4b87210af541d1038d3e041871d9621f Mon Sep 17 00:00:00 2001
From: Virgile <78490891+V-Gira@users.noreply.github.com>
Date: Fri, 6 Sep 2024 17:36:08 +0200
Subject: [PATCH] chore: allow support for appended URL paths [WPB-10937]
(#18013)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* fix: allow end user to set all url paths (WPB-4676) (#16774)
* fix: allow end user to set all url paths (WPB-4676)
* add new urls in env variables to config
* remove hard coded path from externalRoutes util
* update components using the externalRoutes util
* update missing components
* remove unused path
* rename subpath to url_path
* expose external urls instead of get methods
* add JS doc to methods appending UTM parameters
* Apply suggestions from code review
Co-authored-by: Przemysław Jóźwik
---------
Co-authored-by: Virgile
Co-authored-by: Przemysław Jóźwik
* chore: bump default config to 0.31.22 [WPB-10937]
---------
Co-authored-by: Virgile
Co-authored-by: Przemysław Jóźwik
---
app-config/package.json | 4 +-
server/config/client.config.ts | 19 +++-
server/config/env.ts | 17 +++
.../Message/DecryptErrorMessage.tsx | 4 +-
.../components/Modals/UserModal/UserModal.tsx | 3 +-
.../components/userDevices/DeviceList.tsx | 3 +-
.../components/userDevices/NoDevicesFound.tsx | 4 +-
src/script/externalRoute.ts | 107 +++++++-----------
src/script/main/app.ts | 4 +-
.../panels/preferences/AboutPreferences.tsx | 8 +-
.../AccountSecuritySection.tsx | 12 +-
11 files changed, 91 insertions(+), 94 deletions(-)
diff --git a/app-config/package.json b/app-config/package.json
index 81ea2182a2c..0c982f45cee 100644
--- a/app-config/package.json
+++ b/app-config/package.json
@@ -1,6 +1,6 @@
{
"dependencies": {
- "wire-web-config-default-master": "https://github.com/wireapp/wire-web-config-wire#v0.31.21-0",
- "wire-web-config-default-staging": "https://github.com/wireapp/wire-web-config-default#v0.31.20"
+ "wire-web-config-default-master": "https://github.com/wireapp/wire-web-config-wire#v0.31.22",
+ "wire-web-config-default-staging": "https://github.com/wireapp/wire-web-config-default#v0.31.22"
}
}
diff --git a/server/config/client.config.ts b/server/config/client.config.ts
index a7c58878b34..a1e54b7e5a0 100644
--- a/server/config/client.config.ts
+++ b/server/config/client.config.ts
@@ -77,27 +77,36 @@ export function generateConfig(params: ConfigGeneratorParams, env: Env) {
MOBILE_BASE: env.URL_MOBILE_BASE,
PRICING: env.URL_PRICING,
PRIVACY_POLICY: env.URL_PRIVACY_POLICY,
+ URL_PATH: {
+ CREATE_TEAM: env.URL_PATH_CREATE_TEAM,
+ MANAGE_SERVICES: env.URL_PATH_MANAGE_SERVICES,
+ MANAGE_TEAM: env.URL_PATH_MANAGE_TEAM,
+ PASSWORD_RESET: env.URL_PATH_PASSWORD_RESET,
+ },
SUPPORT: {
BUG_REPORT: env.URL_SUPPORT_BUG_REPORT,
CALLING: env.URL_SUPPORT_CALLING,
CAMERA_ACCESS_DENIED: env.URL_SUPPORT_CAMERA_ACCESS_DENIED,
CONTACT: env.URL_SUPPORT_CONTACT,
+ DECRYPT_ERROR: env.URL_SUPPORT_DECRYPT_ERROR,
DEVICE_ACCESS_DENIED: env.URL_SUPPORT_DEVICE_ACCESS_DENIED,
DEVICE_NOT_FOUND: env.URL_SUPPORT_DEVICE_NOT_FOUND,
+ E2EI_VERIFICATION: env.URL_SUPPORT_E2EI_VERIFICATION,
EMAIL_EXISTS: env.URL_SUPPORT_EMAIL_EXISTS,
+ FEDERATION_STOP: env.URL_SUPPORT_FEDERATION_STOP,
HISTORY: env.URL_SUPPORT_HISTORY,
INDEX: env.URL_SUPPORT_INDEX,
+ LEARN_MORE_ABOUT_GUEST_LINKS: env.URL_LEARN_MORE_ABOUT_GUEST_LINKS,
LEGAL_HOLD_BLOCK: env.URL_SUPPORT_LEGAL_HOLD_BLOCK,
MICROPHONE_ACCESS_DENIED: env.URL_SUPPORT_MICROPHONE_ACCESS_DENIED,
MLS_LEARN_MORE: env.URL_SUPPORT_MLS_LEARN_MORE,
- PRIVACY_VERIFY_FINGERPRINT: env.URL_SUPPORT_PRIVACY_VERIFY_FINGERPRINT,
- SCREEN_ACCESS_DENIED: env.URL_SUPPORT_SCREEN_ACCESS_DENIED,
- LEARN_MORE_ABOUT_GUEST_LINKS: env.URL_LEARN_MORE_ABOUT_GUEST_LINKS,
NON_FEDERATING_INFO: env.URL_SUPPORT_NON_FEDERATING_INFO,
OAUTH_LEARN_MORE: env.URL_SUPPORT_OAUTH_LEARN_MORE,
OFFLINE_BACKEND: env.URL_SUPPORT_OFFLINE_BACKEND,
- FEDERATION_STOP: env.URL_SUPPORT_FEDERATION_STOP,
- E2EI_VERIFICATION: env.URL_SUPPORT_E2EI_VERIFICATION,
+ PRIVACY_UNVERIFIED_USERS: env.URL_SUPPORT_PRIVACY_UNVERIFIED_USERS,
+ PRIVACY_VERIFY_FINGERPRINT: env.URL_SUPPORT_PRIVACY_VERIFY_FINGERPRINT,
+ PRIVACY_WHY: env.URL_SUPPORT_PRIVACY_WHY,
+ SCREEN_ACCESS_DENIED: env.URL_SUPPORT_SCREEN_ACCESS_DENIED,
},
TEAMS_BASE: env.URL_TEAMS_BASE,
TEAMS_CREATE: env.URL_TEAMS_CREATE,
diff --git a/server/config/env.ts b/server/config/env.ts
index 93a54c84be4..0e2861b2602 100644
--- a/server/config/env.ts
+++ b/server/config/env.ts
@@ -215,6 +215,16 @@ export type Env = {
/** Sets the host URL for the website, e.g. https://wire.com */
URL_WEBSITE_BASE: string;
+ /** Sets paths to append to a base URL */
+ URL_PATH_CREATE_TEAM: string;
+
+ URL_PATH_MANAGE_SERVICES: string;
+
+ URL_PATH_MANAGE_TEAM: string;
+
+ URL_PATH_PASSWORD_RESET: string;
+
+ /** Sets Support URLs to specific pages */
URL_SUPPORT_INDEX: string;
URL_SUPPORT_BUG_REPORT: string;
@@ -252,8 +262,15 @@ export type Env = {
URL_SUPPORT_OFFLINE_BACKEND: string;
URL_SUPPORT_FEDERATION_STOP: string;
+
URL_SUPPORT_E2EI_VERIFICATION: string;
+ URL_SUPPORT_DECRYPT_ERROR: string;
+
+ URL_SUPPORT_PRIVACY_UNVERIFIED_USERS: string;
+
+ URL_SUPPORT_PRIVACY_WHY: string;
+
URL_WHATS_NEW: string;
/** Content Security Policy
diff --git a/src/script/components/MessagesList/Message/DecryptErrorMessage.tsx b/src/script/components/MessagesList/Message/DecryptErrorMessage.tsx
index 16a1aa3aab9..ec4593b4c7e 100644
--- a/src/script/components/MessagesList/Message/DecryptErrorMessage.tsx
+++ b/src/script/components/MessagesList/Message/DecryptErrorMessage.tsx
@@ -20,7 +20,7 @@
import React, {useState} from 'react';
import {Icon} from 'Components/Icon';
-import {getDecryptErrorUrl} from 'src/script/externalRoute';
+import {Config} from 'src/script/Config';
import {MotionDuration} from 'src/script/motion/MotionDuration';
import {t} from 'Util/LocalizerUtil';
import {splitFingerprint} from 'Util/StringUtil';
@@ -36,7 +36,7 @@ export interface DecryptErrorMessageProps {
const DecryptErrorMessage: React.FC = ({message, onClickResetSession}) => {
const [isResettingSession, setIsResettingSession] = useState(false);
- const link = getDecryptErrorUrl();
+ const link = Config.getConfig().URL.SUPPORT.DECRYPT_ERROR;
const caption = message.isIdentityChanged
? t('conversationUnableToDecrypt2', message.user().name(), {
'/highlight': '',
diff --git a/src/script/components/Modals/UserModal/UserModal.tsx b/src/script/components/Modals/UserModal/UserModal.tsx
index 761580bf7a3..b6b4df5bd43 100644
--- a/src/script/components/Modals/UserModal/UserModal.tsx
+++ b/src/script/components/Modals/UserModal/UserModal.tsx
@@ -31,7 +31,6 @@ import {ModalComponent} from 'Components/ModalComponent';
import {EnrichedFields} from 'Components/panel/EnrichedFields';
import {UserActions} from 'Components/panel/UserActions';
import {UserDetails} from 'Components/panel/UserDetails';
-import {getPrivacyUnverifiedUsersUrl} from 'src/script/externalRoute';
import {useKoSubscribableChildren} from 'Util/ComponentUtil';
import {handleKeyDown} from 'Util/KeyboardUtil';
import {replaceLink, t} from 'Util/LocalizerUtil';
@@ -117,7 +116,7 @@ export const UnverifiedUserWarning: React.FC = ({use
css={{fontSize: 'var(--font-size-medium)', margin: '0 0.2em'}}
variant={LinkVariant.PRIMARY}
targetBlank
- href={getPrivacyUnverifiedUsersUrl()}
+ href={Config.getConfig().URL.SUPPORT.PRIVACY_UNVERIFIED_USERS}
>
{t('modalUserLearnMore')}
diff --git a/src/script/components/userDevices/DeviceList.tsx b/src/script/components/userDevices/DeviceList.tsx
index dce2baf5e77..a0dc7c891ce 100644
--- a/src/script/components/userDevices/DeviceList.tsx
+++ b/src/script/components/userDevices/DeviceList.tsx
@@ -30,7 +30,6 @@ import {DeviceCard} from './DeviceCard';
import type {ClientEntity} from '../../client/ClientEntity';
import {Config} from '../../Config';
import type {User} from '../../entity/User';
-import {getPrivacyWhyUrl} from '../../externalRoute';
interface DeviceListProps {
clickOnDevice: (client: ClientEntity) => void;
@@ -52,7 +51,7 @@ const DeviceList: React.FC = ({user, getDeviceIdentity, noPaddi
diff --git a/src/script/components/userDevices/NoDevicesFound.tsx b/src/script/components/userDevices/NoDevicesFound.tsx
index 5322967200b..831ee2b3c3b 100644
--- a/src/script/components/userDevices/NoDevicesFound.tsx
+++ b/src/script/components/userDevices/NoDevicesFound.tsx
@@ -26,7 +26,7 @@ import {t} from 'Util/LocalizerUtil';
import {Config} from '../../Config';
import type {User} from '../../entity/User';
-import {getPrivacyPolicyUrl} from '../../externalRoute';
+import {externalUrl} from '../../externalRoute';
interface NoDevicesFoundProps {
noPadding: boolean;
@@ -48,7 +48,7 @@ const NoDevicesFound: React.FC = ({user, noPadding}) => {
diff --git a/src/script/externalRoute.ts b/src/script/externalRoute.ts
index e391e909bcb..737bfe6a093 100644
--- a/src/script/externalRoute.ts
+++ b/src/script/externalRoute.ts
@@ -20,79 +20,55 @@
import {currentLanguage} from './auth/localeConfig';
import {Config} from './Config';
-const env = window.wire.env;
-
-export const URL = {
- ACCOUNT: env.URL?.ACCOUNT_BASE,
- PRIVACY_POLICY: env.URL?.PRIVACY_POLICY,
- SUPPORT: env.URL?.SUPPORT.INDEX,
- TEAM_SETTINGS: env.URL?.TEAMS_BASE,
- TERMS_OF_USE_PERSONAL: env.URL?.TERMS_OF_USE_PERSONAL,
- TERMS_OF_USE_TEAMS: env.URL?.TERMS_OF_USE_TEAMS,
- WEBAPP: {
- INTERNAL: 'https://wire-webapp-staging.wire.com',
- PRODUCTION: env.APP_BASE || 'https://app.wire.com',
- STAGING: 'https://wire-webapp-staging.zinfra.io',
- },
- WEBSITE: env.URL?.WEBSITE_BASE,
-};
-
-export const URL_PATH = {
- CREATE_TEAM: '/create-team/',
- DECRYPT_ERROR_1: '/articles/207948115',
- DECRYPT_ERROR_2: '/privacy/error-2/',
- MANAGE_SERVICES: '/services/',
- MANAGE_TEAM: '/login/',
- PASSWORD_RESET: '/forgot/',
- PRIVACY_HOW: '/privacy/how/',
- PRIVACY_UNVERIFIED_USERS: '/articles/202857164',
- PRIVACY_WHY: '/articles/207859815',
- SUPPORT_USERNAME: '/support/username/',
-} as const;
+const URL = Config.getConfig().URL;
const getTeamSettingsUrl = (path: string = '', utmSource?: string): string | undefined => {
const query = utmSource ? `?utm_source=${utmSource}&utm_term=desktop` : '';
- const teamSettingsUrl = `${URL.TEAM_SETTINGS}${path}${query}`;
- return URL.TEAM_SETTINGS ? teamSettingsUrl : undefined;
+ const teamSettingsUrl = `${URL.TEAMS_BASE}${path}${query}`;
+ return URL.TEAMS_BASE ? teamSettingsUrl : undefined;
};
-export const getWebsiteUrl = (path: string = '', pkCampaign?: string): string | undefined => {
- if (URL.WEBSITE) {
+const getWebsiteUrl = (path: string = '', pkCampaign?: string): string | undefined => {
+ if (URL.WEBSITE_BASE) {
const query = pkCampaign ? `?pk_campaign=${pkCampaign}&pk_kwd=desktop` : '';
- const websiteUrl = `${URL.WEBSITE}${path}${query}`;
- return addLocaleToUrl(URL.WEBSITE ? websiteUrl : undefined);
+ const websiteUrl = `${URL.WEBSITE_BASE}${path}${query}`;
+ return addLocaleToUrl(websiteUrl);
}
return undefined;
};
-const getHelpCenterUrl = (path: (typeof URL_PATH)[keyof typeof URL_PATH]) => {
- if (URL.SUPPORT) {
- const helpcenterUrl = `${URL.SUPPORT}${path}`;
- return addLocaleToHelpCenterUrl(URL.SUPPORT ? helpcenterUrl : undefined);
- }
- return undefined;
+const getAccountPagesUrl = (path: string = ''): string | undefined => {
+ return URL.ACCOUNT_BASE ? `${URL.ACCOUNT_BASE}${path}` : undefined;
};
-export const getAccountPagesUrl = (path: string = ''): string | undefined => {
- const accountPagesUrl = `${URL.ACCOUNT}${path}`;
- return URL.ACCOUNT ? accountPagesUrl : undefined;
-};
+const getPrivacyPolicyUrl = (): string | undefined => addLocaleToUrl(URL.PRIVACY_POLICY || undefined);
+const getTermsOfUsePersonalUrl = (): string | undefined => addLocaleToUrl(URL.TERMS_OF_USE_PERSONAL || undefined);
+const getTermsOfUseTeamUrl = (): string | undefined => addLocaleToUrl(URL.TERMS_OF_USE_TEAMS || undefined);
-export const getPrivacyPolicyUrl = (): string => addLocaleToUrl(URL.PRIVACY_POLICY || undefined);
-export const getTermsOfUsePersonalUrl = (): string => addLocaleToUrl(URL.TERMS_OF_USE_PERSONAL || undefined);
-export const getTermsOfUseTeamUrl = (): string => addLocaleToUrl(URL.TERMS_OF_USE_TEAMS || undefined);
+/**
+ * Retrieves the URL for managing services with optional UTM parameters.
+ * UTM parameters are used in online marketing to track the effectiveness of campaigns.
+ *
+ * @param utmSource - Optional. The source of the UTM parameters.
+ * @returns The URL for managing services with optional UTM parameters.
+ */
+export const getManageServicesUrl = (utmSource?: string): string | undefined =>
+ getTeamSettingsUrl(URL.URL_PATH.MANAGE_SERVICES, utmSource);
-export const getManageServicesUrl = (utmSource?: string): string =>
- getTeamSettingsUrl(URL_PATH.MANAGE_SERVICES, utmSource);
-export const getManageTeamUrl = (utmSource?: string): string => getTeamSettingsUrl(URL_PATH.MANAGE_TEAM, utmSource);
+/**
+ * Retrieves the URL for managing team settings with optional UTM parameters.
+ * UTM parameters are used in online marketing to track the effectiveness of campaigns.
+ *
+ * @param utmSource - Optional. The source of the UTM parameters.
+ * @returns The URL for managing team settings with optional UTM parameters.
+ */
+export const getManageTeamUrl = (utmSource?: string): string | undefined =>
+ getTeamSettingsUrl(URL.URL_PATH.MANAGE_TEAM, utmSource);
-export const getCreateTeamUrl = (): string =>
- Config.getConfig().FEATURE.ENABLE_ACCOUNT_REGISTRATION && `${Config.getConfig().URL.TEAMS_BASE}/register/email`;
-export const getDecryptErrorUrl = (): string => getHelpCenterUrl(URL_PATH.DECRYPT_ERROR_1);
-export const getPrivacyUnverifiedUsersUrl = (): string => getHelpCenterUrl(URL_PATH.PRIVACY_UNVERIFIED_USERS);
-export const getPrivacyWhyUrl = (): string => getHelpCenterUrl(URL_PATH.PRIVACY_WHY);
+const getCreateTeamUrl = (): string | undefined =>
+ Config.getConfig().FEATURE.ENABLE_ACCOUNT_REGISTRATION ? `${URL.TEAMS_BASE}${URL.URL_PATH.CREATE_TEAM}` : undefined;
-export const addLocaleToUrl = (url?: string): string => {
+export const addLocaleToUrl = (url?: string): string | undefined => {
if (!url) {
return undefined;
}
@@ -101,14 +77,11 @@ export const addLocaleToUrl = (url?: string): string => {
return url.replace(Config.getConfig().URL.WEBSITE_BASE, `${Config.getConfig().URL.WEBSITE_BASE}/${websiteLanguage}`);
};
-const addLocaleToHelpCenterUrl = (url?: string): string => {
- if (!url) {
- return undefined;
- }
- const language = currentLanguage().slice(0, 2);
- const websiteLanguage = language == 'de' ? language : 'en-us';
- return url.replace(
- `${Config.getConfig().URL.SUPPORT.INDEX}`,
- `${Config.getConfig().URL.SUPPORT.INDEX}/hc/${websiteLanguage}`,
- );
+export const externalUrl = {
+ createTeam: getCreateTeamUrl(),
+ passwordReset: getAccountPagesUrl(URL.URL_PATH?.PASSWORD_RESET),
+ privacyPolicy: getPrivacyPolicyUrl(),
+ termsOfUsePersonnal: getTermsOfUsePersonalUrl(),
+ termsOfUseTeam: getTermsOfUseTeamUrl(),
+ website: getWebsiteUrl(),
};
diff --git a/src/script/main/app.ts b/src/script/main/app.ts
index 0768374052f..55cd9aed548 100644
--- a/src/script/main/app.ts
+++ b/src/script/main/app.ts
@@ -82,7 +82,7 @@ import {ServiceMiddleware} from '../event/preprocessor/ServiceMiddleware';
import {FederationEventProcessor} from '../event/processor/FederationEventProcessor';
import {GiphyRepository} from '../extension/GiphyRepository';
import {GiphyService} from '../extension/GiphyService';
-import {getWebsiteUrl} from '../externalRoute';
+import {externalUrl} from '../externalRoute';
import {IntegrationRepository} from '../integration/IntegrationRepository';
import {IntegrationService} from '../integration/IntegrationService';
import {startNewVersionPolling} from '../lifecycle/newVersionHandler';
@@ -819,7 +819,7 @@ export class App {
const isLeavingGuestRoom = isTemporaryGuestReason && this.repository.user['userState'].self()?.isTemporaryGuest();
if (isLeavingGuestRoom) {
- const websiteUrl = getWebsiteUrl();
+ const websiteUrl = externalUrl.website;
if (websiteUrl) {
return window.location.replace(websiteUrl);
diff --git a/src/script/page/MainContent/panels/preferences/AboutPreferences.tsx b/src/script/page/MainContent/panels/preferences/AboutPreferences.tsx
index 5c5474093bb..f61050ce6af 100644
--- a/src/script/page/MainContent/panels/preferences/AboutPreferences.tsx
+++ b/src/script/page/MainContent/panels/preferences/AboutPreferences.tsx
@@ -31,7 +31,7 @@ import {PreferencesSection} from './components/PreferencesSection';
import {Config} from '../../../../Config';
import {User} from '../../../../entity/User';
-import {getPrivacyPolicyUrl, getTermsOfUsePersonalUrl, getTermsOfUseTeamUrl, URL} from '../../../../externalRoute';
+import {externalUrl} from '../../../../externalRoute';
interface AboutPreferencesProps {
selfUser: User;
@@ -42,12 +42,12 @@ const AboutPreferences: React.FC = ({selfUser, teamState
const inTeam = teamState.isInTeam(selfUser);
const config = Config.getConfig();
const desktopConfig = Config.getDesktopConfig();
- const websiteUrl = URL.WEBSITE;
- const privacyPolicyUrl = getPrivacyPolicyUrl();
+ const websiteUrl = externalUrl.website;
+ const privacyPolicyUrl = externalUrl.privacyPolicy;
const termsOfUseUrl = useMemo(() => {
if (selfUser) {
- return inTeam ? getTermsOfUseTeamUrl() : getTermsOfUsePersonalUrl();
+ return inTeam ? externalUrl.termsOfUseTeam : externalUrl.termsOfUsePersonnal;
}
return '';
}, [selfUser, inTeam]);
diff --git a/src/script/page/MainContent/panels/preferences/accountPreferences/AccountSecuritySection.tsx b/src/script/page/MainContent/panels/preferences/accountPreferences/AccountSecuritySection.tsx
index 71803f933b7..abcb64139ad 100644
--- a/src/script/page/MainContent/panels/preferences/accountPreferences/AccountSecuritySection.tsx
+++ b/src/script/page/MainContent/panels/preferences/accountPreferences/AccountSecuritySection.tsx
@@ -30,10 +30,9 @@ import {WebAppEvents} from '@wireapp/webapp-events';
import {PrimaryModal} from 'Components/Modals/PrimaryModal';
import {useKoSubscribableChildren} from 'Util/ComponentUtil';
import {t} from 'Util/LocalizerUtil';
-import {safeWindowOpen} from 'Util/SanitizationUtil';
import {User} from '../../../../../entity/User';
-import {getAccountPagesUrl, getCreateTeamUrl, getManageTeamUrl, URL_PATH} from '../../../../../externalRoute';
+import {externalUrl, getManageTeamUrl} from '../../../../../externalRoute';
import {TeamState} from '../../../../../team/TeamState';
import {AppLockState} from '../../../../../user/AppLockState';
import {FEATURES, hasAccessToFeature} from '../../../../../user/UserPermission';
@@ -53,7 +52,7 @@ const AccountSecuritySection: React.FC = ({
appLockState = container.resolve(AppLockState),
teamState = container.resolve(TeamState),
}) => {
- const createTeamUrl = getCreateTeamUrl();
+ const createTeamUrl = externalUrl.createTeam;
const manageTeamUrl = getManageTeamUrl('client_settings');
const {teamRole} = useKoSubscribableChildren(selfUser, ['teamRole']);
const {isAppLockActivated} = useKoSubscribableChildren(appLockState, ['isAppLockActivated']);
@@ -82,7 +81,8 @@ const AccountSecuritySection: React.FC = ({
safeWindowOpen(manageTeamUrl)}
+ href={manageTeamUrl}
+ targetBlank
data-uie-name="do-manage-team"
type="button"
>
@@ -110,8 +110,8 @@ const AccountSecuritySection: React.FC = ({
safeWindowOpen(getAccountPagesUrl(URL_PATH.PASSWORD_RESET))}
+ href={externalUrl.passwordReset}
+ targetBlank
title={t('tooltipPreferencesPassword')}
data-uie-name="do-reset-password"
type="button"