sa2kit 1.6.64 → 1.6.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/legacy/core/index.js +24 -12
- package/dist/auth/legacy/core/index.js.map +1 -1
- package/dist/auth/legacy/core/index.mjs +24 -12
- package/dist/auth/legacy/core/index.mjs.map +1 -1
- package/dist/auth/legacy/index.js +30 -12
- package/dist/auth/legacy/index.js.map +1 -1
- package/dist/auth/legacy/index.mjs +30 -12
- package/dist/auth/legacy/index.mjs.map +1 -1
- package/dist/auth/legacy/logic/index.js +24 -12
- package/dist/auth/legacy/logic/index.js.map +1 -1
- package/dist/auth/legacy/logic/index.mjs +24 -12
- package/dist/auth/legacy/logic/index.mjs.map +1 -1
- package/dist/auth/legacy/miniapp/index.js +24 -12
- package/dist/auth/legacy/miniapp/index.js.map +1 -1
- package/dist/auth/legacy/miniapp/index.mjs +24 -12
- package/dist/auth/legacy/miniapp/index.mjs.map +1 -1
- package/dist/auth/legacy/routes/index.d.mts +3 -0
- package/dist/auth/legacy/routes/index.d.ts +3 -0
- package/dist/auth/legacy/routes/index.js +8 -1
- package/dist/auth/legacy/routes/index.js.map +1 -1
- package/dist/auth/legacy/routes/index.mjs +8 -1
- package/dist/auth/legacy/routes/index.mjs.map +1 -1
- package/dist/auth/legacy/server/index.js +8 -1
- package/dist/auth/legacy/server/index.js.map +1 -1
- package/dist/auth/legacy/server/index.mjs +8 -1
- package/dist/auth/legacy/server/index.mjs.map +1 -1
- package/dist/auth/legacy/ui/miniapp/index.js.map +1 -1
- package/dist/auth/legacy/ui/miniapp/index.mjs.map +1 -1
- package/dist/auth/legacy/ui/web/index.js +6 -0
- package/dist/auth/legacy/ui/web/index.js.map +1 -1
- package/dist/auth/legacy/ui/web/index.mjs +6 -0
- package/dist/auth/legacy/ui/web/index.mjs.map +1 -1
- package/dist/auth/legacy/web/index.js +30 -12
- package/dist/auth/legacy/web/index.js.map +1 -1
- package/dist/auth/legacy/web/index.mjs +30 -12
- package/dist/auth/legacy/web/index.mjs.map +1 -1
- package/dist/festivalCard/index.d.mts +10 -0
- package/dist/festivalCard/index.d.ts +10 -0
- package/dist/festivalCard/index.js +206 -0
- package/dist/festivalCard/index.js.map +1 -0
- package/dist/festivalCard/index.mjs +181 -0
- package/dist/festivalCard/index.mjs.map +1 -0
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +210 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +208 -18
- package/dist/index.mjs.map +1 -1
- package/dist/screenReceiver/core/index.d.mts +10 -2
- package/dist/screenReceiver/core/index.d.ts +10 -2
- package/dist/screenReceiver/core/index.js +15 -0
- package/dist/screenReceiver/core/index.js.map +1 -1
- package/dist/screenReceiver/core/index.mjs +15 -1
- package/dist/screenReceiver/core/index.mjs.map +1 -1
- package/dist/screenReceiver/index.d.mts +1 -1
- package/dist/screenReceiver/index.d.ts +1 -1
- package/dist/screenReceiver/index.js +21 -3
- package/dist/screenReceiver/index.js.map +1 -1
- package/dist/screenReceiver/index.mjs +21 -4
- package/dist/screenReceiver/index.mjs.map +1 -1
- package/dist/screenReceiver/server/index.js +1 -1
- package/dist/screenReceiver/server/index.js.map +1 -1
- package/dist/screenReceiver/server/index.mjs +1 -1
- package/dist/screenReceiver/server/index.mjs.map +1 -1
- package/dist/screenReceiver/server/next.d.mts +9 -0
- package/dist/screenReceiver/server/next.d.ts +9 -0
- package/dist/screenReceiver/server/next.js +178 -0
- package/dist/screenReceiver/server/next.js.map +1 -0
- package/dist/screenReceiver/server/next.mjs +176 -0
- package/dist/screenReceiver/server/next.mjs.map +1 -0
- package/dist/screenReceiver/web/index.d.mts +1 -1
- package/dist/screenReceiver/web/index.d.ts +1 -1
- package/dist/screenReceiver/web/index.js +21 -3
- package/dist/screenReceiver/web/index.js.map +1 -1
- package/dist/screenReceiver/web/index.mjs +21 -4
- package/dist/screenReceiver/web/index.mjs.map +1 -1
- package/dist/showmasterpiece/index.js +30 -12
- package/dist/showmasterpiece/index.js.map +1 -1
- package/dist/showmasterpiece/index.mjs +30 -12
- package/dist/showmasterpiece/index.mjs.map +1 -1
- package/dist/showmasterpiece/ui/web/index.js +30 -12
- package/dist/showmasterpiece/ui/web/index.js.map +1 -1
- package/dist/showmasterpiece/ui/web/index.mjs +30 -12
- package/dist/showmasterpiece/ui/web/index.mjs.map +1 -1
- package/dist/showmasterpiece/web/index.js +30 -12
- package/dist/showmasterpiece/web/index.js.map +1 -1
- package/dist/showmasterpiece/web/index.mjs +30 -12
- package/dist/showmasterpiece/web/index.mjs.map +1 -1
- package/package.json +11 -1
|
@@ -8,6 +8,14 @@ var React__default = /*#__PURE__*/_interopDefault(React);
|
|
|
8
8
|
|
|
9
9
|
// src/auth/legacy/contexts/AuthContext.tsx
|
|
10
10
|
var AuthContext = React.createContext(void 0);
|
|
11
|
+
function extractUser(data) {
|
|
12
|
+
return data?.user ?? data?.data?.user ?? null;
|
|
13
|
+
}
|
|
14
|
+
function extractValid(data) {
|
|
15
|
+
if (typeof data?.valid === "boolean") return data.valid;
|
|
16
|
+
if (typeof data?.data?.valid === "boolean") return data.data.valid;
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
11
19
|
function AuthProvider({ children }) {
|
|
12
20
|
const [user, setUser] = React.useState(null);
|
|
13
21
|
const [loading, setLoading] = React.useState(true);
|
|
@@ -25,10 +33,12 @@ function AuthProvider({ children }) {
|
|
|
25
33
|
console.log("\u{1F4E1} [AuthContext] \u4F1A\u8BDD\u9A8C\u8BC1\u54CD\u5E94\u72B6\u6001:", response.status);
|
|
26
34
|
const data = await response.json();
|
|
27
35
|
console.log("\u{1F4C4} [AuthContext] \u4F1A\u8BDD\u9A8C\u8BC1\u54CD\u5E94\u6570\u636E:", data);
|
|
36
|
+
const resolvedUser = extractUser(data);
|
|
37
|
+
const resolvedValid = extractValid(data);
|
|
28
38
|
safeSetState(() => {
|
|
29
|
-
if (
|
|
30
|
-
console.log("\u2705 [AuthContext] \u4F1A\u8BDD\u9A8C\u8BC1\u6210\u529F, \u7528\u6237:",
|
|
31
|
-
setUser(
|
|
39
|
+
if (resolvedValid && resolvedUser) {
|
|
40
|
+
console.log("\u2705 [AuthContext] \u4F1A\u8BDD\u9A8C\u8BC1\u6210\u529F, \u7528\u6237:", resolvedUser);
|
|
41
|
+
setUser(resolvedUser);
|
|
32
42
|
setIsAuthenticated(true);
|
|
33
43
|
} else {
|
|
34
44
|
console.log("\u274C [AuthContext] \u4F1A\u8BDD\u9A8C\u8BC1\u5931\u8D25:", data.message);
|
|
@@ -59,9 +69,10 @@ function AuthProvider({ children }) {
|
|
|
59
69
|
console.log("\u{1F4E1} [AuthContext] \u6536\u5230\u54CD\u5E94\uFF0C\u72B6\u6001\u7801:", response.status);
|
|
60
70
|
const data = await response.json();
|
|
61
71
|
console.log("\u{1F4C4} [AuthContext] \u54CD\u5E94\u6570\u636E:", data);
|
|
62
|
-
|
|
72
|
+
const resolvedUser = extractUser(data);
|
|
73
|
+
if (data.success && resolvedUser) {
|
|
63
74
|
console.log("\u2705 [AuthContext] \u767B\u5F55\u6210\u529F, \u5F00\u59CB\u66F4\u65B0\u5168\u5C40\u72B6\u6001");
|
|
64
|
-
console.log("\u{1F464} [AuthContext] \u7528\u6237\u6570\u636E:",
|
|
75
|
+
console.log("\u{1F464} [AuthContext] \u7528\u6237\u6570\u636E:", resolvedUser);
|
|
65
76
|
console.log("\u{1F4CA} [AuthContext] \u66F4\u65B0\u524D\u72B6\u6001:", {
|
|
66
77
|
currentUser: user ? `${user.name || "\u672A\u8BBE\u7F6E"} (${user.phone})` : null,
|
|
67
78
|
currentIsAuthenticated: isAuthenticated,
|
|
@@ -69,8 +80,8 @@ function AuthProvider({ children }) {
|
|
|
69
80
|
});
|
|
70
81
|
console.log("\u{1F504} [AuthContext] \u6267\u884C\u5168\u5C40\u72B6\u6001\u66F4\u65B0...");
|
|
71
82
|
safeSetState(() => {
|
|
72
|
-
console.log("\u{1F504} [AuthContext] \u6B63\u5728\u8BBE\u7F6E\u7528\u6237:",
|
|
73
|
-
setUser(
|
|
83
|
+
console.log("\u{1F504} [AuthContext] \u6B63\u5728\u8BBE\u7F6E\u7528\u6237:", resolvedUser);
|
|
84
|
+
setUser(resolvedUser);
|
|
74
85
|
console.log("\u{1F504} [AuthContext] \u6B63\u5728\u8BBE\u7F6E\u8BA4\u8BC1\u72B6\u6001: true");
|
|
75
86
|
setIsAuthenticated(true);
|
|
76
87
|
console.log("\u{1F504} [AuthContext] \u6B63\u5728\u8BBE\u7F6E\u52A0\u8F7D\u72B6\u6001: false");
|
|
@@ -79,12 +90,12 @@ function AuthProvider({ children }) {
|
|
|
79
90
|
});
|
|
80
91
|
setTimeout(() => {
|
|
81
92
|
console.log("\u{1F389} [AuthContext] \u5EF6\u8FDF\u786E\u8BA4 - \u5168\u5C40\u767B\u5F55\u72B6\u6001\u5E94\u8BE5\u5DF2\u66F4\u65B0:", {
|
|
82
|
-
user:
|
|
93
|
+
user: resolvedUser,
|
|
83
94
|
isAuthenticated: true
|
|
84
95
|
});
|
|
85
96
|
}, 0);
|
|
86
97
|
console.log("\u{1F680} [AuthContext] \u8FD4\u56DE\u6210\u529F\u7ED3\u679C");
|
|
87
|
-
return { success: true, user:
|
|
98
|
+
return { success: true, user: resolvedUser };
|
|
88
99
|
} else {
|
|
89
100
|
console.log("\u274C [AuthContext] \u767B\u5F55\u5931\u8D25:", data.message);
|
|
90
101
|
return { success: false, message: data.message };
|
|
@@ -104,15 +115,16 @@ function AuthProvider({ children }) {
|
|
|
104
115
|
});
|
|
105
116
|
const data = await response.json();
|
|
106
117
|
console.log("\u{1F4E1} [AuthContext] \u6CE8\u518C\u54CD\u5E94:", data);
|
|
107
|
-
|
|
118
|
+
const resolvedUser = extractUser(data);
|
|
119
|
+
if (data.success && resolvedUser) {
|
|
108
120
|
console.log("\u2705 [AuthContext] \u6CE8\u518C\u6210\u529F, \u7ACB\u5373\u66F4\u65B0\u5168\u5C40\u72B6\u6001");
|
|
109
121
|
safeSetState(() => {
|
|
110
|
-
setUser(
|
|
122
|
+
setUser(resolvedUser);
|
|
111
123
|
setIsAuthenticated(true);
|
|
112
124
|
setLoading(false);
|
|
113
125
|
});
|
|
114
126
|
console.log("\u{1F680} [AuthContext] \u8FD4\u56DE\u6CE8\u518C\u6210\u529F\u7ED3\u679C");
|
|
115
|
-
return { success: true, user:
|
|
127
|
+
return { success: true, user: resolvedUser };
|
|
116
128
|
} else {
|
|
117
129
|
console.log("\u274C [AuthContext] \u6CE8\u518C\u5931\u8D25:", data.message);
|
|
118
130
|
return { success: false, message: data.message };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/auth/legacy/contexts/AuthContext.tsx","../../../../src/auth/legacy/types/index.ts","../../../../src/auth/legacy/utils/authUtils.ts"],"names":["createContext","useState","useRef","useCallback","useEffect","React","useContext","UserRole"],"mappings":"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","file":"index.js","sourcesContent":["'use client';\n\nimport React, { createContext, useContext, useState, useEffect, useCallback, useRef } from 'react';\nimport type { User, UseAuthReturn, LoginRequest, RegisterRequest } from '../types';\n\ninterface AuthContextType extends UseAuthReturn {}\n\nconst AuthContext = createContext<AuthContextType | undefined>(undefined);\n\nexport function AuthProvider({ children }: { children: React.ReactNode }) {\n const [user, setUser] = useState<User | null>(null);\n const [loading, setLoading] = useState(true);\n const [isAuthenticated, setIsAuthenticated] = useState(false);\n const isMountedRef = useRef(true);\n\n // 安全的状态更新函数\n const safeSetState = useCallback((updater: () => void) => {\n if (isMountedRef.current) {\n updater();\n }\n }, []);\n\n // 验证会话\n const validateSession = useCallback(async () => {\n console.log('🔍 [AuthContext] 开始验证会话...');\n try {\n const response = await fetch('/api/auth/validate');\n console.log('📡 [AuthContext] 会话验证响应状态:', response.status);\n \n const data = await response.json();\n console.log('📄 [AuthContext] 会话验证响应数据:', data);\n \n safeSetState(() => {\n if (data.valid && data.user) {\n console.log('✅ [AuthContext] 会话验证成功, 用户:', data.user);\n setUser(data.user);\n setIsAuthenticated(true);\n } else {\n console.log('❌ [AuthContext] 会话验证失败:', data.message);\n setUser(null);\n setIsAuthenticated(false);\n }\n setLoading(false);\n });\n } catch (error) {\n console.error('💥 [AuthContext] 会话验证异常:', error);\n safeSetState(() => {\n setUser(null);\n setIsAuthenticated(false);\n setLoading(false);\n });\n }\n }, [safeSetState]);\n\n // 登录\n const login = useCallback(async (credentials: LoginRequest) => {\n console.log('🔑 [AuthContext] 开始登录...');\n console.log('📝 [AuthContext] 登录凭据:', { phone: credentials.phone, password: '***' });\n \n try {\n console.log('📤 [AuthContext] 发送登录请求到 /api/auth/login');\n const response = await fetch('/api/auth/login', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(credentials),\n });\n\n console.log('📡 [AuthContext] 收到响应,状态码:', response.status);\n const data = await response.json();\n console.log('📄 [AuthContext] 响应数据:', data);\n\n if (data.success && data.user) {\n console.log('✅ [AuthContext] 登录成功, 开始更新全局状态');\n console.log('👤 [AuthContext] 用户数据:', data.user);\n \n // 记录当前状态\n console.log('📊 [AuthContext] 更新前状态:', {\n currentUser: user ? `${user.name || '未设置'} (${user.phone})` : null,\n currentIsAuthenticated: isAuthenticated,\n currentLoading: loading\n });\n \n // 使用同步的状态更新确保立即生效\n console.log('🔄 [AuthContext] 执行全局状态更新...');\n safeSetState(() => {\n console.log('🔄 [AuthContext] 正在设置用户:', data.user);\n setUser(data.user);\n console.log('🔄 [AuthContext] 正在设置认证状态: true');\n setIsAuthenticated(true);\n console.log('🔄 [AuthContext] 正在设置加载状态: false');\n setLoading(false);\n console.log('✅ [AuthContext] 全局状态更新完成');\n });\n \n // 等待下一个事件循环后输出确认日志\n setTimeout(() => {\n console.log('🎉 [AuthContext] 延迟确认 - 全局登录状态应该已更新:', {\n user: data.user,\n isAuthenticated: true\n });\n }, 0);\n \n console.log('🚀 [AuthContext] 返回成功结果');\n return { success: true, user: data.user };\n } else {\n console.log('❌ [AuthContext] 登录失败:', data.message);\n return { success: false, message: data.message };\n }\n } catch (error) {\n console.error('💥 [AuthContext] 登录异常:', error);\n return { success: false, message: '登录失败,请稍后重试' };\n }\n }, [safeSetState, user, isAuthenticated, loading]);\n\n // 注册\n const register = useCallback(async (userData: RegisterRequest) => {\n console.log('📝 [AuthContext] 开始注册...');\n try {\n const response = await fetch('/api/auth/register', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(userData),\n });\n\n const data = await response.json();\n console.log('📡 [AuthContext] 注册响应:', data);\n\n if (data.success && data.user) {\n console.log('✅ [AuthContext] 注册成功, 立即更新全局状态');\n \n // 使用同步的状态更新确保立即生效\n safeSetState(() => {\n setUser(data.user);\n setIsAuthenticated(true);\n setLoading(false);\n });\n \n console.log('🚀 [AuthContext] 返回注册成功结果');\n return { success: true, user: data.user };\n } else {\n console.log('❌ [AuthContext] 注册失败:', data.message);\n return { success: false, message: data.message };\n }\n } catch (error) {\n console.error('💥 [AuthContext] 注册异常:', error);\n return { success: false, message: '注册失败,请稍后重试' };\n }\n }, [safeSetState]);\n\n // 登出\n const logout = useCallback(async () => {\n console.log('🚪 [AuthContext] 开始登出...');\n try {\n await fetch('/api/auth/logout', { method: 'POST' });\n safeSetState(() => {\n setUser(null);\n setIsAuthenticated(false);\n });\n console.log('✅ [AuthContext] 登出成功, 全局状态已清除');\n } catch (error) {\n console.error('💥 [AuthContext] 登出失败:', error);\n }\n }, [safeSetState]);\n\n // 刷新用户信息\n const refreshUser = useCallback(() => {\n console.log('🔄 [AuthContext] 刷新用户信息...');\n setLoading(true);\n validateSession();\n }, [validateSession]);\n\n // 组件挂载/卸载管理\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n };\n }, []);\n\n // 初始化时验证会话\n useEffect(() => {\n console.log('🚀 [AuthContext] 初始化, 开始验证会话');\n validateSession();\n }, [validateSession]);\n\n // 状态变化监控(用于调试)\n useEffect(() => {\n console.log('📊 [AuthContext] 全局状态变化:', {\n isAuthenticated,\n user: user ? `${user.name || '未设置'} (${user.phone})` : null,\n loading\n });\n }, [isAuthenticated, user, loading]);\n\n const value: AuthContextType = {\n user,\n loading,\n isAuthenticated,\n login,\n register,\n logout,\n refreshUser,\n };\n\n return (\n <AuthContext.Provider value={value}>\n {children}\n </AuthContext.Provider>\n );\n}\n\nexport function useAuth(): UseAuthReturn {\n const context = useContext(AuthContext);\n if (context === undefined) {\n throw new Error('useAuth must be used within an AuthProvider');\n }\n return context;\n} ","// ===== 用户相关类型 =====\n\n/**\n * 用户信息接口\n */\nexport interface User {\n id: number;\n phone: string;\n name?: string | null;\n email?: string | null;\n role: string;\n isActive: boolean;\n lastLoginAt?: Date | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\n/**\n * 用户会话接口\n */\nexport interface UserSession {\n id: number;\n userId: number;\n sessionToken: string;\n expiresAt: Date;\n createdAt: Date;\n}\n\n// ===== 请求/响应类型 =====\n\n/**\n * 登录请求接口\n */\nexport interface LoginRequest {\n phone: string;\n password: string;\n}\n\n/**\n * 注册请求接口\n */\nexport interface RegisterRequest {\n phone: string;\n password: string;\n name?: string;\n}\n\n/**\n * 登录响应接口\n */\nexport interface LoginResponse {\n success: boolean;\n message: string;\n user?: User;\n sessionToken?: string;\n}\n\n/**\n * 注册响应接口\n */\nexport interface RegisterResponse {\n success: boolean;\n message: string;\n user?: User;\n sessionToken?: string;\n}\n\n/**\n * 会话验证响应接口\n */\nexport interface SessionValidationResponse {\n valid: boolean;\n user?: User;\n message?: string;\n}\n\n/**\n * 会话验证结果接口\n */\nexport interface SessionValidation {\n valid: boolean;\n user?: User;\n}\n\n// ===== 组件Props类型 =====\n\n/**\n * 登录模态框Props\n */\nexport interface LoginModalProps {\n isOpen: boolean;\n onClose: () => void;\n onSuccess: () => void;\n onSwitchToRegister?: () => void;\n}\n\n/**\n * 注册模态框Props\n */\nexport interface RegisterModalProps {\n isOpen: boolean;\n onClose: () => void;\n onSuccess: () => void;\n onSwitchToLogin?: () => void;\n}\n\n/**\n * 认证守卫Props\n */\nexport interface AuthGuardProps {\n children: React.ReactNode;\n fallback?: React.ReactNode;\n requireAuth?: boolean;\n}\n\n/**\n * 自定义菜单项接口\n */\nexport interface CustomMenuItem {\n id: string;\n label: string;\n icon?: React.ComponentType<any>;\n onClick: () => void;\n requireAuth?: boolean; // 是否需要登录才显示\n}\n\n/**\n * 用户菜单Props\n */\nexport interface UserMenuProps {\n customMenuItems?: CustomMenuItem[]; // 自定义菜单项\n className?: string; // 自定义样式类名\n}\n\n/**\n * 忘记密码模态框Props\n */\nexport interface ForgotPasswordModalProps {\n isOpen: boolean;\n onClose: () => void;\n onSuccess: () => void;\n}\n\n// ===== Hook返回类型 =====\n\n/**\n * useAuth Hook返回值类型\n */\nexport interface UseAuthReturn {\n user: User | null;\n loading: boolean;\n isAuthenticated: boolean;\n login: (credentials: LoginRequest) => Promise<{ success: boolean; user?: User; message?: string }>;\n register: (userData: RegisterRequest) => Promise<{ success: boolean; user?: User; message?: string }>;\n logout: () => Promise<void>;\n refreshUser: () => void;\n}\n\n// ===== 服务相关类型 =====\n\n/**\n * 认证服务接口\n */\nexport interface AuthService {\n verifyPassword(phone: string, password: string): Promise<User | null>;\n createUser(phone: string, password: string, name?: string): Promise<User>;\n createSession(userId: number): Promise<UserSession>;\n validateSession(sessionToken: string): Promise<SessionValidation>;\n deleteSession(sessionToken: string): Promise<void>;\n deleteUserSessions(userId: number): Promise<void>;\n updateLastLogin(userId: number): Promise<void>;\n cleanupExpiredSessions(): Promise<void>;\n getUserByPhone(phone: string): Promise<User | null>;\n sendVerificationCode(phone: string): Promise<string>;\n verifyCode(phone: string, code: string): Promise<boolean>;\n resetPassword(phone: string, newPassword: string): Promise<void>;\n cleanupExpiredVerificationCodes(): Promise<void>;\n}\n\n// ===== 工具函数类型 =====\n\n/**\n * API权限验证函数类型\n */\nexport type ValidateApiAuth = (request: Request) => Promise<User | null>;\n\n// ===== 常量类型 =====\n\n/**\n * 用户角色枚举\n */\nexport enum UserRole {\n USER = 'user',\n ADMIN = 'admin'\n}\n\n/**\n * 会话配置\n */\nexport interface SessionConfig {\n maxAge: number; // 会话最大存活时间(秒)\n cookieName: string; // Cookie名称\n secure: boolean; // 是否使用安全Cookie\n httpOnly: boolean; // 是否仅HTTP访问\n sameSite: 'strict' | 'lax' | 'none'; // SameSite策略\n} ","import type { User } from '../types';\n\n/**\n * 验证手机号格式\n */\nexport function validatePhoneNumber(phone: string): boolean {\n return /^1[3-9]\\d{9}$/.test(phone);\n}\n\n/**\n * 验证密码强度(可扩展)\n */\nexport function validatePassword(password: string): { valid: boolean; message?: string } {\n if (!password) {\n return { valid: false, message: '密码不能为空' };\n }\n \n if (password.length < 6) {\n return { valid: false, message: '密码长度至少6位' };\n }\n \n return { valid: true };\n}\n\n/**\n * 生成安全的会话令牌\n */\nexport function generateSessionToken(): string {\n // 在实际环境中,应该使用更安全的随机数生成\n return Math.random().toString(36).substring(2) + \n Date.now().toString(36) + \n Math.random().toString(36).substring(2);\n}\n\n/**\n * 检查用户是否为管理员\n */\nexport function isAdmin(user: User | null): boolean {\n return user?.role === 'admin';\n}\n\n/**\n * 检查用户是否处于活跃状态\n */\nexport function isActiveUser(user: User | null): boolean {\n return user?.isActive === true;\n}\n\n/**\n * 格式化用户显示名称\n */\nexport function getUserDisplayName(user: User): string {\n return user.name || user.phone || '未知用户';\n}\n\n/**\n * 计算会话过期时间\n */\nexport function calculateSessionExpiry(days: number = 30): Date {\n return new Date(Date.now() + days * 24 * 60 * 60 * 1000);\n}\n\n/**\n * 检查会话是否过期\n */\nexport function isSessionExpired(expiresAt: Date): boolean {\n return new Date() > new Date(expiresAt);\n} "]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/auth/legacy/contexts/AuthContext.tsx","../../../../src/auth/legacy/types/index.ts","../../../../src/auth/legacy/utils/authUtils.ts"],"names":["createContext","useState","useRef","useCallback","useEffect","React","useContext","UserRole"],"mappings":"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","file":"index.js","sourcesContent":["'use client';\n\nimport React, { createContext, useContext, useState, useEffect, useCallback, useRef } from 'react';\nimport type { User, UseAuthReturn, LoginRequest, RegisterRequest } from '../types';\n\ninterface AuthContextType extends UseAuthReturn {}\n\nconst AuthContext = createContext<AuthContextType | undefined>(undefined);\n\nfunction extractUser(data: any): User | null {\n return data?.user ?? data?.data?.user ?? null;\n}\n\nfunction extractValid(data: any): boolean {\n if (typeof data?.valid === 'boolean') return data.valid;\n if (typeof data?.data?.valid === 'boolean') return data.data.valid;\n return false;\n}\n\nexport function AuthProvider({ children }: { children: React.ReactNode }) {\n const [user, setUser] = useState<User | null>(null);\n const [loading, setLoading] = useState(true);\n const [isAuthenticated, setIsAuthenticated] = useState(false);\n const isMountedRef = useRef(true);\n\n // 安全的状态更新函数\n const safeSetState = useCallback((updater: () => void) => {\n if (isMountedRef.current) {\n updater();\n }\n }, []);\n\n // 验证会话\n const validateSession = useCallback(async () => {\n console.log('🔍 [AuthContext] 开始验证会话...');\n try {\n const response = await fetch('/api/auth/validate');\n console.log('📡 [AuthContext] 会话验证响应状态:', response.status);\n \n const data = await response.json();\n console.log('📄 [AuthContext] 会话验证响应数据:', data);\n const resolvedUser = extractUser(data);\n const resolvedValid = extractValid(data);\n \n safeSetState(() => {\n if (resolvedValid && resolvedUser) {\n console.log('✅ [AuthContext] 会话验证成功, 用户:', resolvedUser);\n setUser(resolvedUser);\n setIsAuthenticated(true);\n } else {\n console.log('❌ [AuthContext] 会话验证失败:', data.message);\n setUser(null);\n setIsAuthenticated(false);\n }\n setLoading(false);\n });\n } catch (error) {\n console.error('💥 [AuthContext] 会话验证异常:', error);\n safeSetState(() => {\n setUser(null);\n setIsAuthenticated(false);\n setLoading(false);\n });\n }\n }, [safeSetState]);\n\n // 登录\n const login = useCallback(async (credentials: LoginRequest) => {\n console.log('🔑 [AuthContext] 开始登录...');\n console.log('📝 [AuthContext] 登录凭据:', { phone: credentials.phone, password: '***' });\n \n try {\n console.log('📤 [AuthContext] 发送登录请求到 /api/auth/login');\n const response = await fetch('/api/auth/login', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(credentials),\n });\n\n console.log('📡 [AuthContext] 收到响应,状态码:', response.status);\n const data = await response.json();\n console.log('📄 [AuthContext] 响应数据:', data);\n const resolvedUser = extractUser(data);\n\n if (data.success && resolvedUser) {\n console.log('✅ [AuthContext] 登录成功, 开始更新全局状态');\n console.log('👤 [AuthContext] 用户数据:', resolvedUser);\n \n // 记录当前状态\n console.log('📊 [AuthContext] 更新前状态:', {\n currentUser: user ? `${user.name || '未设置'} (${user.phone})` : null,\n currentIsAuthenticated: isAuthenticated,\n currentLoading: loading\n });\n \n // 使用同步的状态更新确保立即生效\n console.log('🔄 [AuthContext] 执行全局状态更新...');\n safeSetState(() => {\n console.log('🔄 [AuthContext] 正在设置用户:', resolvedUser);\n setUser(resolvedUser);\n console.log('🔄 [AuthContext] 正在设置认证状态: true');\n setIsAuthenticated(true);\n console.log('🔄 [AuthContext] 正在设置加载状态: false');\n setLoading(false);\n console.log('✅ [AuthContext] 全局状态更新完成');\n });\n \n // 等待下一个事件循环后输出确认日志\n setTimeout(() => {\n console.log('🎉 [AuthContext] 延迟确认 - 全局登录状态应该已更新:', {\n user: resolvedUser,\n isAuthenticated: true\n });\n }, 0);\n \n console.log('🚀 [AuthContext] 返回成功结果');\n return { success: true, user: resolvedUser };\n } else {\n console.log('❌ [AuthContext] 登录失败:', data.message);\n return { success: false, message: data.message };\n }\n } catch (error) {\n console.error('💥 [AuthContext] 登录异常:', error);\n return { success: false, message: '登录失败,请稍后重试' };\n }\n }, [safeSetState, user, isAuthenticated, loading]);\n\n // 注册\n const register = useCallback(async (userData: RegisterRequest) => {\n console.log('📝 [AuthContext] 开始注册...');\n try {\n const response = await fetch('/api/auth/register', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(userData),\n });\n\n const data = await response.json();\n console.log('📡 [AuthContext] 注册响应:', data);\n const resolvedUser = extractUser(data);\n\n if (data.success && resolvedUser) {\n console.log('✅ [AuthContext] 注册成功, 立即更新全局状态');\n \n // 使用同步的状态更新确保立即生效\n safeSetState(() => {\n setUser(resolvedUser);\n setIsAuthenticated(true);\n setLoading(false);\n });\n \n console.log('🚀 [AuthContext] 返回注册成功结果');\n return { success: true, user: resolvedUser };\n } else {\n console.log('❌ [AuthContext] 注册失败:', data.message);\n return { success: false, message: data.message };\n }\n } catch (error) {\n console.error('💥 [AuthContext] 注册异常:', error);\n return { success: false, message: '注册失败,请稍后重试' };\n }\n }, [safeSetState]);\n\n // 登出\n const logout = useCallback(async () => {\n console.log('🚪 [AuthContext] 开始登出...');\n try {\n await fetch('/api/auth/logout', { method: 'POST' });\n safeSetState(() => {\n setUser(null);\n setIsAuthenticated(false);\n });\n console.log('✅ [AuthContext] 登出成功, 全局状态已清除');\n } catch (error) {\n console.error('💥 [AuthContext] 登出失败:', error);\n }\n }, [safeSetState]);\n\n // 刷新用户信息\n const refreshUser = useCallback(() => {\n console.log('🔄 [AuthContext] 刷新用户信息...');\n setLoading(true);\n validateSession();\n }, [validateSession]);\n\n // 组件挂载/卸载管理\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n };\n }, []);\n\n // 初始化时验证会话\n useEffect(() => {\n console.log('🚀 [AuthContext] 初始化, 开始验证会话');\n validateSession();\n }, [validateSession]);\n\n // 状态变化监控(用于调试)\n useEffect(() => {\n console.log('📊 [AuthContext] 全局状态变化:', {\n isAuthenticated,\n user: user ? `${user.name || '未设置'} (${user.phone})` : null,\n loading\n });\n }, [isAuthenticated, user, loading]);\n\n const value: AuthContextType = {\n user,\n loading,\n isAuthenticated,\n login,\n register,\n logout,\n refreshUser,\n };\n\n return (\n <AuthContext.Provider value={value}>\n {children}\n </AuthContext.Provider>\n );\n}\n\nexport function useAuth(): UseAuthReturn {\n const context = useContext(AuthContext);\n if (context === undefined) {\n throw new Error('useAuth must be used within an AuthProvider');\n }\n return context;\n} \n","// ===== 用户相关类型 =====\n\n/**\n * 用户信息接口\n */\nexport interface User {\n id: number;\n phone: string;\n name?: string | null;\n email?: string | null;\n role: string;\n isActive: boolean;\n lastLoginAt?: Date | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\n/**\n * 用户会话接口\n */\nexport interface UserSession {\n id: number;\n userId: number;\n sessionToken: string;\n expiresAt: Date;\n createdAt: Date;\n}\n\n// ===== 请求/响应类型 =====\n\n/**\n * 登录请求接口\n */\nexport interface LoginRequest {\n phone: string;\n password: string;\n}\n\n/**\n * 注册请求接口\n */\nexport interface RegisterRequest {\n phone: string;\n password: string;\n name?: string;\n}\n\n/**\n * 登录响应接口\n */\nexport interface LoginResponse {\n success: boolean;\n message: string;\n user?: User;\n sessionToken?: string;\n}\n\n/**\n * 注册响应接口\n */\nexport interface RegisterResponse {\n success: boolean;\n message: string;\n user?: User;\n sessionToken?: string;\n}\n\n/**\n * 会话验证响应接口\n */\nexport interface SessionValidationResponse {\n valid: boolean;\n user?: User;\n message?: string;\n}\n\n/**\n * 会话验证结果接口\n */\nexport interface SessionValidation {\n valid: boolean;\n user?: User;\n}\n\n// ===== 组件Props类型 =====\n\n/**\n * 登录模态框Props\n */\nexport interface LoginModalProps {\n isOpen: boolean;\n onClose: () => void;\n onSuccess: () => void;\n onSwitchToRegister?: () => void;\n}\n\n/**\n * 注册模态框Props\n */\nexport interface RegisterModalProps {\n isOpen: boolean;\n onClose: () => void;\n onSuccess: () => void;\n onSwitchToLogin?: () => void;\n}\n\n/**\n * 认证守卫Props\n */\nexport interface AuthGuardProps {\n children: React.ReactNode;\n fallback?: React.ReactNode;\n requireAuth?: boolean;\n}\n\n/**\n * 自定义菜单项接口\n */\nexport interface CustomMenuItem {\n id: string;\n label: string;\n icon?: React.ComponentType<any>;\n onClick: () => void;\n requireAuth?: boolean; // 是否需要登录才显示\n}\n\n/**\n * 用户菜单Props\n */\nexport interface UserMenuProps {\n customMenuItems?: CustomMenuItem[]; // 自定义菜单项\n className?: string; // 自定义样式类名\n}\n\n/**\n * 忘记密码模态框Props\n */\nexport interface ForgotPasswordModalProps {\n isOpen: boolean;\n onClose: () => void;\n onSuccess: () => void;\n}\n\n// ===== Hook返回类型 =====\n\n/**\n * useAuth Hook返回值类型\n */\nexport interface UseAuthReturn {\n user: User | null;\n loading: boolean;\n isAuthenticated: boolean;\n login: (credentials: LoginRequest) => Promise<{ success: boolean; user?: User; message?: string }>;\n register: (userData: RegisterRequest) => Promise<{ success: boolean; user?: User; message?: string }>;\n logout: () => Promise<void>;\n refreshUser: () => void;\n}\n\n// ===== 服务相关类型 =====\n\n/**\n * 认证服务接口\n */\nexport interface AuthService {\n verifyPassword(phone: string, password: string): Promise<User | null>;\n createUser(phone: string, password: string, name?: string): Promise<User>;\n createSession(userId: number): Promise<UserSession>;\n validateSession(sessionToken: string): Promise<SessionValidation>;\n deleteSession(sessionToken: string): Promise<void>;\n deleteUserSessions(userId: number): Promise<void>;\n updateLastLogin(userId: number): Promise<void>;\n cleanupExpiredSessions(): Promise<void>;\n getUserByPhone(phone: string): Promise<User | null>;\n sendVerificationCode(phone: string): Promise<string>;\n verifyCode(phone: string, code: string): Promise<boolean>;\n resetPassword(phone: string, newPassword: string): Promise<void>;\n cleanupExpiredVerificationCodes(): Promise<void>;\n}\n\n// ===== 工具函数类型 =====\n\n/**\n * API权限验证函数类型\n */\nexport type ValidateApiAuth = (request: Request) => Promise<User | null>;\n\n// ===== 常量类型 =====\n\n/**\n * 用户角色枚举\n */\nexport enum UserRole {\n USER = 'user',\n ADMIN = 'admin'\n}\n\n/**\n * 会话配置\n */\nexport interface SessionConfig {\n maxAge: number; // 会话最大存活时间(秒)\n cookieName: string; // Cookie名称\n secure: boolean; // 是否使用安全Cookie\n httpOnly: boolean; // 是否仅HTTP访问\n sameSite: 'strict' | 'lax' | 'none'; // SameSite策略\n} ","import type { User } from '../types';\n\n/**\n * 验证手机号格式\n */\nexport function validatePhoneNumber(phone: string): boolean {\n return /^1[3-9]\\d{9}$/.test(phone);\n}\n\n/**\n * 验证密码强度(可扩展)\n */\nexport function validatePassword(password: string): { valid: boolean; message?: string } {\n if (!password) {\n return { valid: false, message: '密码不能为空' };\n }\n \n if (password.length < 6) {\n return { valid: false, message: '密码长度至少6位' };\n }\n \n return { valid: true };\n}\n\n/**\n * 生成安全的会话令牌\n */\nexport function generateSessionToken(): string {\n // 在实际环境中,应该使用更安全的随机数生成\n return Math.random().toString(36).substring(2) + \n Date.now().toString(36) + \n Math.random().toString(36).substring(2);\n}\n\n/**\n * 检查用户是否为管理员\n */\nexport function isAdmin(user: User | null): boolean {\n return user?.role === 'admin';\n}\n\n/**\n * 检查用户是否处于活跃状态\n */\nexport function isActiveUser(user: User | null): boolean {\n return user?.isActive === true;\n}\n\n/**\n * 格式化用户显示名称\n */\nexport function getUserDisplayName(user: User): string {\n return user.name || user.phone || '未知用户';\n}\n\n/**\n * 计算会话过期时间\n */\nexport function calculateSessionExpiry(days: number = 30): Date {\n return new Date(Date.now() + days * 24 * 60 * 60 * 1000);\n}\n\n/**\n * 检查会话是否过期\n */\nexport function isSessionExpired(expiresAt: Date): boolean {\n return new Date() > new Date(expiresAt);\n} "]}
|
|
@@ -2,6 +2,14 @@ import React, { createContext, useState, useRef, useCallback, useEffect, useCont
|
|
|
2
2
|
|
|
3
3
|
// src/auth/legacy/contexts/AuthContext.tsx
|
|
4
4
|
var AuthContext = createContext(void 0);
|
|
5
|
+
function extractUser(data) {
|
|
6
|
+
return data?.user ?? data?.data?.user ?? null;
|
|
7
|
+
}
|
|
8
|
+
function extractValid(data) {
|
|
9
|
+
if (typeof data?.valid === "boolean") return data.valid;
|
|
10
|
+
if (typeof data?.data?.valid === "boolean") return data.data.valid;
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
5
13
|
function AuthProvider({ children }) {
|
|
6
14
|
const [user, setUser] = useState(null);
|
|
7
15
|
const [loading, setLoading] = useState(true);
|
|
@@ -19,10 +27,12 @@ function AuthProvider({ children }) {
|
|
|
19
27
|
console.log("\u{1F4E1} [AuthContext] \u4F1A\u8BDD\u9A8C\u8BC1\u54CD\u5E94\u72B6\u6001:", response.status);
|
|
20
28
|
const data = await response.json();
|
|
21
29
|
console.log("\u{1F4C4} [AuthContext] \u4F1A\u8BDD\u9A8C\u8BC1\u54CD\u5E94\u6570\u636E:", data);
|
|
30
|
+
const resolvedUser = extractUser(data);
|
|
31
|
+
const resolvedValid = extractValid(data);
|
|
22
32
|
safeSetState(() => {
|
|
23
|
-
if (
|
|
24
|
-
console.log("\u2705 [AuthContext] \u4F1A\u8BDD\u9A8C\u8BC1\u6210\u529F, \u7528\u6237:",
|
|
25
|
-
setUser(
|
|
33
|
+
if (resolvedValid && resolvedUser) {
|
|
34
|
+
console.log("\u2705 [AuthContext] \u4F1A\u8BDD\u9A8C\u8BC1\u6210\u529F, \u7528\u6237:", resolvedUser);
|
|
35
|
+
setUser(resolvedUser);
|
|
26
36
|
setIsAuthenticated(true);
|
|
27
37
|
} else {
|
|
28
38
|
console.log("\u274C [AuthContext] \u4F1A\u8BDD\u9A8C\u8BC1\u5931\u8D25:", data.message);
|
|
@@ -53,9 +63,10 @@ function AuthProvider({ children }) {
|
|
|
53
63
|
console.log("\u{1F4E1} [AuthContext] \u6536\u5230\u54CD\u5E94\uFF0C\u72B6\u6001\u7801:", response.status);
|
|
54
64
|
const data = await response.json();
|
|
55
65
|
console.log("\u{1F4C4} [AuthContext] \u54CD\u5E94\u6570\u636E:", data);
|
|
56
|
-
|
|
66
|
+
const resolvedUser = extractUser(data);
|
|
67
|
+
if (data.success && resolvedUser) {
|
|
57
68
|
console.log("\u2705 [AuthContext] \u767B\u5F55\u6210\u529F, \u5F00\u59CB\u66F4\u65B0\u5168\u5C40\u72B6\u6001");
|
|
58
|
-
console.log("\u{1F464} [AuthContext] \u7528\u6237\u6570\u636E:",
|
|
69
|
+
console.log("\u{1F464} [AuthContext] \u7528\u6237\u6570\u636E:", resolvedUser);
|
|
59
70
|
console.log("\u{1F4CA} [AuthContext] \u66F4\u65B0\u524D\u72B6\u6001:", {
|
|
60
71
|
currentUser: user ? `${user.name || "\u672A\u8BBE\u7F6E"} (${user.phone})` : null,
|
|
61
72
|
currentIsAuthenticated: isAuthenticated,
|
|
@@ -63,8 +74,8 @@ function AuthProvider({ children }) {
|
|
|
63
74
|
});
|
|
64
75
|
console.log("\u{1F504} [AuthContext] \u6267\u884C\u5168\u5C40\u72B6\u6001\u66F4\u65B0...");
|
|
65
76
|
safeSetState(() => {
|
|
66
|
-
console.log("\u{1F504} [AuthContext] \u6B63\u5728\u8BBE\u7F6E\u7528\u6237:",
|
|
67
|
-
setUser(
|
|
77
|
+
console.log("\u{1F504} [AuthContext] \u6B63\u5728\u8BBE\u7F6E\u7528\u6237:", resolvedUser);
|
|
78
|
+
setUser(resolvedUser);
|
|
68
79
|
console.log("\u{1F504} [AuthContext] \u6B63\u5728\u8BBE\u7F6E\u8BA4\u8BC1\u72B6\u6001: true");
|
|
69
80
|
setIsAuthenticated(true);
|
|
70
81
|
console.log("\u{1F504} [AuthContext] \u6B63\u5728\u8BBE\u7F6E\u52A0\u8F7D\u72B6\u6001: false");
|
|
@@ -73,12 +84,12 @@ function AuthProvider({ children }) {
|
|
|
73
84
|
});
|
|
74
85
|
setTimeout(() => {
|
|
75
86
|
console.log("\u{1F389} [AuthContext] \u5EF6\u8FDF\u786E\u8BA4 - \u5168\u5C40\u767B\u5F55\u72B6\u6001\u5E94\u8BE5\u5DF2\u66F4\u65B0:", {
|
|
76
|
-
user:
|
|
87
|
+
user: resolvedUser,
|
|
77
88
|
isAuthenticated: true
|
|
78
89
|
});
|
|
79
90
|
}, 0);
|
|
80
91
|
console.log("\u{1F680} [AuthContext] \u8FD4\u56DE\u6210\u529F\u7ED3\u679C");
|
|
81
|
-
return { success: true, user:
|
|
92
|
+
return { success: true, user: resolvedUser };
|
|
82
93
|
} else {
|
|
83
94
|
console.log("\u274C [AuthContext] \u767B\u5F55\u5931\u8D25:", data.message);
|
|
84
95
|
return { success: false, message: data.message };
|
|
@@ -98,15 +109,16 @@ function AuthProvider({ children }) {
|
|
|
98
109
|
});
|
|
99
110
|
const data = await response.json();
|
|
100
111
|
console.log("\u{1F4E1} [AuthContext] \u6CE8\u518C\u54CD\u5E94:", data);
|
|
101
|
-
|
|
112
|
+
const resolvedUser = extractUser(data);
|
|
113
|
+
if (data.success && resolvedUser) {
|
|
102
114
|
console.log("\u2705 [AuthContext] \u6CE8\u518C\u6210\u529F, \u7ACB\u5373\u66F4\u65B0\u5168\u5C40\u72B6\u6001");
|
|
103
115
|
safeSetState(() => {
|
|
104
|
-
setUser(
|
|
116
|
+
setUser(resolvedUser);
|
|
105
117
|
setIsAuthenticated(true);
|
|
106
118
|
setLoading(false);
|
|
107
119
|
});
|
|
108
120
|
console.log("\u{1F680} [AuthContext] \u8FD4\u56DE\u6CE8\u518C\u6210\u529F\u7ED3\u679C");
|
|
109
|
-
return { success: true, user:
|
|
121
|
+
return { success: true, user: resolvedUser };
|
|
110
122
|
} else {
|
|
111
123
|
console.log("\u274C [AuthContext] \u6CE8\u518C\u5931\u8D25:", data.message);
|
|
112
124
|
return { success: false, message: data.message };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/auth/legacy/contexts/AuthContext.tsx","../../../../src/auth/legacy/types/index.ts","../../../../src/auth/legacy/utils/authUtils.ts"],"names":["UserRole"],"mappings":"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","file":"index.mjs","sourcesContent":["'use client';\n\nimport React, { createContext, useContext, useState, useEffect, useCallback, useRef } from 'react';\nimport type { User, UseAuthReturn, LoginRequest, RegisterRequest } from '../types';\n\ninterface AuthContextType extends UseAuthReturn {}\n\nconst AuthContext = createContext<AuthContextType | undefined>(undefined);\n\nexport function AuthProvider({ children }: { children: React.ReactNode }) {\n const [user, setUser] = useState<User | null>(null);\n const [loading, setLoading] = useState(true);\n const [isAuthenticated, setIsAuthenticated] = useState(false);\n const isMountedRef = useRef(true);\n\n // 安全的状态更新函数\n const safeSetState = useCallback((updater: () => void) => {\n if (isMountedRef.current) {\n updater();\n }\n }, []);\n\n // 验证会话\n const validateSession = useCallback(async () => {\n console.log('🔍 [AuthContext] 开始验证会话...');\n try {\n const response = await fetch('/api/auth/validate');\n console.log('📡 [AuthContext] 会话验证响应状态:', response.status);\n \n const data = await response.json();\n console.log('📄 [AuthContext] 会话验证响应数据:', data);\n \n safeSetState(() => {\n if (data.valid && data.user) {\n console.log('✅ [AuthContext] 会话验证成功, 用户:', data.user);\n setUser(data.user);\n setIsAuthenticated(true);\n } else {\n console.log('❌ [AuthContext] 会话验证失败:', data.message);\n setUser(null);\n setIsAuthenticated(false);\n }\n setLoading(false);\n });\n } catch (error) {\n console.error('💥 [AuthContext] 会话验证异常:', error);\n safeSetState(() => {\n setUser(null);\n setIsAuthenticated(false);\n setLoading(false);\n });\n }\n }, [safeSetState]);\n\n // 登录\n const login = useCallback(async (credentials: LoginRequest) => {\n console.log('🔑 [AuthContext] 开始登录...');\n console.log('📝 [AuthContext] 登录凭据:', { phone: credentials.phone, password: '***' });\n \n try {\n console.log('📤 [AuthContext] 发送登录请求到 /api/auth/login');\n const response = await fetch('/api/auth/login', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(credentials),\n });\n\n console.log('📡 [AuthContext] 收到响应,状态码:', response.status);\n const data = await response.json();\n console.log('📄 [AuthContext] 响应数据:', data);\n\n if (data.success && data.user) {\n console.log('✅ [AuthContext] 登录成功, 开始更新全局状态');\n console.log('👤 [AuthContext] 用户数据:', data.user);\n \n // 记录当前状态\n console.log('📊 [AuthContext] 更新前状态:', {\n currentUser: user ? `${user.name || '未设置'} (${user.phone})` : null,\n currentIsAuthenticated: isAuthenticated,\n currentLoading: loading\n });\n \n // 使用同步的状态更新确保立即生效\n console.log('🔄 [AuthContext] 执行全局状态更新...');\n safeSetState(() => {\n console.log('🔄 [AuthContext] 正在设置用户:', data.user);\n setUser(data.user);\n console.log('🔄 [AuthContext] 正在设置认证状态: true');\n setIsAuthenticated(true);\n console.log('🔄 [AuthContext] 正在设置加载状态: false');\n setLoading(false);\n console.log('✅ [AuthContext] 全局状态更新完成');\n });\n \n // 等待下一个事件循环后输出确认日志\n setTimeout(() => {\n console.log('🎉 [AuthContext] 延迟确认 - 全局登录状态应该已更新:', {\n user: data.user,\n isAuthenticated: true\n });\n }, 0);\n \n console.log('🚀 [AuthContext] 返回成功结果');\n return { success: true, user: data.user };\n } else {\n console.log('❌ [AuthContext] 登录失败:', data.message);\n return { success: false, message: data.message };\n }\n } catch (error) {\n console.error('💥 [AuthContext] 登录异常:', error);\n return { success: false, message: '登录失败,请稍后重试' };\n }\n }, [safeSetState, user, isAuthenticated, loading]);\n\n // 注册\n const register = useCallback(async (userData: RegisterRequest) => {\n console.log('📝 [AuthContext] 开始注册...');\n try {\n const response = await fetch('/api/auth/register', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(userData),\n });\n\n const data = await response.json();\n console.log('📡 [AuthContext] 注册响应:', data);\n\n if (data.success && data.user) {\n console.log('✅ [AuthContext] 注册成功, 立即更新全局状态');\n \n // 使用同步的状态更新确保立即生效\n safeSetState(() => {\n setUser(data.user);\n setIsAuthenticated(true);\n setLoading(false);\n });\n \n console.log('🚀 [AuthContext] 返回注册成功结果');\n return { success: true, user: data.user };\n } else {\n console.log('❌ [AuthContext] 注册失败:', data.message);\n return { success: false, message: data.message };\n }\n } catch (error) {\n console.error('💥 [AuthContext] 注册异常:', error);\n return { success: false, message: '注册失败,请稍后重试' };\n }\n }, [safeSetState]);\n\n // 登出\n const logout = useCallback(async () => {\n console.log('🚪 [AuthContext] 开始登出...');\n try {\n await fetch('/api/auth/logout', { method: 'POST' });\n safeSetState(() => {\n setUser(null);\n setIsAuthenticated(false);\n });\n console.log('✅ [AuthContext] 登出成功, 全局状态已清除');\n } catch (error) {\n console.error('💥 [AuthContext] 登出失败:', error);\n }\n }, [safeSetState]);\n\n // 刷新用户信息\n const refreshUser = useCallback(() => {\n console.log('🔄 [AuthContext] 刷新用户信息...');\n setLoading(true);\n validateSession();\n }, [validateSession]);\n\n // 组件挂载/卸载管理\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n };\n }, []);\n\n // 初始化时验证会话\n useEffect(() => {\n console.log('🚀 [AuthContext] 初始化, 开始验证会话');\n validateSession();\n }, [validateSession]);\n\n // 状态变化监控(用于调试)\n useEffect(() => {\n console.log('📊 [AuthContext] 全局状态变化:', {\n isAuthenticated,\n user: user ? `${user.name || '未设置'} (${user.phone})` : null,\n loading\n });\n }, [isAuthenticated, user, loading]);\n\n const value: AuthContextType = {\n user,\n loading,\n isAuthenticated,\n login,\n register,\n logout,\n refreshUser,\n };\n\n return (\n <AuthContext.Provider value={value}>\n {children}\n </AuthContext.Provider>\n );\n}\n\nexport function useAuth(): UseAuthReturn {\n const context = useContext(AuthContext);\n if (context === undefined) {\n throw new Error('useAuth must be used within an AuthProvider');\n }\n return context;\n} ","// ===== 用户相关类型 =====\n\n/**\n * 用户信息接口\n */\nexport interface User {\n id: number;\n phone: string;\n name?: string | null;\n email?: string | null;\n role: string;\n isActive: boolean;\n lastLoginAt?: Date | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\n/**\n * 用户会话接口\n */\nexport interface UserSession {\n id: number;\n userId: number;\n sessionToken: string;\n expiresAt: Date;\n createdAt: Date;\n}\n\n// ===== 请求/响应类型 =====\n\n/**\n * 登录请求接口\n */\nexport interface LoginRequest {\n phone: string;\n password: string;\n}\n\n/**\n * 注册请求接口\n */\nexport interface RegisterRequest {\n phone: string;\n password: string;\n name?: string;\n}\n\n/**\n * 登录响应接口\n */\nexport interface LoginResponse {\n success: boolean;\n message: string;\n user?: User;\n sessionToken?: string;\n}\n\n/**\n * 注册响应接口\n */\nexport interface RegisterResponse {\n success: boolean;\n message: string;\n user?: User;\n sessionToken?: string;\n}\n\n/**\n * 会话验证响应接口\n */\nexport interface SessionValidationResponse {\n valid: boolean;\n user?: User;\n message?: string;\n}\n\n/**\n * 会话验证结果接口\n */\nexport interface SessionValidation {\n valid: boolean;\n user?: User;\n}\n\n// ===== 组件Props类型 =====\n\n/**\n * 登录模态框Props\n */\nexport interface LoginModalProps {\n isOpen: boolean;\n onClose: () => void;\n onSuccess: () => void;\n onSwitchToRegister?: () => void;\n}\n\n/**\n * 注册模态框Props\n */\nexport interface RegisterModalProps {\n isOpen: boolean;\n onClose: () => void;\n onSuccess: () => void;\n onSwitchToLogin?: () => void;\n}\n\n/**\n * 认证守卫Props\n */\nexport interface AuthGuardProps {\n children: React.ReactNode;\n fallback?: React.ReactNode;\n requireAuth?: boolean;\n}\n\n/**\n * 自定义菜单项接口\n */\nexport interface CustomMenuItem {\n id: string;\n label: string;\n icon?: React.ComponentType<any>;\n onClick: () => void;\n requireAuth?: boolean; // 是否需要登录才显示\n}\n\n/**\n * 用户菜单Props\n */\nexport interface UserMenuProps {\n customMenuItems?: CustomMenuItem[]; // 自定义菜单项\n className?: string; // 自定义样式类名\n}\n\n/**\n * 忘记密码模态框Props\n */\nexport interface ForgotPasswordModalProps {\n isOpen: boolean;\n onClose: () => void;\n onSuccess: () => void;\n}\n\n// ===== Hook返回类型 =====\n\n/**\n * useAuth Hook返回值类型\n */\nexport interface UseAuthReturn {\n user: User | null;\n loading: boolean;\n isAuthenticated: boolean;\n login: (credentials: LoginRequest) => Promise<{ success: boolean; user?: User; message?: string }>;\n register: (userData: RegisterRequest) => Promise<{ success: boolean; user?: User; message?: string }>;\n logout: () => Promise<void>;\n refreshUser: () => void;\n}\n\n// ===== 服务相关类型 =====\n\n/**\n * 认证服务接口\n */\nexport interface AuthService {\n verifyPassword(phone: string, password: string): Promise<User | null>;\n createUser(phone: string, password: string, name?: string): Promise<User>;\n createSession(userId: number): Promise<UserSession>;\n validateSession(sessionToken: string): Promise<SessionValidation>;\n deleteSession(sessionToken: string): Promise<void>;\n deleteUserSessions(userId: number): Promise<void>;\n updateLastLogin(userId: number): Promise<void>;\n cleanupExpiredSessions(): Promise<void>;\n getUserByPhone(phone: string): Promise<User | null>;\n sendVerificationCode(phone: string): Promise<string>;\n verifyCode(phone: string, code: string): Promise<boolean>;\n resetPassword(phone: string, newPassword: string): Promise<void>;\n cleanupExpiredVerificationCodes(): Promise<void>;\n}\n\n// ===== 工具函数类型 =====\n\n/**\n * API权限验证函数类型\n */\nexport type ValidateApiAuth = (request: Request) => Promise<User | null>;\n\n// ===== 常量类型 =====\n\n/**\n * 用户角色枚举\n */\nexport enum UserRole {\n USER = 'user',\n ADMIN = 'admin'\n}\n\n/**\n * 会话配置\n */\nexport interface SessionConfig {\n maxAge: number; // 会话最大存活时间(秒)\n cookieName: string; // Cookie名称\n secure: boolean; // 是否使用安全Cookie\n httpOnly: boolean; // 是否仅HTTP访问\n sameSite: 'strict' | 'lax' | 'none'; // SameSite策略\n} ","import type { User } from '../types';\n\n/**\n * 验证手机号格式\n */\nexport function validatePhoneNumber(phone: string): boolean {\n return /^1[3-9]\\d{9}$/.test(phone);\n}\n\n/**\n * 验证密码强度(可扩展)\n */\nexport function validatePassword(password: string): { valid: boolean; message?: string } {\n if (!password) {\n return { valid: false, message: '密码不能为空' };\n }\n \n if (password.length < 6) {\n return { valid: false, message: '密码长度至少6位' };\n }\n \n return { valid: true };\n}\n\n/**\n * 生成安全的会话令牌\n */\nexport function generateSessionToken(): string {\n // 在实际环境中,应该使用更安全的随机数生成\n return Math.random().toString(36).substring(2) + \n Date.now().toString(36) + \n Math.random().toString(36).substring(2);\n}\n\n/**\n * 检查用户是否为管理员\n */\nexport function isAdmin(user: User | null): boolean {\n return user?.role === 'admin';\n}\n\n/**\n * 检查用户是否处于活跃状态\n */\nexport function isActiveUser(user: User | null): boolean {\n return user?.isActive === true;\n}\n\n/**\n * 格式化用户显示名称\n */\nexport function getUserDisplayName(user: User): string {\n return user.name || user.phone || '未知用户';\n}\n\n/**\n * 计算会话过期时间\n */\nexport function calculateSessionExpiry(days: number = 30): Date {\n return new Date(Date.now() + days * 24 * 60 * 60 * 1000);\n}\n\n/**\n * 检查会话是否过期\n */\nexport function isSessionExpired(expiresAt: Date): boolean {\n return new Date() > new Date(expiresAt);\n} "]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/auth/legacy/contexts/AuthContext.tsx","../../../../src/auth/legacy/types/index.ts","../../../../src/auth/legacy/utils/authUtils.ts"],"names":["UserRole"],"mappings":"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","file":"index.mjs","sourcesContent":["'use client';\n\nimport React, { createContext, useContext, useState, useEffect, useCallback, useRef } from 'react';\nimport type { User, UseAuthReturn, LoginRequest, RegisterRequest } from '../types';\n\ninterface AuthContextType extends UseAuthReturn {}\n\nconst AuthContext = createContext<AuthContextType | undefined>(undefined);\n\nfunction extractUser(data: any): User | null {\n return data?.user ?? data?.data?.user ?? null;\n}\n\nfunction extractValid(data: any): boolean {\n if (typeof data?.valid === 'boolean') return data.valid;\n if (typeof data?.data?.valid === 'boolean') return data.data.valid;\n return false;\n}\n\nexport function AuthProvider({ children }: { children: React.ReactNode }) {\n const [user, setUser] = useState<User | null>(null);\n const [loading, setLoading] = useState(true);\n const [isAuthenticated, setIsAuthenticated] = useState(false);\n const isMountedRef = useRef(true);\n\n // 安全的状态更新函数\n const safeSetState = useCallback((updater: () => void) => {\n if (isMountedRef.current) {\n updater();\n }\n }, []);\n\n // 验证会话\n const validateSession = useCallback(async () => {\n console.log('🔍 [AuthContext] 开始验证会话...');\n try {\n const response = await fetch('/api/auth/validate');\n console.log('📡 [AuthContext] 会话验证响应状态:', response.status);\n \n const data = await response.json();\n console.log('📄 [AuthContext] 会话验证响应数据:', data);\n const resolvedUser = extractUser(data);\n const resolvedValid = extractValid(data);\n \n safeSetState(() => {\n if (resolvedValid && resolvedUser) {\n console.log('✅ [AuthContext] 会话验证成功, 用户:', resolvedUser);\n setUser(resolvedUser);\n setIsAuthenticated(true);\n } else {\n console.log('❌ [AuthContext] 会话验证失败:', data.message);\n setUser(null);\n setIsAuthenticated(false);\n }\n setLoading(false);\n });\n } catch (error) {\n console.error('💥 [AuthContext] 会话验证异常:', error);\n safeSetState(() => {\n setUser(null);\n setIsAuthenticated(false);\n setLoading(false);\n });\n }\n }, [safeSetState]);\n\n // 登录\n const login = useCallback(async (credentials: LoginRequest) => {\n console.log('🔑 [AuthContext] 开始登录...');\n console.log('📝 [AuthContext] 登录凭据:', { phone: credentials.phone, password: '***' });\n \n try {\n console.log('📤 [AuthContext] 发送登录请求到 /api/auth/login');\n const response = await fetch('/api/auth/login', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(credentials),\n });\n\n console.log('📡 [AuthContext] 收到响应,状态码:', response.status);\n const data = await response.json();\n console.log('📄 [AuthContext] 响应数据:', data);\n const resolvedUser = extractUser(data);\n\n if (data.success && resolvedUser) {\n console.log('✅ [AuthContext] 登录成功, 开始更新全局状态');\n console.log('👤 [AuthContext] 用户数据:', resolvedUser);\n \n // 记录当前状态\n console.log('📊 [AuthContext] 更新前状态:', {\n currentUser: user ? `${user.name || '未设置'} (${user.phone})` : null,\n currentIsAuthenticated: isAuthenticated,\n currentLoading: loading\n });\n \n // 使用同步的状态更新确保立即生效\n console.log('🔄 [AuthContext] 执行全局状态更新...');\n safeSetState(() => {\n console.log('🔄 [AuthContext] 正在设置用户:', resolvedUser);\n setUser(resolvedUser);\n console.log('🔄 [AuthContext] 正在设置认证状态: true');\n setIsAuthenticated(true);\n console.log('🔄 [AuthContext] 正在设置加载状态: false');\n setLoading(false);\n console.log('✅ [AuthContext] 全局状态更新完成');\n });\n \n // 等待下一个事件循环后输出确认日志\n setTimeout(() => {\n console.log('🎉 [AuthContext] 延迟确认 - 全局登录状态应该已更新:', {\n user: resolvedUser,\n isAuthenticated: true\n });\n }, 0);\n \n console.log('🚀 [AuthContext] 返回成功结果');\n return { success: true, user: resolvedUser };\n } else {\n console.log('❌ [AuthContext] 登录失败:', data.message);\n return { success: false, message: data.message };\n }\n } catch (error) {\n console.error('💥 [AuthContext] 登录异常:', error);\n return { success: false, message: '登录失败,请稍后重试' };\n }\n }, [safeSetState, user, isAuthenticated, loading]);\n\n // 注册\n const register = useCallback(async (userData: RegisterRequest) => {\n console.log('📝 [AuthContext] 开始注册...');\n try {\n const response = await fetch('/api/auth/register', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(userData),\n });\n\n const data = await response.json();\n console.log('📡 [AuthContext] 注册响应:', data);\n const resolvedUser = extractUser(data);\n\n if (data.success && resolvedUser) {\n console.log('✅ [AuthContext] 注册成功, 立即更新全局状态');\n \n // 使用同步的状态更新确保立即生效\n safeSetState(() => {\n setUser(resolvedUser);\n setIsAuthenticated(true);\n setLoading(false);\n });\n \n console.log('🚀 [AuthContext] 返回注册成功结果');\n return { success: true, user: resolvedUser };\n } else {\n console.log('❌ [AuthContext] 注册失败:', data.message);\n return { success: false, message: data.message };\n }\n } catch (error) {\n console.error('💥 [AuthContext] 注册异常:', error);\n return { success: false, message: '注册失败,请稍后重试' };\n }\n }, [safeSetState]);\n\n // 登出\n const logout = useCallback(async () => {\n console.log('🚪 [AuthContext] 开始登出...');\n try {\n await fetch('/api/auth/logout', { method: 'POST' });\n safeSetState(() => {\n setUser(null);\n setIsAuthenticated(false);\n });\n console.log('✅ [AuthContext] 登出成功, 全局状态已清除');\n } catch (error) {\n console.error('💥 [AuthContext] 登出失败:', error);\n }\n }, [safeSetState]);\n\n // 刷新用户信息\n const refreshUser = useCallback(() => {\n console.log('🔄 [AuthContext] 刷新用户信息...');\n setLoading(true);\n validateSession();\n }, [validateSession]);\n\n // 组件挂载/卸载管理\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n };\n }, []);\n\n // 初始化时验证会话\n useEffect(() => {\n console.log('🚀 [AuthContext] 初始化, 开始验证会话');\n validateSession();\n }, [validateSession]);\n\n // 状态变化监控(用于调试)\n useEffect(() => {\n console.log('📊 [AuthContext] 全局状态变化:', {\n isAuthenticated,\n user: user ? `${user.name || '未设置'} (${user.phone})` : null,\n loading\n });\n }, [isAuthenticated, user, loading]);\n\n const value: AuthContextType = {\n user,\n loading,\n isAuthenticated,\n login,\n register,\n logout,\n refreshUser,\n };\n\n return (\n <AuthContext.Provider value={value}>\n {children}\n </AuthContext.Provider>\n );\n}\n\nexport function useAuth(): UseAuthReturn {\n const context = useContext(AuthContext);\n if (context === undefined) {\n throw new Error('useAuth must be used within an AuthProvider');\n }\n return context;\n} \n","// ===== 用户相关类型 =====\n\n/**\n * 用户信息接口\n */\nexport interface User {\n id: number;\n phone: string;\n name?: string | null;\n email?: string | null;\n role: string;\n isActive: boolean;\n lastLoginAt?: Date | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\n/**\n * 用户会话接口\n */\nexport interface UserSession {\n id: number;\n userId: number;\n sessionToken: string;\n expiresAt: Date;\n createdAt: Date;\n}\n\n// ===== 请求/响应类型 =====\n\n/**\n * 登录请求接口\n */\nexport interface LoginRequest {\n phone: string;\n password: string;\n}\n\n/**\n * 注册请求接口\n */\nexport interface RegisterRequest {\n phone: string;\n password: string;\n name?: string;\n}\n\n/**\n * 登录响应接口\n */\nexport interface LoginResponse {\n success: boolean;\n message: string;\n user?: User;\n sessionToken?: string;\n}\n\n/**\n * 注册响应接口\n */\nexport interface RegisterResponse {\n success: boolean;\n message: string;\n user?: User;\n sessionToken?: string;\n}\n\n/**\n * 会话验证响应接口\n */\nexport interface SessionValidationResponse {\n valid: boolean;\n user?: User;\n message?: string;\n}\n\n/**\n * 会话验证结果接口\n */\nexport interface SessionValidation {\n valid: boolean;\n user?: User;\n}\n\n// ===== 组件Props类型 =====\n\n/**\n * 登录模态框Props\n */\nexport interface LoginModalProps {\n isOpen: boolean;\n onClose: () => void;\n onSuccess: () => void;\n onSwitchToRegister?: () => void;\n}\n\n/**\n * 注册模态框Props\n */\nexport interface RegisterModalProps {\n isOpen: boolean;\n onClose: () => void;\n onSuccess: () => void;\n onSwitchToLogin?: () => void;\n}\n\n/**\n * 认证守卫Props\n */\nexport interface AuthGuardProps {\n children: React.ReactNode;\n fallback?: React.ReactNode;\n requireAuth?: boolean;\n}\n\n/**\n * 自定义菜单项接口\n */\nexport interface CustomMenuItem {\n id: string;\n label: string;\n icon?: React.ComponentType<any>;\n onClick: () => void;\n requireAuth?: boolean; // 是否需要登录才显示\n}\n\n/**\n * 用户菜单Props\n */\nexport interface UserMenuProps {\n customMenuItems?: CustomMenuItem[]; // 自定义菜单项\n className?: string; // 自定义样式类名\n}\n\n/**\n * 忘记密码模态框Props\n */\nexport interface ForgotPasswordModalProps {\n isOpen: boolean;\n onClose: () => void;\n onSuccess: () => void;\n}\n\n// ===== Hook返回类型 =====\n\n/**\n * useAuth Hook返回值类型\n */\nexport interface UseAuthReturn {\n user: User | null;\n loading: boolean;\n isAuthenticated: boolean;\n login: (credentials: LoginRequest) => Promise<{ success: boolean; user?: User; message?: string }>;\n register: (userData: RegisterRequest) => Promise<{ success: boolean; user?: User; message?: string }>;\n logout: () => Promise<void>;\n refreshUser: () => void;\n}\n\n// ===== 服务相关类型 =====\n\n/**\n * 认证服务接口\n */\nexport interface AuthService {\n verifyPassword(phone: string, password: string): Promise<User | null>;\n createUser(phone: string, password: string, name?: string): Promise<User>;\n createSession(userId: number): Promise<UserSession>;\n validateSession(sessionToken: string): Promise<SessionValidation>;\n deleteSession(sessionToken: string): Promise<void>;\n deleteUserSessions(userId: number): Promise<void>;\n updateLastLogin(userId: number): Promise<void>;\n cleanupExpiredSessions(): Promise<void>;\n getUserByPhone(phone: string): Promise<User | null>;\n sendVerificationCode(phone: string): Promise<string>;\n verifyCode(phone: string, code: string): Promise<boolean>;\n resetPassword(phone: string, newPassword: string): Promise<void>;\n cleanupExpiredVerificationCodes(): Promise<void>;\n}\n\n// ===== 工具函数类型 =====\n\n/**\n * API权限验证函数类型\n */\nexport type ValidateApiAuth = (request: Request) => Promise<User | null>;\n\n// ===== 常量类型 =====\n\n/**\n * 用户角色枚举\n */\nexport enum UserRole {\n USER = 'user',\n ADMIN = 'admin'\n}\n\n/**\n * 会话配置\n */\nexport interface SessionConfig {\n maxAge: number; // 会话最大存活时间(秒)\n cookieName: string; // Cookie名称\n secure: boolean; // 是否使用安全Cookie\n httpOnly: boolean; // 是否仅HTTP访问\n sameSite: 'strict' | 'lax' | 'none'; // SameSite策略\n} ","import type { User } from '../types';\n\n/**\n * 验证手机号格式\n */\nexport function validatePhoneNumber(phone: string): boolean {\n return /^1[3-9]\\d{9}$/.test(phone);\n}\n\n/**\n * 验证密码强度(可扩展)\n */\nexport function validatePassword(password: string): { valid: boolean; message?: string } {\n if (!password) {\n return { valid: false, message: '密码不能为空' };\n }\n \n if (password.length < 6) {\n return { valid: false, message: '密码长度至少6位' };\n }\n \n return { valid: true };\n}\n\n/**\n * 生成安全的会话令牌\n */\nexport function generateSessionToken(): string {\n // 在实际环境中,应该使用更安全的随机数生成\n return Math.random().toString(36).substring(2) + \n Date.now().toString(36) + \n Math.random().toString(36).substring(2);\n}\n\n/**\n * 检查用户是否为管理员\n */\nexport function isAdmin(user: User | null): boolean {\n return user?.role === 'admin';\n}\n\n/**\n * 检查用户是否处于活跃状态\n */\nexport function isActiveUser(user: User | null): boolean {\n return user?.isActive === true;\n}\n\n/**\n * 格式化用户显示名称\n */\nexport function getUserDisplayName(user: User): string {\n return user.name || user.phone || '未知用户';\n}\n\n/**\n * 计算会话过期时间\n */\nexport function calculateSessionExpiry(days: number = 30): Date {\n return new Date(Date.now() + days * 24 * 60 * 60 * 1000);\n}\n\n/**\n * 检查会话是否过期\n */\nexport function isSessionExpired(expiresAt: Date): boolean {\n return new Date() > new Date(expiresAt);\n} "]}
|
|
@@ -10,6 +10,14 @@ var React5__default = /*#__PURE__*/_interopDefault(React5);
|
|
|
10
10
|
|
|
11
11
|
// src/auth/legacy/components/AuthGuard.tsx
|
|
12
12
|
var AuthContext = React5.createContext(void 0);
|
|
13
|
+
function extractUser(data) {
|
|
14
|
+
return data?.user ?? data?.data?.user ?? null;
|
|
15
|
+
}
|
|
16
|
+
function extractValid(data) {
|
|
17
|
+
if (typeof data?.valid === "boolean") return data.valid;
|
|
18
|
+
if (typeof data?.data?.valid === "boolean") return data.data.valid;
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
13
21
|
function AuthProvider({ children }) {
|
|
14
22
|
const [user, setUser] = React5.useState(null);
|
|
15
23
|
const [loading, setLoading] = React5.useState(true);
|
|
@@ -27,10 +35,12 @@ function AuthProvider({ children }) {
|
|
|
27
35
|
console.log("\u{1F4E1} [AuthContext] \u4F1A\u8BDD\u9A8C\u8BC1\u54CD\u5E94\u72B6\u6001:", response.status);
|
|
28
36
|
const data = await response.json();
|
|
29
37
|
console.log("\u{1F4C4} [AuthContext] \u4F1A\u8BDD\u9A8C\u8BC1\u54CD\u5E94\u6570\u636E:", data);
|
|
38
|
+
const resolvedUser = extractUser(data);
|
|
39
|
+
const resolvedValid = extractValid(data);
|
|
30
40
|
safeSetState(() => {
|
|
31
|
-
if (
|
|
32
|
-
console.log("\u2705 [AuthContext] \u4F1A\u8BDD\u9A8C\u8BC1\u6210\u529F, \u7528\u6237:",
|
|
33
|
-
setUser(
|
|
41
|
+
if (resolvedValid && resolvedUser) {
|
|
42
|
+
console.log("\u2705 [AuthContext] \u4F1A\u8BDD\u9A8C\u8BC1\u6210\u529F, \u7528\u6237:", resolvedUser);
|
|
43
|
+
setUser(resolvedUser);
|
|
34
44
|
setIsAuthenticated(true);
|
|
35
45
|
} else {
|
|
36
46
|
console.log("\u274C [AuthContext] \u4F1A\u8BDD\u9A8C\u8BC1\u5931\u8D25:", data.message);
|
|
@@ -61,9 +71,10 @@ function AuthProvider({ children }) {
|
|
|
61
71
|
console.log("\u{1F4E1} [AuthContext] \u6536\u5230\u54CD\u5E94\uFF0C\u72B6\u6001\u7801:", response.status);
|
|
62
72
|
const data = await response.json();
|
|
63
73
|
console.log("\u{1F4C4} [AuthContext] \u54CD\u5E94\u6570\u636E:", data);
|
|
64
|
-
|
|
74
|
+
const resolvedUser = extractUser(data);
|
|
75
|
+
if (data.success && resolvedUser) {
|
|
65
76
|
console.log("\u2705 [AuthContext] \u767B\u5F55\u6210\u529F, \u5F00\u59CB\u66F4\u65B0\u5168\u5C40\u72B6\u6001");
|
|
66
|
-
console.log("\u{1F464} [AuthContext] \u7528\u6237\u6570\u636E:",
|
|
77
|
+
console.log("\u{1F464} [AuthContext] \u7528\u6237\u6570\u636E:", resolvedUser);
|
|
67
78
|
console.log("\u{1F4CA} [AuthContext] \u66F4\u65B0\u524D\u72B6\u6001:", {
|
|
68
79
|
currentUser: user ? `${user.name || "\u672A\u8BBE\u7F6E"} (${user.phone})` : null,
|
|
69
80
|
currentIsAuthenticated: isAuthenticated,
|
|
@@ -71,8 +82,8 @@ function AuthProvider({ children }) {
|
|
|
71
82
|
});
|
|
72
83
|
console.log("\u{1F504} [AuthContext] \u6267\u884C\u5168\u5C40\u72B6\u6001\u66F4\u65B0...");
|
|
73
84
|
safeSetState(() => {
|
|
74
|
-
console.log("\u{1F504} [AuthContext] \u6B63\u5728\u8BBE\u7F6E\u7528\u6237:",
|
|
75
|
-
setUser(
|
|
85
|
+
console.log("\u{1F504} [AuthContext] \u6B63\u5728\u8BBE\u7F6E\u7528\u6237:", resolvedUser);
|
|
86
|
+
setUser(resolvedUser);
|
|
76
87
|
console.log("\u{1F504} [AuthContext] \u6B63\u5728\u8BBE\u7F6E\u8BA4\u8BC1\u72B6\u6001: true");
|
|
77
88
|
setIsAuthenticated(true);
|
|
78
89
|
console.log("\u{1F504} [AuthContext] \u6B63\u5728\u8BBE\u7F6E\u52A0\u8F7D\u72B6\u6001: false");
|
|
@@ -81,12 +92,12 @@ function AuthProvider({ children }) {
|
|
|
81
92
|
});
|
|
82
93
|
setTimeout(() => {
|
|
83
94
|
console.log("\u{1F389} [AuthContext] \u5EF6\u8FDF\u786E\u8BA4 - \u5168\u5C40\u767B\u5F55\u72B6\u6001\u5E94\u8BE5\u5DF2\u66F4\u65B0:", {
|
|
84
|
-
user:
|
|
95
|
+
user: resolvedUser,
|
|
85
96
|
isAuthenticated: true
|
|
86
97
|
});
|
|
87
98
|
}, 0);
|
|
88
99
|
console.log("\u{1F680} [AuthContext] \u8FD4\u56DE\u6210\u529F\u7ED3\u679C");
|
|
89
|
-
return { success: true, user:
|
|
100
|
+
return { success: true, user: resolvedUser };
|
|
90
101
|
} else {
|
|
91
102
|
console.log("\u274C [AuthContext] \u767B\u5F55\u5931\u8D25:", data.message);
|
|
92
103
|
return { success: false, message: data.message };
|
|
@@ -106,15 +117,16 @@ function AuthProvider({ children }) {
|
|
|
106
117
|
});
|
|
107
118
|
const data = await response.json();
|
|
108
119
|
console.log("\u{1F4E1} [AuthContext] \u6CE8\u518C\u54CD\u5E94:", data);
|
|
109
|
-
|
|
120
|
+
const resolvedUser = extractUser(data);
|
|
121
|
+
if (data.success && resolvedUser) {
|
|
110
122
|
console.log("\u2705 [AuthContext] \u6CE8\u518C\u6210\u529F, \u7ACB\u5373\u66F4\u65B0\u5168\u5C40\u72B6\u6001");
|
|
111
123
|
safeSetState(() => {
|
|
112
|
-
setUser(
|
|
124
|
+
setUser(resolvedUser);
|
|
113
125
|
setIsAuthenticated(true);
|
|
114
126
|
setLoading(false);
|
|
115
127
|
});
|
|
116
128
|
console.log("\u{1F680} [AuthContext] \u8FD4\u56DE\u6CE8\u518C\u6210\u529F\u7ED3\u679C");
|
|
117
|
-
return { success: true, user:
|
|
129
|
+
return { success: true, user: resolvedUser };
|
|
118
130
|
} else {
|
|
119
131
|
console.log("\u274C [AuthContext] \u6CE8\u518C\u5931\u8D25:", data.message);
|
|
120
132
|
return { success: false, message: data.message };
|
|
@@ -566,6 +578,7 @@ function LoginModal({ isOpen, onClose, onSuccess, onSwitchToRegister }) {
|
|
|
566
578
|
id: "phone",
|
|
567
579
|
name: "phone",
|
|
568
580
|
type: "tel",
|
|
581
|
+
autoComplete: "tel",
|
|
569
582
|
value: formData.phone,
|
|
570
583
|
onChange: handleInputChange,
|
|
571
584
|
placeholder: "\u8BF7\u8F93\u5165\u624B\u673A\u53F7",
|
|
@@ -578,6 +591,7 @@ function LoginModal({ isOpen, onClose, onSuccess, onSwitchToRegister }) {
|
|
|
578
591
|
id: "password",
|
|
579
592
|
name: "password",
|
|
580
593
|
type: showPassword ? "text" : "password",
|
|
594
|
+
autoComplete: "current-password",
|
|
581
595
|
value: formData.password,
|
|
582
596
|
onChange: handleInputChange,
|
|
583
597
|
placeholder: "\u8BF7\u8F93\u5165\u5BC6\u7801",
|
|
@@ -806,6 +820,7 @@ function RegisterModal({ isOpen, onClose, onSuccess, onSwitchToLogin }) {
|
|
|
806
820
|
id: "phone",
|
|
807
821
|
name: "phone",
|
|
808
822
|
type: "tel",
|
|
823
|
+
autoComplete: "tel",
|
|
809
824
|
value: formData.phone,
|
|
810
825
|
onChange: handleInputChange,
|
|
811
826
|
placeholder: "\u8BF7\u8F93\u5165\u624B\u673A\u53F7",
|
|
@@ -818,6 +833,7 @@ function RegisterModal({ isOpen, onClose, onSuccess, onSwitchToLogin }) {
|
|
|
818
833
|
id: "name",
|
|
819
834
|
name: "name",
|
|
820
835
|
type: "text",
|
|
836
|
+
autoComplete: "name",
|
|
821
837
|
value: formData.name,
|
|
822
838
|
onChange: handleInputChange,
|
|
823
839
|
placeholder: "\u8BF7\u8F93\u5165\u59D3\u540D\uFF08\u53EF\u9009\uFF09",
|
|
@@ -830,6 +846,7 @@ function RegisterModal({ isOpen, onClose, onSuccess, onSwitchToLogin }) {
|
|
|
830
846
|
id: "password",
|
|
831
847
|
name: "password",
|
|
832
848
|
type: showPassword ? "text" : "password",
|
|
849
|
+
autoComplete: "new-password",
|
|
833
850
|
value: formData.password,
|
|
834
851
|
onChange: handleInputChange,
|
|
835
852
|
placeholder: "\u8BF7\u8F93\u5165\u5BC6\u7801\uFF08\u81F3\u5C116\u4F4D\uFF09",
|
|
@@ -851,6 +868,7 @@ function RegisterModal({ isOpen, onClose, onSuccess, onSwitchToLogin }) {
|
|
|
851
868
|
id: "confirmPassword",
|
|
852
869
|
name: "confirmPassword",
|
|
853
870
|
type: showConfirmPassword ? "text" : "password",
|
|
871
|
+
autoComplete: "new-password",
|
|
854
872
|
value: formData.confirmPassword,
|
|
855
873
|
onChange: handleInputChange,
|
|
856
874
|
placeholder: "\u8BF7\u518D\u6B21\u8F93\u5165\u5BC6\u7801",
|