fix: restore security hardening compatibility and validation

Restore authorized rule reveal, explicit full HTTP capture and retention, video task business fields, and valid payment URLs. Add opt-in credential preservation for trusted recovery, fix frontend type contracts and async races, and eliminate PostgreSQL test fixture resource leaks. Document audit coverage and successful fmt and CI-scoped Clippy checks.
This commit is contained in:
elky
2026-09-07 21:14:27 +08:00
parent a5c3699ae9
commit a90d564931
191 changed files with 6785 additions and 1643 deletions
+10 -10
View File
@@ -57,61 +57,61 @@ export const announcementApi = {
limit?: number
offset?: number
}): Promise<AnnouncementListResponse> {
const response = await apiClient.get('/api/announcements', { params })
const response = await apiClient.get<AnnouncementListResponse>('/api/announcements', { params })
return response.data
},
// 获取当前有效的公告
async getActiveAnnouncements(): Promise<AnnouncementListResponse> {
const response = await apiClient.get('/api/announcements/active')
const response = await apiClient.get<AnnouncementListResponse>('/api/announcements/active')
return response.data
},
// 获取单个公告
async getAnnouncement(id: string): Promise<Announcement> {
const response = await apiClient.get(`/api/announcements/${id}`)
const response = await apiClient.get<Announcement>(`/api/announcements/${id}`)
return response.data
},
// 标记公告为已读
async markAsRead(id: string): Promise<{ message: string }> {
const response = await apiClient.patch(`/api/announcements/${id}/read-status`)
const response = await apiClient.patch<{ message: string }>(`/api/announcements/${id}/read-status`)
return response.data
},
// 标记所有公告为已读
async markAllAsRead(): Promise<{ message: string }> {
const response = await apiClient.post('/api/announcements/read-all')
const response = await apiClient.post<{ message: string }>('/api/announcements/read-all')
return response.data
},
// 获取未读公告数量
async getUnreadCount(): Promise<{ unread_count: number }> {
const response = await apiClient.get('/api/announcements/users/me/unread-count')
const response = await apiClient.get<{ unread_count: number }>('/api/announcements/users/me/unread-count')
return response.data
},
async getRequiredUnreadAnnouncements(): Promise<AnnouncementListResponse> {
const response = await apiClient.get('/api/announcements/users/me/required-unread')
const response = await apiClient.get<AnnouncementListResponse>('/api/announcements/users/me/required-unread')
return response.data
},
// 管理员方法
// 创建公告
async createAnnouncement(data: CreateAnnouncementRequest): Promise<{ id: string; title: string; message: string }> {
const response = await apiClient.post('/api/announcements', data)
const response = await apiClient.post<{ id: string; title: string; message: string }>('/api/announcements', data)
return response.data
},
// 更新公告
async updateAnnouncement(id: string, data: UpdateAnnouncementRequest): Promise<{ message: string }> {
const response = await apiClient.put(`/api/announcements/${id}`, data)
const response = await apiClient.put<{ message: string }>(`/api/announcements/${id}`, data)
return response.data
},
// 删除公告
async deleteAnnouncement(id: string): Promise<{ message: string }> {
const response = await apiClient.delete(`/api/announcements/${id}`)
const response = await apiClient.delete<{ message: string }>(`/api/announcements/${id}`)
return response.data
}
}