From ffc7f3a97dbdedf398b9f4feb09e6d74c82bc666 Mon Sep 17 00:00:00 2001 From: Codex Date: Thu, 16 Apr 2026 16:30:36 +0300 Subject: [PATCH] fix: speed up otp login --- src/context/AuthContext.jsx | 51 ++++++++++++++------------------- src/context/AuthContext.test.js | 21 ++++++++++++++ 2 files changed, 43 insertions(+), 29 deletions(-) diff --git a/src/context/AuthContext.jsx b/src/context/AuthContext.jsx index c166173..d22d0c2 100644 --- a/src/context/AuthContext.jsx +++ b/src/context/AuthContext.jsx @@ -1,13 +1,11 @@ import React, { createContext, useContext, useEffect, useState } from "react"; import { demoUsers } from "../data/mockAppData"; import { supabase, hasSupabaseConfig } from "../supabaseClient"; -import { safeSupabaseCall } from "../services/safeSupabaseCall"; const AuthContext = createContext(null); const STORAGE_KEY = "construction-auth-local-user"; export const DEMO_LOGIN_EMAIL = "local@local"; export const ROLE_SWITCH_ENTRY_EMAIL = "roles@local"; -export const MISSING_PROFILE_ERROR = "Профиль пользователя не найден. Обратитесь к администратору."; export const PROFILE_LOAD_ERROR = "Не удалось загрузить профиль пользователя."; export const UNKNOWN_EMAIL_ERROR = "Email не найден в системе. Обратитесь к администратору."; @@ -66,6 +64,23 @@ export const mapProfileToAuthUser = (profile) => { }; }; +export const mapSessionUserToAuthUser = (sessionUser) => { + if (!sessionUser) { + return null; + } + + const userMetadata = sessionUser.user_metadata || {}; + const appMetadata = sessionUser.app_metadata || {}; + + return { + id: sessionUser.id, + email: sessionUser.email, + name: userMetadata.name || sessionUser.email || "Пользователь", + role: userMetadata.role || appMetadata.role || "manager", + lastLogin: sessionUser.last_sign_in_at || sessionUser.updated_at || null, + }; +}; + export const AuthProvider = ({ children }) => { const [user, setUser] = useState(() => { const stored = localStorage.getItem(STORAGE_KEY); @@ -83,39 +98,15 @@ export const AuthProvider = ({ children }) => { const { data: { subscription }, - } = supabase.auth.onAuthStateChange(async (_event, session) => { + } = supabase.auth.onAuthStateChange((_event, session) => { if (!session?.user) { setUser(null); setAuthError(""); return; } - const { data, error } = await safeSupabaseCall(async () => { - const { data: profile, error } = await supabase - .from("users") - .select("id, email, name, last_login, role_info:roles(name)") - .eq("id", session.user.id) - .maybeSingle(); - - if (error) { - throw error; - } - return profile; - }, "Ошибка загрузки профиля"); - - if (error) { - setUser(null); - setAuthError(error?.message || PROFILE_LOAD_ERROR); - return; - } - - if (!data) { - setUser(null); - setAuthError(MISSING_PROFILE_ERROR); - return; - } - - setUser(mapProfileToAuthUser(data)); + const nextUser = mapSessionUserToAuthUser(session.user); + setUser(nextUser); setAuthError(""); }); @@ -171,6 +162,8 @@ export const AuthProvider = ({ children }) => { throw normalizeOtpError(error); } + setUser(mapSessionUserToAuthUser(data.session?.user)); + setAuthError(""); return { success: Boolean(data.session) }; } diff --git a/src/context/AuthContext.test.js b/src/context/AuthContext.test.js index ef08d16..75b718b 100644 --- a/src/context/AuthContext.test.js +++ b/src/context/AuthContext.test.js @@ -6,6 +6,7 @@ import { buildOtpRequestPayload, isRoleSwitchEntryEmail, mapProfileToAuthUser, + mapSessionUserToAuthUser, normalizeOtpError, resolveDemoUser, resolveLoginEmail, @@ -75,6 +76,26 @@ describe("mapProfileToAuthUser", () => { }); }); +describe("mapSessionUserToAuthUser", () => { + it("maps session metadata to an immediate app user", () => { + expect( + mapSessionUserToAuthUser({ + id: "session-id", + email: "driver@company.ru", + user_metadata: { name: "Иван Соколов", role: "driver" }, + app_metadata: { role: "logistician" }, + last_sign_in_at: "2026-04-15T08:00:00Z", + }), + ).toEqual({ + id: "session-id", + email: "driver@company.ru", + name: "Иван Соколов", + role: "driver", + lastLogin: "2026-04-15T08:00:00Z", + }); + }); +}); + describe("normalizeOtpError", () => { it("maps unknown email errors to the admin hint", () => {