({
async queryFn(formData, _api, _extraOpts, fetchWithBQ) {
// Pull entries out from the hooked form.
@@ -78,7 +90,9 @@ const extended = gtsApi.injectEndpoints({
export const {
useUpdateCredentialsMutation,
+ useUserQuery,
usePasswordChangeMutation,
+ useEmailChangeMutation,
useAliasAccountMutation,
useMoveAccountMutation,
useAccountThemesQuery,
diff --git a/web/source/settings/lib/types/user.ts b/web/source/settings/lib/types/user.ts
new file mode 100644
index 000000000..92210d5d3
--- /dev/null
+++ b/web/source/settings/lib/types/user.ts
@@ -0,0 +1,34 @@
+/*
+ GoToSocial
+ Copyright (C) GoToSocial Authors admin@gotosocial.org
+ SPDX-License-Identifier: AGPL-3.0-or-later
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+export interface User {
+ id: string;
+ created_at: string;
+ email?: string;
+ unconfirmed_email?: string;
+ reason?: string;
+ last_emailed_at?: string;
+ confirmed_at?: string;
+ confirmation_sent_at?: string;
+ moderator: boolean;
+ admin: boolean;
+ disabled: boolean;
+ approved: boolean;
+ reset_password_sent_at?: string;
+}
diff --git a/web/source/settings/views/user/settings.tsx b/web/source/settings/views/user/settings.tsx
index cbd973706..a27cc1ba3 100644
--- a/web/source/settings/views/user/settings.tsx
+++ b/web/source/settings/views/user/settings.tsx
@@ -25,7 +25,9 @@ import FormWithData from "../../lib/form/form-with-data";
import Languages from "../../components/languages";
import MutationButton from "../../components/form/mutation-button";
import { useVerifyCredentialsQuery } from "../../lib/query/oauth";
-import { usePasswordChangeMutation, useUpdateCredentialsMutation } from "../../lib/query/user";
+import { useEmailChangeMutation, usePasswordChangeMutation, useUpdateCredentialsMutation, useUserQuery } from "../../lib/query/user";
+import Loading from "../../components/loading";
+import { User } from "../../lib/types/user";
export default function UserSettings() {
return (
@@ -98,6 +100,7 @@ function UserSettingsForm({ data }) {
/>
+
>
);
}
@@ -168,3 +171,105 @@ function PasswordChange() {
);
}
+
+function EmailChange() {
+ // Load existing user data.
+ const { data: user, isFetching, isLoading } = useUserQuery();
+ if (isFetching || isLoading) {
+ return ;
+ }
+
+ if (user === undefined) {
+ throw "could not fetch user";
+ }
+
+ return ;
+}
+
+function EmailChangeForm({user}: {user: User}) {
+ const form = {
+ currentEmail: useTextInput("current_email", {
+ defaultValue: user.email,
+ nosubmit: true
+ }),
+ newEmail: useTextInput("new_email", {
+ validator: (value: string | undefined) => {
+ if (!value) {
+ return "";
+ }
+
+ if (value.toLowerCase() === user.email?.toLowerCase()) {
+ return "cannot change to your existing address";
+ }
+
+ if (value.toLowerCase() === user.unconfirmed_email?.toLowerCase()) {
+ return "you already have a pending email address change to this address";
+ }
+
+ return "";
+ },
+ }),
+ password: useTextInput("password"),
+ };
+ const [submitForm, result] = useFormSubmit(form, useEmailChangeMutation());
+
+ return (
+
+ );
+}
diff --git a/web/template/email_confirm.tmpl b/web/template/email_confirm.tmpl
index b223e9e40..167ffcdf7 100644
--- a/web/template/email_confirm.tmpl
+++ b/web/template/email_confirm.tmpl
@@ -18,11 +18,15 @@
*/ -}}
Hello {{ .Username -}}!
-
+{{ if .NewSignup }}
You are receiving this mail because you've requested an account on {{ .InstanceURL -}}.
To use your account, you must confirm that this is your email address.
+{{ else }}
+You are receiving this mail because you've requested an email address change on {{ .InstanceURL -}}.
+To complete the change, you must confirm that this is your email address.
+{{ end }}
To confirm your email, paste the following in your browser's address bar:
{{ .ConfirmLink }}