diff --git a/public/i18n/en.json b/public/i18n/en.json
index 4f107e0..3762487 100644
--- a/public/i18n/en.json
+++ b/public/i18n/en.json
@@ -115,6 +115,15 @@
"newPassword": "New password",
"newPasswordRepeat": "Repeat new password"
},
+ "changeEmailDialog": {
+ "label": "Change e-mail address",
+ "labelSet": "Set e-mail address",
+ "labelRemove": "Remove e-mail address",
+ "newMail": "New e-mail address",
+ "currentPassword": "Current password",
+ "oldCode": "Code sent to the old e-mail address",
+ "newCode": "Code sent to the new e-mail address"
+ },
"label": "Keep your account safe by using as much sign in methods as possible. Also check your credentials regularly to keep them up to date.",
"password": "Password",
"set": "Set",
diff --git a/src/app/chat/user-settings/security/email/email.html b/src/app/chat/user-settings/security/email/email.html
new file mode 100644
index 0000000..42b23a5
--- /dev/null
+++ b/src/app/chat/user-settings/security/email/email.html
@@ -0,0 +1,97 @@
+
+
+ @if (step() == 0) {
+
+
+
+
+ {{ ('chat.userSettingsDialog.security.changeEmailDialog.' + (changeEmailRemoveMode() ? 'labelRemove' : serviceManager.currentSession()!.userData.passwordSet ? 'label' : 'labelSet'))|translate }}
+
+
+ } @else {
+
+
+
+
+ {{ ('chat.userSettingsDialog.security.changeEmailDialog.' + (changeEmailRemoveMode() ? 'labelRemove' : serviceManager.currentSession()!.userData.passwordSet ? 'label' : 'labelSet'))|translate }}
+
+
+ }
+
+
+
+
+ {{ "chat.userSettingsDialog.security.email"|translate }}
+
+ @if (serviceManager.currentSession()!.userData.emailSet) {
+ {{ 'chat.userSettingsDialog.security.set'|translate }}
+
+ } @else {
+ {{ 'chat.userSettingsDialog.security.notSet'|translate }}
+
+ }
+
+
+
+
+ @if (serviceManager.currentSession()!.userData.phoneSet) {
+ {{ "chat.userSettingsDialog.security.changeMail"|translate }}
+ } @else {
+ {{ "chat.userSettingsDialog.security.setMail"|translate }}
+ }
+
+
+ @if (serviceManager.currentSession()!.userData.emailSet) {
+
+ {{ "chat.userSettingsDialog.security.removeMail"|translate }}
+
+ }
+
+
diff --git a/src/app/chat/user-settings/security/email/email.scss b/src/app/chat/user-settings/security/email/email.scss
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/chat/user-settings/security/email/email.spec.ts b/src/app/chat/user-settings/security/email/email.spec.ts
new file mode 100644
index 0000000..583023d
--- /dev/null
+++ b/src/app/chat/user-settings/security/email/email.spec.ts
@@ -0,0 +1,22 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { Email } from './email';
+
+describe('Email', () => {
+ let component: Email;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [Email],
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(Email);
+ component = fixture.componentInstance;
+ await fixture.whenStable();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/chat/user-settings/security/email/email.ts b/src/app/chat/user-settings/security/email/email.ts
new file mode 100644
index 0000000..5a54c5a
--- /dev/null
+++ b/src/app/chat/user-settings/security/email/email.ts
@@ -0,0 +1,105 @@
+import {Component, inject, signal} from '@angular/core';
+import {TranslatePipe} from '@ngx-translate/core';
+import {TuiBadge, TuiButtonLoading, TuiInputNumber} from '@taiga-ui/kit';
+import {
+ TuiButton,
+ TuiDialog,
+ TuiErrorComponent,
+ TuiIcon,
+ TuiInputDirective,
+ TuiLabel,
+ TuiTextfieldComponent
+} from '@taiga-ui/core';
+import {ServiceManager} from '../../../../service-manager';
+import {
+ AbstractControl,
+ FormControl,
+ FormGroup,
+ ReactiveFormsModule,
+ ValidationErrors,
+ Validators
+} from '@angular/forms';
+
+@Component({
+ selector: 'user-settings-security-email',
+ imports: [
+ TranslatePipe,
+ TuiBadge,
+ TuiButton,
+ TuiIcon,
+ ReactiveFormsModule,
+ TuiButtonLoading,
+ TuiDialog,
+ TuiErrorComponent,
+ TuiInputDirective,
+ TuiLabel,
+ TuiTextfieldComponent,
+ TuiInputNumber,
+ ],
+ templateUrl: './email.html',
+ styleUrl: './email.scss',
+})
+export class Email {
+ serviceManager = inject(ServiceManager)
+
+ step = signal(0)
+ changeEmailDialogOpen = signal(false)
+ changeEmailRemoveMode = signal(false)
+ changeEmailPending = signal(false)
+ verifyEmailPending = signal(false)
+ newAddress = ""
+
+ changeEmailForm = new FormGroup({
+ newAddress: new FormControl(""),
+ currentPassword: new FormControl(""),
+ })
+
+ verifyEmailForm = new FormGroup({
+ oldCode: new FormControl(0),
+ newCode: new FormControl(0, {validators: [Validators.required]})
+ })
+
+ openChangeEmailDialog(modeRemove: boolean) {
+ this.changeEmailDialogOpen.set(true)
+ this.changeEmailRemoveMode.set(modeRemove)
+ this.changeEmailForm.controls["currentPassword"].clearValidators()
+ this.changeEmailForm.controls["newAddress"].clearValidators()
+ if (!modeRemove) {
+ this.changeEmailForm.controls["newAddress"].setValidators([Validators.required])
+ this.changeEmailForm.controls["newAddress"].updateValueAndValidity()
+ }
+
+ this.changeEmailForm.controls["currentPassword"].setValidators([Validators.required])
+ this.changeEmailForm.controls["currentPassword"].updateValueAndValidity()
+ }
+
+ async changeEmail(currentPassword: string | null, newMail: string | null) {
+ this.changeEmailPending.set(true)
+ const service = this.serviceManager.currentSessionHandler
+ if (service) {
+ try {
+ await service.changeEmail(newMail ?? "", currentPassword ?? "")
+ if (!this.changeEmailRemoveMode()) {
+ this.newAddress = newMail ?? ""
+ this.verifyEmailForm.controls["oldCode"].setValidators([Validators.required])
+ this.step.set(1)
+ }
+ } catch (e) {
+ this.changeEmailForm.controls["currentPassword"].setErrors({incorrect: true})
+ }
+ }
+ }
+
+ async verifyEmail(newCode: number | null, oldCode: number | null) {
+ this.verifyEmailPending.set(true)
+ const service = this.serviceManager.currentSessionHandler
+ if (service) {
+ try {
+ await service.verifyEmailChange(oldCode ?? 0, newCode ?? 0, this.newAddress)
+ this.changeEmailDialogOpen.set(false)
+ } catch (e) {
+ this.verifyEmailForm.controls["newCode"].setErrors({incorrect: true})
+ }
+ }
+ }
+}
diff --git a/src/app/chat/user-settings/security/password/password.html b/src/app/chat/user-settings/security/password/password.html
index dfdbc4c..98ce371 100644
--- a/src/app/chat/user-settings/security/password/password.html
+++ b/src/app/chat/user-settings/security/password/password.html
@@ -1,7 +1,7 @@