feat: 添加存储调试页面并优化用户角色查询
This commit is contained in:
+11
-13
@@ -244,25 +244,23 @@ router.get('/profile', authMiddleware, async (req, res) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const roles = await Role.findAll({
|
const userRoles = await UserRole.findAll({
|
||||||
include: [
|
where: { UserId: user.userId },
|
||||||
{
|
include: [{ model: Role }],
|
||||||
model: User,
|
|
||||||
where: { userId: req.user.userId },
|
|
||||||
attributes: [],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
data: {
|
data: {
|
||||||
user,
|
user,
|
||||||
roles: roles.map(r => ({
|
roles: userRoles.map(ur => {
|
||||||
roleId: r.roleId,
|
const role = ur.Role || ur;
|
||||||
roleName: r.roleName,
|
return {
|
||||||
roleCode: r.roleCode,
|
roleId: role.roleId,
|
||||||
})),
|
roleName: role.roleName,
|
||||||
|
roleCode: role.roleCode,
|
||||||
|
};
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
Generated
+30
-26
@@ -278,6 +278,7 @@
|
|||||||
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
|
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/code-frame": "^7.27.1",
|
"@babel/code-frame": "^7.27.1",
|
||||||
"@babel/generator": "^7.28.5",
|
"@babel/generator": "^7.28.5",
|
||||||
@@ -626,6 +627,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
},
|
},
|
||||||
@@ -669,6 +671,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
@@ -690,6 +693,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.4.0.tgz",
|
||||||
"integrity": "sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==",
|
"integrity": "sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/memoize": "^0.9.0"
|
"@emotion/memoize": "^0.9.0"
|
||||||
}
|
}
|
||||||
@@ -1735,6 +1739,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-8.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-8.18.0.tgz",
|
||||||
"integrity": "sha512-FYZZqD0UUHUswKz3LQl2Z7H24AhD14XGTsIRw3SJaXUxyfVMi+1yiZGmqTcPt/CkPpdU7rrxqcyQ1zJE5DjvIQ==",
|
"integrity": "sha512-FYZZqD0UUHUswKz3LQl2Z7H24AhD14XGTsIRw3SJaXUxyfVMi+1yiZGmqTcPt/CkPpdU7rrxqcyQ1zJE5DjvIQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.17.8",
|
"@babel/runtime": "^7.17.8",
|
||||||
"@types/react-reconciler": "^0.26.7",
|
"@types/react-reconciler": "^0.26.7",
|
||||||
@@ -2507,8 +2512,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
|
||||||
"integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
|
"integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT"
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/@types/babel__core": {
|
"node_modules/@types/babel__core": {
|
||||||
"version": "7.20.5",
|
"version": "7.20.5",
|
||||||
@@ -2863,6 +2867,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.9.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.9.tgz",
|
||||||
"integrity": "sha512-Lpo8kgb/igvMIPeNV2rsYKTgaORYdO1XGVZ4Qz3akwOj0ySGYMPlQWa8BaLn0G63D1aSaAQ5ldR06wCpChQCjA==",
|
"integrity": "sha512-Lpo8kgb/igvMIPeNV2rsYKTgaORYdO1XGVZ4Qz3akwOj0ySGYMPlQWa8BaLn0G63D1aSaAQ5ldR06wCpChQCjA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"csstype": "^3.2.2"
|
"csstype": "^3.2.2"
|
||||||
}
|
}
|
||||||
@@ -2893,6 +2898,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/three/-/three-0.182.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/three/-/three-0.182.0.tgz",
|
||||||
"integrity": "sha512-WByN9V3Sbwbe2OkWuSGyoqQO8Du6yhYaXtXLoA5FkKTUJorZ+yOHBZ35zUUPQXlAKABZmbYp5oAqpA4RBjtJ/Q==",
|
"integrity": "sha512-WByN9V3Sbwbe2OkWuSGyoqQO8Du6yhYaXtXLoA5FkKTUJorZ+yOHBZ35zUUPQXlAKABZmbYp5oAqpA4RBjtJ/Q==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@dimforge/rapier3d-compat": "~0.12.0",
|
"@dimforge/rapier3d-compat": "~0.12.0",
|
||||||
"@tweenjs/tween.js": "~23.1.3",
|
"@tweenjs/tween.js": "~23.1.3",
|
||||||
@@ -3038,7 +3044,6 @@
|
|||||||
"integrity": "sha512-cuzPhD8fwRHk8IGfmYaR4eEe4cAyJEL66Ove/WZL7yWNL134nqLddSLwNRIsFlnnW1kK+p8Ck3viFnC0chXCXw==",
|
"integrity": "sha512-cuzPhD8fwRHk8IGfmYaR4eEe4cAyJEL66Ove/WZL7yWNL134nqLddSLwNRIsFlnnW1kK+p8Ck3viFnC0chXCXw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.29.0",
|
"@babel/parser": "^7.29.0",
|
||||||
"@vue/shared": "3.5.29",
|
"@vue/shared": "3.5.29",
|
||||||
@@ -3053,7 +3058,6 @@
|
|||||||
"integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
|
"integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.12"
|
"node": ">=0.12"
|
||||||
},
|
},
|
||||||
@@ -3066,8 +3070,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT"
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-dom": {
|
"node_modules/@vue/compiler-dom": {
|
||||||
"version": "3.5.29",
|
"version": "3.5.29",
|
||||||
@@ -3075,7 +3078,6 @@
|
|||||||
"integrity": "sha512-n0G5o7R3uBVmVxjTIYcz7ovr8sy7QObFG8OQJ3xGCDNhbG60biP/P5KnyY8NLd81OuT1WJflG7N4KWYHaeeaIg==",
|
"integrity": "sha512-n0G5o7R3uBVmVxjTIYcz7ovr8sy7QObFG8OQJ3xGCDNhbG60biP/P5KnyY8NLd81OuT1WJflG7N4KWYHaeeaIg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-core": "3.5.29",
|
"@vue/compiler-core": "3.5.29",
|
||||||
"@vue/shared": "3.5.29"
|
"@vue/shared": "3.5.29"
|
||||||
@@ -3105,8 +3107,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT"
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-ssr": {
|
"node_modules/@vue/compiler-ssr": {
|
||||||
"version": "3.5.29",
|
"version": "3.5.29",
|
||||||
@@ -3114,7 +3115,6 @@
|
|||||||
"integrity": "sha512-Y/ARJZE6fpjzL5GH/phJmsFwx3g6t2KmHKHx5q+MLl2kencADKIrhH5MLF6HHpRMmlRAYBRSvv347Mepf1zVNw==",
|
"integrity": "sha512-Y/ARJZE6fpjzL5GH/phJmsFwx3g6t2KmHKHx5q+MLl2kencADKIrhH5MLF6HHpRMmlRAYBRSvv347Mepf1zVNw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-dom": "3.5.29",
|
"@vue/compiler-dom": "3.5.29",
|
||||||
"@vue/shared": "3.5.29"
|
"@vue/shared": "3.5.29"
|
||||||
@@ -3126,7 +3126,6 @@
|
|||||||
"integrity": "sha512-zcrANcrRdcLtmGZETBxWqIkoQei8HaFpZWx/GHKxx79JZsiZ8j1du0VUJtu4eJjgFvU/iKL5lRXFXksVmI+5DA==",
|
"integrity": "sha512-zcrANcrRdcLtmGZETBxWqIkoQei8HaFpZWx/GHKxx79JZsiZ8j1du0VUJtu4eJjgFvU/iKL5lRXFXksVmI+5DA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/shared": "3.5.29"
|
"@vue/shared": "3.5.29"
|
||||||
}
|
}
|
||||||
@@ -3137,7 +3136,6 @@
|
|||||||
"integrity": "sha512-8DpW2QfdwIWOLqtsNcds4s+QgwSaHSJY/SUe04LptianUQ/0xi6KVsu/pYVh+HO3NTVvVJjIPL2t6GdeKbS4Lg==",
|
"integrity": "sha512-8DpW2QfdwIWOLqtsNcds4s+QgwSaHSJY/SUe04LptianUQ/0xi6KVsu/pYVh+HO3NTVvVJjIPL2t6GdeKbS4Lg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/reactivity": "3.5.29",
|
"@vue/reactivity": "3.5.29",
|
||||||
"@vue/shared": "3.5.29"
|
"@vue/shared": "3.5.29"
|
||||||
@@ -3149,7 +3147,6 @@
|
|||||||
"integrity": "sha512-AHvvJEtcY9tw/uk+s/YRLSlxxQnqnAkjqvK25ZiM4CllCZWzElRAoQnCM42m9AHRLNJ6oe2kC5DCgD4AUdlvXg==",
|
"integrity": "sha512-AHvvJEtcY9tw/uk+s/YRLSlxxQnqnAkjqvK25ZiM4CllCZWzElRAoQnCM42m9AHRLNJ6oe2kC5DCgD4AUdlvXg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/reactivity": "3.5.29",
|
"@vue/reactivity": "3.5.29",
|
||||||
"@vue/runtime-core": "3.5.29",
|
"@vue/runtime-core": "3.5.29",
|
||||||
@@ -3163,7 +3160,6 @@
|
|||||||
"integrity": "sha512-G/1k6WK5MusLlbxSE2YTcqAAezS+VuwHhOvLx2KnQU7G2zCH6KIb+5Wyt6UjMq7a3qPzNEjJXs1hvAxDclQH+g==",
|
"integrity": "sha512-G/1k6WK5MusLlbxSE2YTcqAAezS+VuwHhOvLx2KnQU7G2zCH6KIb+5Wyt6UjMq7a3qPzNEjJXs1hvAxDclQH+g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-ssr": "3.5.29",
|
"@vue/compiler-ssr": "3.5.29",
|
||||||
"@vue/shared": "3.5.29"
|
"@vue/shared": "3.5.29"
|
||||||
@@ -3177,8 +3173,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.29.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.29.tgz",
|
||||||
"integrity": "sha512-w7SR0A5zyRByL9XUkCfdLs7t9XOHUyJ67qPGQjOou3p6GvBeBW+AVjUUmlxtZ4PIYaRvE+1LmK44O4uajlZwcg==",
|
"integrity": "sha512-w7SR0A5zyRByL9XUkCfdLs7t9XOHUyJ67qPGQjOou3p6GvBeBW+AVjUUmlxtZ4PIYaRvE+1LmK44O4uajlZwcg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT"
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/@webgpu/types": {
|
"node_modules/@webgpu/types": {
|
||||||
"version": "0.1.69",
|
"version": "0.1.69",
|
||||||
@@ -3192,6 +3187,7 @@
|
|||||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"acorn": "bin/acorn"
|
"acorn": "bin/acorn"
|
||||||
},
|
},
|
||||||
@@ -3251,7 +3247,6 @@
|
|||||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
@@ -3651,6 +3646,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"baseline-browser-mapping": "^2.9.0",
|
"baseline-browser-mapping": "^2.9.0",
|
||||||
"caniuse-lite": "^1.0.30001759",
|
"caniuse-lite": "^1.0.30001759",
|
||||||
@@ -4127,6 +4123,7 @@
|
|||||||
"resolved": "https://registry.npmmirror.com/d3-selection/-/d3-selection-3.0.0.tgz",
|
"resolved": "https://registry.npmmirror.com/d3-selection/-/d3-selection-3.0.0.tgz",
|
||||||
"integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
|
"integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
@@ -4247,7 +4244,8 @@
|
|||||||
"version": "1.11.19",
|
"version": "1.11.19",
|
||||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz",
|
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz",
|
||||||
"integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==",
|
"integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "4.4.3",
|
"version": "4.4.3",
|
||||||
@@ -4362,8 +4360,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
|
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
|
||||||
"integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
|
"integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT"
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/dom-helpers": {
|
"node_modules/dom-helpers": {
|
||||||
"version": "5.2.1",
|
"version": "5.2.1",
|
||||||
@@ -4662,6 +4659,7 @@
|
|||||||
"integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
|
"integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.8.0",
|
"@eslint-community/eslint-utils": "^4.8.0",
|
||||||
"@eslint-community/regexpp": "^4.12.1",
|
"@eslint-community/regexpp": "^4.12.1",
|
||||||
@@ -4722,6 +4720,7 @@
|
|||||||
"integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==",
|
"integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"eslint-config-prettier": "bin/cli.js"
|
"eslint-config-prettier": "bin/cli.js"
|
||||||
},
|
},
|
||||||
@@ -6076,6 +6075,7 @@
|
|||||||
"integrity": "sha512-GtldT42B8+jefDUC4yUKAvsaOrH7PDHmZxZXNgF2xMmymjUbRYJvpAybZAKEmXDGTM0mCsz8duOa4vTm5AY2Kg==",
|
"integrity": "sha512-GtldT42B8+jefDUC4yUKAvsaOrH7PDHmZxZXNgF2xMmymjUbRYJvpAybZAKEmXDGTM0mCsz8duOa4vTm5AY2Kg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@acemir/cssom": "^0.9.28",
|
"@acemir/cssom": "^0.9.28",
|
||||||
"@asamuzakjp/dom-selector": "^6.7.6",
|
"@asamuzakjp/dom-selector": "^6.7.6",
|
||||||
@@ -6284,7 +6284,6 @@
|
|||||||
"integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
|
"integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"bin": {
|
"bin": {
|
||||||
"lz-string": "bin/bin.js"
|
"lz-string": "bin/bin.js"
|
||||||
}
|
}
|
||||||
@@ -6826,6 +6825,7 @@
|
|||||||
"integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==",
|
"integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"prettier": "bin/prettier.cjs"
|
"prettier": "bin/prettier.cjs"
|
||||||
},
|
},
|
||||||
@@ -6855,7 +6855,6 @@
|
|||||||
"integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
|
"integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-regex": "^5.0.1",
|
"ansi-regex": "^5.0.1",
|
||||||
"ansi-styles": "^5.0.0",
|
"ansi-styles": "^5.0.0",
|
||||||
@@ -6871,7 +6870,6 @@
|
|||||||
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
|
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
},
|
},
|
||||||
@@ -6884,8 +6882,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||||
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
|
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT"
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/promise-worker-transferable": {
|
"node_modules/promise-worker-transferable": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
@@ -7558,6 +7555,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
|
||||||
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
|
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"loose-envify": "^1.1.0"
|
"loose-envify": "^1.1.0"
|
||||||
},
|
},
|
||||||
@@ -7582,6 +7580,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
|
||||||
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
|
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"loose-envify": "^1.1.0",
|
"loose-envify": "^1.1.0",
|
||||||
"scheduler": "^0.23.2"
|
"scheduler": "^0.23.2"
|
||||||
@@ -8529,6 +8528,7 @@
|
|||||||
"integrity": "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==",
|
"integrity": "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/source-map": "^0.3.3",
|
"@jridgewell/source-map": "^0.3.3",
|
||||||
"acorn": "^8.15.0",
|
"acorn": "^8.15.0",
|
||||||
@@ -8555,7 +8555,8 @@
|
|||||||
"version": "0.183.2",
|
"version": "0.183.2",
|
||||||
"resolved": "https://registry.npmjs.org/three/-/three-0.183.2.tgz",
|
"resolved": "https://registry.npmjs.org/three/-/three-0.183.2.tgz",
|
||||||
"integrity": "sha512-di3BsL2FEQ1PA7Hcvn4fyJOlxRRgFYBpMTcyOgkwJIaDOdJMebEFPA+t98EvjuljDx4hNulAGwF6KIjtwI5jgQ==",
|
"integrity": "sha512-di3BsL2FEQ1PA7Hcvn4fyJOlxRRgFYBpMTcyOgkwJIaDOdJMebEFPA+t98EvjuljDx4hNulAGwF6KIjtwI5jgQ==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/three-mesh-bvh": {
|
"node_modules/three-mesh-bvh": {
|
||||||
"version": "0.7.8",
|
"version": "0.7.8",
|
||||||
@@ -9134,6 +9135,7 @@
|
|||||||
"integrity": "sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g==",
|
"integrity": "sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.18.10",
|
"esbuild": "^0.18.10",
|
||||||
"postcss": "^8.4.27",
|
"postcss": "^8.4.27",
|
||||||
@@ -9753,6 +9755,7 @@
|
|||||||
"integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==",
|
"integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.27.0",
|
"esbuild": "^0.27.0",
|
||||||
"fdir": "^6.5.0",
|
"fdir": "^6.5.0",
|
||||||
@@ -10158,6 +10161,7 @@
|
|||||||
"integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
|
"integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/colinhacks"
|
"url": "https://github.com/sponsors/colinhacks"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,68 +1,52 @@
|
|||||||
import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
|
import React, { createContext, useContext, useState, useEffect, useCallback, useMemo } from 'react';
|
||||||
import { authAPI } from '../api';
|
import { authAPI } from '../api';
|
||||||
import secureStorage, { TOKEN_KEY, USER_KEY } from '../utils/secureStorage';
|
import secureStorage, { TOKEN_KEY, USER_KEY } from '../utils/secureStorage';
|
||||||
|
|
||||||
const AuthContext = createContext(null);
|
const AuthContext = createContext({
|
||||||
|
user: null,
|
||||||
|
token: null,
|
||||||
|
loading: true,
|
||||||
|
initialized: false,
|
||||||
|
login: async () => ({ success: false, message: '认证未初始化' }),
|
||||||
|
register: async () => ({ success: false, message: '认证未初始化' }),
|
||||||
|
logout: () => {},
|
||||||
|
updateUser: () => {},
|
||||||
|
hasPermission: () => false,
|
||||||
|
checkAdmin: () => Promise.resolve({ success: true, data: { hasAdmin: false, userCount: 0 } }),
|
||||||
|
});
|
||||||
|
|
||||||
export const useAuth = () => {
|
export const useAuth = () => {
|
||||||
const context = useContext(AuthContext);
|
return useContext(AuthContext);
|
||||||
if (!context) {
|
|
||||||
throw new Error('useAuth必须在AuthProvider内部使用');
|
|
||||||
}
|
|
||||||
return context;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AuthProvider = ({ children }) => {
|
export const AuthProvider = ({ children }) => {
|
||||||
console.log('[AuthContext] Initializing...');
|
|
||||||
|
|
||||||
const savedToken = secureStorage.get(TOKEN_KEY);
|
const savedToken = secureStorage.get(TOKEN_KEY);
|
||||||
const savedUser = secureStorage.get(USER_KEY);
|
const savedUser = secureStorage.get(USER_KEY);
|
||||||
|
|
||||||
console.log('[AuthContext] Saved token:', savedToken ? 'exists' : 'null');
|
const [user, setUser] = useState(savedUser);
|
||||||
console.log('[AuthContext] Saved user:', savedUser ? 'exists' : 'null');
|
const [token, setToken] = useState(savedToken);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
const [user, setUser] = useState(() => savedUser || null);
|
|
||||||
const [token, setToken] = useState(() => savedToken);
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
const [initialized, setInitialized] = useState(false);
|
const [initialized, setInitialized] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const currentToken = secureStorage.get(TOKEN_KEY);
|
const currentToken = secureStorage.get(TOKEN_KEY);
|
||||||
const currentUser = secureStorage.get(USER_KEY);
|
|
||||||
|
|
||||||
if (currentToken && currentToken === token) {
|
if (!currentToken) {
|
||||||
if (currentUser && JSON.stringify(currentUser) !== JSON.stringify(user)) {
|
|
||||||
setUser(currentUser);
|
|
||||||
}
|
|
||||||
// 有 token 时调用 fetchProfile 验证有效性并刷新用户信息
|
|
||||||
fetchProfile();
|
|
||||||
} else if (!currentToken) {
|
|
||||||
setToken(null);
|
setToken(null);
|
||||||
setUser(null);
|
setUser(null);
|
||||||
setInitialized(true);
|
|
||||||
} else {
|
|
||||||
setToken(currentToken);
|
|
||||||
setInitialized(true);
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const fetchProfile = useCallback(async () => {
|
|
||||||
const currentToken = secureStorage.get(TOKEN_KEY);
|
|
||||||
if (!currentToken) {
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
setInitialized(true);
|
setInitialized(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const initializeAuth = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await authAPI.getProfile();
|
const response = await authAPI.getProfile();
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
setUser(response.data.user);
|
setUser(response.data.user);
|
||||||
secureStorage.set(USER_KEY, response.data.user);
|
secureStorage.set(USER_KEY, response.data.user);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch {
|
||||||
console.error('获取用户信息失败:', error);
|
|
||||||
// Token 无效,清除登录状态
|
|
||||||
secureStorage.remove(TOKEN_KEY);
|
secureStorage.remove(TOKEN_KEY);
|
||||||
secureStorage.remove(USER_KEY);
|
secureStorage.remove(USER_KEY);
|
||||||
setToken(null);
|
setToken(null);
|
||||||
@@ -71,9 +55,12 @@ export const AuthProvider = ({ children }) => {
|
|||||||
setLoading(false);
|
setLoading(false);
|
||||||
setInitialized(true);
|
setInitialized(true);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
initializeAuth();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const login = async (username, password) => {
|
const login = useCallback(async (username, password) => {
|
||||||
try {
|
try {
|
||||||
const response = await authAPI.login({ username, password });
|
const response = await authAPI.login({ username, password });
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
@@ -89,9 +76,9 @@ export const AuthProvider = ({ children }) => {
|
|||||||
const message = error?.response?.data?.message || error?.message || '登录失败,请稍后重试';
|
const message = error?.response?.data?.message || error?.message || '登录失败,请稍后重试';
|
||||||
return { success: false, message };
|
return { success: false, message };
|
||||||
}
|
}
|
||||||
};
|
}, []);
|
||||||
|
|
||||||
const register = async userData => {
|
const register = useCallback(async userData => {
|
||||||
try {
|
try {
|
||||||
const response = await authAPI.register(userData);
|
const response = await authAPI.register(userData);
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
@@ -109,7 +96,7 @@ export const AuthProvider = ({ children }) => {
|
|||||||
const message = error?.response?.data?.message || error?.message || '注册失败,请稍后重试';
|
const message = error?.response?.data?.message || error?.message || '注册失败,请稍后重试';
|
||||||
return { success: false, message };
|
return { success: false, message };
|
||||||
}
|
}
|
||||||
};
|
}, []);
|
||||||
|
|
||||||
const logout = useCallback(() => {
|
const logout = useCallback(() => {
|
||||||
secureStorage.remove(TOKEN_KEY);
|
secureStorage.remove(TOKEN_KEY);
|
||||||
@@ -118,24 +105,25 @@ export const AuthProvider = ({ children }) => {
|
|||||||
setUser(null);
|
setUser(null);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const updateUser = newUserData => {
|
const updateUser = useCallback(newUserData => {
|
||||||
const updatedUser = { ...user, ...newUserData };
|
setUser(prev => {
|
||||||
setUser(updatedUser);
|
const updated = { ...prev, ...newUserData };
|
||||||
secureStorage.set(USER_KEY, updatedUser);
|
secureStorage.set(USER_KEY, updated);
|
||||||
};
|
return updated;
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
const hasPermission = permission => {
|
const hasPermission = useCallback(permission => {
|
||||||
if (!user) return false;
|
if (!user) return false;
|
||||||
const roles = user.roles || [];
|
const roles = user.roles || [];
|
||||||
// 管理员拥有所有权限
|
|
||||||
if (roles.some(r => r.roleCode === 'admin')) return true;
|
if (roles.some(r => r.roleCode === 'admin')) return true;
|
||||||
// 检查具体权限
|
|
||||||
if (permission === 'admin') return roles.some(r => r.roleCode === 'admin');
|
if (permission === 'admin') return roles.some(r => r.roleCode === 'admin');
|
||||||
// roleCode 格式的权限直接匹配
|
|
||||||
return roles.some(r => r.roleCode === permission);
|
return roles.some(r => r.roleCode === permission);
|
||||||
};
|
}, [user]);
|
||||||
|
|
||||||
const value = {
|
const checkAdmin = useCallback(() => authAPI.checkAdmin(), []);
|
||||||
|
|
||||||
|
const value = useMemo(() => ({
|
||||||
user,
|
user,
|
||||||
token,
|
token,
|
||||||
loading,
|
loading,
|
||||||
@@ -145,8 +133,8 @@ export const AuthProvider = ({ children }) => {
|
|||||||
logout,
|
logout,
|
||||||
updateUser,
|
updateUser,
|
||||||
hasPermission,
|
hasPermission,
|
||||||
checkAdmin: () => authAPI.checkAdmin(),
|
checkAdmin,
|
||||||
};
|
}), [user, token, loading, initialized, login, register, logout, updateUser, hasPermission, checkAdmin]);
|
||||||
|
|
||||||
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
|
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
const STORAGE_PREFIX = 'idc_';
|
const STORAGE_PREFIX = 'idc_';
|
||||||
const ENCRYPTION_ENABLED = import.meta.env.PROD;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成运行时密钥(基于浏览器指纹)
|
* 生成运行时密钥(基于浏览器指纹)
|
||||||
@@ -11,7 +10,6 @@ const getOrCreateRuntimeKey = () => {
|
|||||||
let key = sessionStorage.getItem(KEY_STORAGE_ID);
|
let key = sessionStorage.getItem(KEY_STORAGE_ID);
|
||||||
if (key) return key;
|
if (key) return key;
|
||||||
|
|
||||||
// 基于浏览器特征生成指纹作为密钥种子
|
|
||||||
const fingerprint = [
|
const fingerprint = [
|
||||||
navigator.userAgent,
|
navigator.userAgent,
|
||||||
screen.width,
|
screen.width,
|
||||||
@@ -21,14 +19,12 @@ const getOrCreateRuntimeKey = () => {
|
|||||||
navigator.language,
|
navigator.language,
|
||||||
].join('|');
|
].join('|');
|
||||||
|
|
||||||
// 使用简单的哈希混合生成 32 字符密钥
|
|
||||||
let hash = 0;
|
let hash = 0;
|
||||||
for (let i = 0; i < fingerprint.length; i++) {
|
for (let i = 0; i < fingerprint.length; i++) {
|
||||||
const char = fingerprint.charCodeAt(i);
|
const char = fingerprint.charCodeAt(i);
|
||||||
hash = ((hash << 5) - hash + char) | 0;
|
hash = ((hash << 5) - hash + char) | 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生成 32 字符的随机密钥
|
|
||||||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
key = '';
|
key = '';
|
||||||
let seed = Math.abs(hash) + Date.now();
|
let seed = Math.abs(hash) + Date.now();
|
||||||
@@ -38,12 +34,11 @@ const getOrCreateRuntimeKey = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sessionStorage.setItem(KEY_STORAGE_ID, key);
|
sessionStorage.setItem(KEY_STORAGE_ID, key);
|
||||||
|
console.log('[SecureStorage] New runtime key generated:', key.substring(0, 8) + '...');
|
||||||
return key;
|
return key;
|
||||||
};
|
};
|
||||||
|
|
||||||
const simpleEncrypt = (text) => {
|
const simpleEncrypt = (text) => {
|
||||||
if (!ENCRYPTION_ENABLED) return text;
|
|
||||||
|
|
||||||
const key = getOrCreateRuntimeKey();
|
const key = getOrCreateRuntimeKey();
|
||||||
let result = '';
|
let result = '';
|
||||||
for (let i = 0; i < text.length; i++) {
|
for (let i = 0; i < text.length; i++) {
|
||||||
@@ -53,8 +48,6 @@ const simpleEncrypt = (text) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const simpleDecrypt = (encrypted) => {
|
const simpleDecrypt = (encrypted) => {
|
||||||
if (!ENCRYPTION_ENABLED) return encrypted;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const key = getOrCreateRuntimeKey();
|
const key = getOrCreateRuntimeKey();
|
||||||
const decoded = decodeURIComponent(atob(encrypted));
|
const decoded = decodeURIComponent(atob(encrypted));
|
||||||
@@ -63,7 +56,8 @@ const simpleDecrypt = (encrypted) => {
|
|||||||
result += String.fromCharCode(decoded.charCodeAt(i) ^ key.charCodeAt(i % key.length));
|
result += String.fromCharCode(decoded.charCodeAt(i) ^ key.charCodeAt(i % key.length));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} catch {
|
} catch (e) {
|
||||||
|
console.error('[SecureStorage] Decrypt error:', e.message);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -80,6 +74,8 @@ export const secureStorage = {
|
|||||||
const serialized = JSON.stringify(data);
|
const serialized = JSON.stringify(data);
|
||||||
const encrypted = simpleEncrypt(serialized);
|
const encrypted = simpleEncrypt(serialized);
|
||||||
localStorage.setItem(storageKey, encrypted);
|
localStorage.setItem(storageKey, encrypted);
|
||||||
|
console.log('[SecureStorage] Set:', key, '=', value ? value.substring(0, 30) + '...' : 'null');
|
||||||
|
console.log('[SecureStorage] Stored encrypted value length:', encrypted.length);
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[SecureStorage] Set error:', error);
|
console.error('[SecureStorage] Set error:', error);
|
||||||
@@ -92,10 +88,25 @@ export const secureStorage = {
|
|||||||
const storageKey = `${STORAGE_PREFIX}${key}`;
|
const storageKey = `${STORAGE_PREFIX}${key}`;
|
||||||
const encrypted = localStorage.getItem(storageKey);
|
const encrypted = localStorage.getItem(storageKey);
|
||||||
|
|
||||||
if (!encrypted) return null;
|
if (!encrypted) {
|
||||||
|
console.log('[SecureStorage] Get:', key, '- not found in localStorage');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const decrypted = simpleDecrypt(encrypted);
|
console.log('[SecureStorage] Get:', key, '- found encrypted data, length:', encrypted.length);
|
||||||
|
|
||||||
|
let decrypted = simpleDecrypt(encrypted);
|
||||||
if (!decrypted) {
|
if (!decrypted) {
|
||||||
|
console.log('[SecureStorage] Get:', key, '- decryption failed, trying raw JSON parse');
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(encrypted);
|
||||||
|
if (parsed && parsed.value !== undefined) {
|
||||||
|
console.log('[SecureStorage] Get:', key, '- recovered from raw JSON');
|
||||||
|
return parsed.value;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
console.log('[SecureStorage] Get:', key, '- raw JSON parse also failed');
|
||||||
|
}
|
||||||
localStorage.removeItem(storageKey);
|
localStorage.removeItem(storageKey);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -103,10 +114,13 @@ export const secureStorage = {
|
|||||||
const data = JSON.parse(decrypted);
|
const data = JSON.parse(decrypted);
|
||||||
|
|
||||||
if (data.expiry && Date.now() > data.expiry) {
|
if (data.expiry && Date.now() > data.expiry) {
|
||||||
|
console.log('[SecureStorage] Get:', key, '- expired');
|
||||||
localStorage.removeItem(storageKey);
|
localStorage.removeItem(storageKey);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const valuePreview = typeof data.value === 'string' ? data.value.substring(0, 30) + '...' : typeof data.value;
|
||||||
|
console.log('[SecureStorage] Get:', key, '- success:', valuePreview);
|
||||||
return data.value;
|
return data.value;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[SecureStorage] Get error:', error);
|
console.error('[SecureStorage] Get error:', error);
|
||||||
@@ -118,6 +132,7 @@ export const secureStorage = {
|
|||||||
try {
|
try {
|
||||||
const storageKey = `${STORAGE_PREFIX}${key}`;
|
const storageKey = `${STORAGE_PREFIX}${key}`;
|
||||||
localStorage.removeItem(storageKey);
|
localStorage.removeItem(storageKey);
|
||||||
|
console.log('[SecureStorage] Remove:', key);
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[SecureStorage] Remove error:', error);
|
console.error('[SecureStorage] Remove error:', error);
|
||||||
@@ -135,6 +150,7 @@ export const secureStorage = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
keys.forEach((key) => localStorage.removeItem(key));
|
keys.forEach((key) => localStorage.removeItem(key));
|
||||||
|
console.log('[SecureStorage] Clear: removed', keys.length, 'keys');
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[SecureStorage] Clear error:', error);
|
console.error('[SecureStorage] Clear error:', error);
|
||||||
|
|||||||
Reference in New Issue
Block a user