mirror of
https://github.com/SECTL/SecScore.git
synced 2026-07-21 18:19:03 +08:00
feat(auth): 实现 OAuth PKCE 安全流程并优化错误处理
添加 PKCE code_verifier 和 code_challenge 支持以增强 OAuth 安全性 重构 OAuth 回调处理逻辑,添加全局锁防止重复处理 优化错误处理和信息打印,增加调试日志 移除不必要的 setTimeout 包装导出功能 格式化代码以提高可读性
This commit is contained in:
@@ -76,60 +76,58 @@ export const Leaderboard: React.FC = () => {
|
||||
}
|
||||
|
||||
const handleExport = () => {
|
||||
setTimeout(() => {
|
||||
const title =
|
||||
timeRange === "today"
|
||||
? t("leaderboard.today")
|
||||
: timeRange === "week"
|
||||
? t("leaderboard.week")
|
||||
: t("leaderboard.month")
|
||||
const title =
|
||||
timeRange === "today"
|
||||
? t("leaderboard.today")
|
||||
: timeRange === "week"
|
||||
? t("leaderboard.week")
|
||||
: t("leaderboard.month")
|
||||
|
||||
const sanitizeCell = (v: unknown) => {
|
||||
if (typeof v !== "string") return v
|
||||
if (/^[=+\-@]/.test(v)) return `'${v}`
|
||||
return v
|
||||
}
|
||||
const sanitizeCell = (v: unknown) => {
|
||||
if (typeof v !== "string") return v
|
||||
if (/^[=+\-@]/.test(v)) return `'${v}`
|
||||
return v
|
||||
}
|
||||
|
||||
const sheetData = [
|
||||
[
|
||||
t("leaderboard.rank"),
|
||||
t("leaderboard.name"),
|
||||
t("leaderboard.totalScore"),
|
||||
`${title}${t("leaderboard.change")}`,
|
||||
],
|
||||
...data.map((item, index) => [
|
||||
index + 1,
|
||||
sanitizeCell(item.name),
|
||||
item.score,
|
||||
item.range_change,
|
||||
]),
|
||||
]
|
||||
const sheetData = [
|
||||
[
|
||||
t("leaderboard.rank"),
|
||||
t("leaderboard.name"),
|
||||
t("leaderboard.totalScore"),
|
||||
`${title}${t("leaderboard.change")}`,
|
||||
],
|
||||
...data.map((item, index) => [
|
||||
index + 1,
|
||||
sanitizeCell(item.name),
|
||||
item.score,
|
||||
item.range_change,
|
||||
]),
|
||||
]
|
||||
|
||||
const ws = XLSX.utils.aoa_to_sheet(sheetData)
|
||||
ws["!cols"] = [{ wch: 6 }, { wch: 14 }, { wch: 10 }, { wch: 10 }]
|
||||
const ws = XLSX.utils.aoa_to_sheet(sheetData)
|
||||
ws["!cols"] = [{ wch: 6 }, { wch: 14 }, { wch: 10 }, { wch: 10 }]
|
||||
|
||||
const wb = XLSX.utils.book_new()
|
||||
XLSX.utils.book_append_sheet(wb, ws, t("leaderboard.title"))
|
||||
const wb = XLSX.utils.book_new()
|
||||
XLSX.utils.book_append_sheet(wb, ws, t("leaderboard.title"))
|
||||
|
||||
const xlsxBytes = XLSX.write(wb, { bookType: "xlsx", type: "array" })
|
||||
const blob = new Blob([xlsxBytes], {
|
||||
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
})
|
||||
const xlsxBytes = XLSX.write(wb, { bookType: "xlsx", type: "array" })
|
||||
const blob = new Blob([xlsxBytes], {
|
||||
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
})
|
||||
|
||||
const link = document.createElement("a")
|
||||
const url = URL.createObjectURL(blob)
|
||||
link.setAttribute("href", url)
|
||||
link.setAttribute(
|
||||
"download",
|
||||
`${t("leaderboard.title")}_${timeRange}_${new Date().toISOString().slice(0, 10)}.xlsx`
|
||||
)
|
||||
link.style.visibility = "hidden"
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
URL.revokeObjectURL(url)
|
||||
messageApi.success(t("leaderboard.exportSuccess"))
|
||||
}, 0)
|
||||
const link = document.createElement("a")
|
||||
const url = URL.createObjectURL(blob)
|
||||
link.setAttribute("href", url)
|
||||
link.setAttribute(
|
||||
"download",
|
||||
`${t("leaderboard.title")}_${timeRange}_${new Date().toISOString().slice(0, 10)}.xlsx`
|
||||
)
|
||||
link.style.visibility = "hidden"
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
URL.revokeObjectURL(url)
|
||||
messageApi.success(t("leaderboard.exportSuccess"))
|
||||
}
|
||||
|
||||
const columns: ColumnsType<studentRank> = [
|
||||
|
||||
Reference in New Issue
Block a user