diff --git a/src/app/providers/RouterProvider.tsx b/src/app/providers/RouterProvider.tsx
index 3546f32..c8cf995 100644
--- a/src/app/providers/RouterProvider.tsx
+++ b/src/app/providers/RouterProvider.tsx
@@ -9,6 +9,7 @@ import { RegisterPage } from '@pages/register'
import { ConverterPage } from '@pages/converter'
import { SeedPhrasePage } from '@pages/seed-phrase'
import { KycPage } from '@pages/kyc'
+import { RestorePasswordPage } from '@pages/restore-password'
import { ROUTES } from '@shared/config/routes'
import { ScrollToTop } from './ScrollToTop'
import { ProtectedRoute } from './ProtectedRoute'
@@ -24,6 +25,7 @@ export function RouterProvider() {
}>
} />
} />
+ } />
}>
diff --git a/src/features/auth/api/profileApi.ts b/src/features/auth/api/profileApi.ts
index c713bca..d65cd29 100644
--- a/src/features/auth/api/profileApi.ts
+++ b/src/features/auth/api/profileApi.ts
@@ -68,3 +68,41 @@ export async function uploadAvatar(payload: UploadAvatarPayload): Promise {
+ const csrf = await getCsrfToken()
+ const res = await fetch(`${USERS_API_URL}/me/settings/password/start`, {
+ method: 'POST',
+ credentials: 'include',
+ headers: {
+ 'X-CSRF-Token': csrf,
+ },
+ })
+ if (!res.ok) {
+ const data = await res.json().catch(() => ({}))
+ throw data
+ }
+}
+
+export interface PasswordResetCompletePayload {
+ code: string
+ new_password: string
+ confirm_password: string
+}
+
+export async function passwordResetComplete(payload: PasswordResetCompletePayload): Promise {
+ const csrf = await getCsrfToken()
+ const res = await fetch(`${USERS_API_URL}/me/settings/password/complete`, {
+ method: 'POST',
+ credentials: 'include',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'X-CSRF-Token': csrf,
+ },
+ body: JSON.stringify(payload),
+ })
+ if (!res.ok) {
+ const data = await res.json().catch(() => ({}))
+ throw data
+ }
+}
diff --git a/src/pages/restore-password/index.ts b/src/pages/restore-password/index.ts
new file mode 100644
index 0000000..07d031a
--- /dev/null
+++ b/src/pages/restore-password/index.ts
@@ -0,0 +1 @@
+export { RestorePasswordPage } from './ui/RestorePasswordPage'
diff --git a/src/pages/restore-password/ui/RestorePasswordPage.module.css b/src/pages/restore-password/ui/RestorePasswordPage.module.css
new file mode 100644
index 0000000..24fe10c
--- /dev/null
+++ b/src/pages/restore-password/ui/RestorePasswordPage.module.css
@@ -0,0 +1,7 @@
+.page {
+ min-height: 100vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 1rem 0;
+}
diff --git a/src/pages/restore-password/ui/RestorePasswordPage.tsx b/src/pages/restore-password/ui/RestorePasswordPage.tsx
new file mode 100644
index 0000000..2800407
--- /dev/null
+++ b/src/pages/restore-password/ui/RestorePasswordPage.tsx
@@ -0,0 +1,10 @@
+import { RestorePasswordForm } from '@widgets/restore-password-form'
+import styles from './RestorePasswordPage.module.css'
+
+export function RestorePasswordPage() {
+ return (
+
+
+
+ )
+}
diff --git a/src/shared/config/routes.ts b/src/shared/config/routes.ts
index bfd1152..4c6f298 100644
--- a/src/shared/config/routes.ts
+++ b/src/shared/config/routes.ts
@@ -10,4 +10,5 @@ export const ROUTES = {
SEED_PHRASE: '/seed-phrase',
CONVERTER: '/converter',
KYC: '/kyc',
+ RESTORE_PASSWORD: '/restore-password',
} as const
diff --git a/src/widgets/login-form/ui/LoginForm.tsx b/src/widgets/login-form/ui/LoginForm.tsx
index f3c14c7..0987f3b 100644
--- a/src/widgets/login-form/ui/LoginForm.tsx
+++ b/src/widgets/login-form/ui/LoginForm.tsx
@@ -76,7 +76,7 @@ export function LoginForm() {
-
Забыли пароль?
+
navigate(ROUTES.RESTORE_PASSWORD)}>Забыли пароль?
или