优化后端鉴权与日志安全

This commit is contained in:
yml2213
2026-05-26 08:21:11 +08:00
parent 851d1d1efc
commit dea3023825
35 changed files with 402 additions and 185 deletions
@@ -23,6 +23,7 @@ export type AdminSession = {
username: string
role: AdminRole
expiresAt: string
sessionVersion: number
}
type AdminRole = 'admin' | 'operator' | 'support'
@@ -137,12 +138,22 @@ export async function verifyAdminSessionToken(token: unknown): Promise<AdminSess
})
}
const tokenSessionVersion = Number(payload?.ver || 0)
const currentSessionVersion = normalizeAdminSessionVersion(user.session_version)
if (tokenSessionVersion !== currentSessionVersion) {
throw createHttpError('后台登录态已失效,请重新登录', {
statusCode: 401,
errorCode: 'admin_auth_stale',
})
}
return {
sessionId: String(payload?.sid || '').trim(),
userId: Number(user.id),
username: String(user.username || ''),
role: normalizeAdminRole(user.role),
expiresAt,
sessionVersion: currentSessionVersion,
}
}
@@ -248,6 +259,7 @@ export async function updateManagedAdminUserRole(
await ensureAdminUserChangeAllowed(user, { nextRole: role }, session)
const updated = await updateAdminUser(user.id, {
role,
session_version: nextAdminSessionVersion(user),
updated_at: nowIso(),
})
@@ -273,6 +285,7 @@ export async function updateManagedAdminUserStatus(
await ensureAdminUserChangeAllowed(user, { nextStatus: status }, session)
const updated = await updateAdminUser(user.id, {
status,
session_version: nextAdminSessionVersion(user),
updated_at: nowIso(),
})
@@ -295,6 +308,7 @@ export async function resetManagedAdminUserPassword(userId: number | string, pay
validatePassword(password)
const updated = await updateAdminUser(user.id, {
password_hash: hashAdminPassword(password),
session_version: nextAdminSessionVersion(user),
updated_at: nowIso(),
})
@@ -325,6 +339,7 @@ function createAdminSession(user: AdminUserRow): JsonObject {
uid: Number(user.id),
usr: String(user.username || ''),
role: normalizeAdminRole(user.role),
ver: normalizeAdminSessionVersion(user.session_version),
iat: issuedAt,
exp: expiresAt,
}
@@ -430,6 +445,15 @@ function validatePassword(password: string): void {
}
}
function normalizeAdminSessionVersion(value: unknown): number {
const parsed = Number(value)
return Number.isInteger(parsed) && parsed > 0 ? parsed : 1
}
function nextAdminSessionVersion(user: AdminUserRow): number {
return normalizeAdminSessionVersion(user.session_version) + 1
}
async function getRequiredAdminUser(userId: number | string): Promise<AdminUserRow> {
const user = await getAdminUserById(Number(userId))
@@ -86,7 +86,7 @@ export function mapKuaishouCloudFulfillmentContext(value: unknown): JsonRecord |
prepareStatus: String(binding.prepareStatus || 'pending').trim() || 'pending',
cloudSourceKey: String(binding.cloudSourceKey || '').trim(),
cloudSourceKeyFallbacks: Array.isArray(binding.cloudSourceKeyFallbacks)
? binding.cloudSourceKeyFallbacks.map((value) => String(value || '').trim()).filter(Boolean)
? binding.cloudSourceKeyFallbacks.map((value: unknown) => String(value || '').trim()).filter(Boolean)
: [],
resolvedSourceKey: String(binding.resolvedSourceKey || '').trim(),
skuId: Number(binding.skuId || 0) || 0,
@@ -95,7 +95,7 @@ function mapAdminNotificationConfig(config: JsonObject = {}) {
bark: {
enabled: bark.enabled !== false,
serverUrl: String(bark.serverUrl || 'https://api.day.app').trim(),
recipients: (Array.isArray(bark.recipients) ? bark.recipients : []).map((item) => ({
recipients: (Array.isArray(bark.recipients) ? bark.recipients : []).map((item: JsonObject) => ({
id: String(item.id || '').trim(),
name: String(item.name || '').trim(),
deviceKey: String(item.deviceKey || '').trim(),
@@ -105,7 +105,7 @@ function mapAdminNotificationConfig(config: JsonObject = {}) {
},
wpush: {
enabled: wpush.enabled !== false,
recipients: (Array.isArray(wpush.recipients) ? wpush.recipients : []).map((item) => ({
recipients: (Array.isArray(wpush.recipients) ? wpush.recipients : []).map((item: JsonObject) => ({
id: String(item.id || '').trim(),
name: String(item.name || '').trim(),
apiKey: String(item.apiKey || item.apikey || '').trim(),
@@ -146,7 +146,7 @@ function mapAdminScheduledJobsConfig(config: JsonObject = {}) {
function listAdminCloudtentaclesMonitorAccounts() {
const sourcesConfig = listCloudtentaclesSources()
const sessionsConfig = getAllCloudtentaclesSessionStates()
const sessions = sessionsConfig.sessions || {}
const sessions: Record<string, JsonObject> = sessionsConfig.sessions || {}
return (Array.isArray(sourcesConfig.sources) ? sourcesConfig.sources : []).map((source) => {
const sourceKey = String(source.key || '').trim()
@@ -171,7 +171,7 @@ export async function prepareAdminTaskKuaishouCloudFulfillment(
bindUrl: preparedBinding.bindUrl,
bindPreparedAt: now,
bindExpiresAt: resolveKuaishouCloudBindUrlExpiresAt(now),
bindProbeAt: null,
bindProbeAt: null as null,
bindProbeStatus: 'pending',
bindProbeMessage: '',
roleName: '',
@@ -181,9 +181,9 @@ export async function prepareAdminTaskKuaishouCloudFulfillment(
status: 'pending',
name: '',
rid: '',
refreshedAt: null,
refreshedAt: null as null,
errorMessage: '',
rawInfo: null,
rawInfo: null as null,
},
purchase: {
...flowWithResolvedBinding.purchase,