mirror of
https://github.com/siv-org/siv.git
synced 2026-01-09 10:27:57 -05:00
/api/malware-check: Alert admin on edge-case endpoint errors
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
|
||||
import { firebase, pushover } from '../_services'
|
||||
import { malwareCheckErrorGenerator } from './download'
|
||||
|
||||
export default async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const { auth_token, confirmed, election_id, issue_description, otp } = req.body
|
||||
@@ -14,17 +15,15 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const checkDoc = electionDoc.collection('malware-checks').doc(auth_token)
|
||||
|
||||
const check = await checkDoc.get()
|
||||
if (!check.exists) return res.status(404).json({ error: 'No malware check found' })
|
||||
const malwareCheckError = malwareCheckErrorGenerator('confirm', election_id, auth_token, otp, res)
|
||||
if (!check.exists) return malwareCheckError('No malware check found')
|
||||
|
||||
const data = check.data()
|
||||
if (!data || !data.checks || !Array.isArray(data.checks)) return res.status(404).json({ error: 'Invalid check data' })
|
||||
if (!data || !data.checks || !Array.isArray(data.checks)) return malwareCheckError('Invalid check data')
|
||||
|
||||
// Find matching check entry by OTP
|
||||
const checkEntry = data.checks.find((entry: { otp?: string }) => entry.otp === otp)
|
||||
if (!checkEntry) {
|
||||
await pushover('Malware check, confirm: Invalid OTP', `${election_id}: ${auth_token}\nOTP: ${otp}`)
|
||||
return res.status(404).json({ error: 'Invalid OTP' })
|
||||
}
|
||||
if (!checkEntry) return malwareCheckError('Invalid OTP', 401)
|
||||
|
||||
// Update the specific check entry - add confirmation
|
||||
const updatedChecks = data.checks.map((entry: { confirmations?: unknown[]; otp?: string }) => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
|
||||
import { firebase, pushover } from '../_services'
|
||||
import { firebase } from '../_services'
|
||||
import { malwareCheckErrorGenerator } from './download'
|
||||
|
||||
export default async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const { auth_token, election_id, otp } = req.body
|
||||
@@ -12,18 +13,16 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const electionDoc = firebase.firestore().collection('elections').doc(election_id)
|
||||
const checkDoc = electionDoc.collection('malware-checks').doc(auth_token)
|
||||
|
||||
const malwareCheckError = malwareCheckErrorGenerator('decrypt-success', election_id, auth_token, otp, res)
|
||||
const check = await checkDoc.get()
|
||||
if (!check.exists) return res.status(404).json({ error: 'No malware check found' })
|
||||
if (!check.exists) return malwareCheckError('No malware check found')
|
||||
|
||||
const data = check.data()
|
||||
if (!data || !data.checks || !Array.isArray(data.checks)) return res.status(404).json({ error: 'Invalid check data' })
|
||||
if (!data || !data.checks || !Array.isArray(data.checks)) return malwareCheckError('Invalid check data')
|
||||
|
||||
// Find matching check entry by OTP
|
||||
const checkEntry = data.checks.find((entry: { otp?: string }) => entry.otp === otp)
|
||||
if (!checkEntry) {
|
||||
await pushover('Malware check, decrypt success: Invalid OTP', `${election_id}: ${auth_token}\nOTP: ${otp}`)
|
||||
return res.status(404).json({ error: 'Invalid OTP' })
|
||||
}
|
||||
if (!checkEntry) return malwareCheckError('Invalid OTP', 401)
|
||||
|
||||
// Update the specific check entry
|
||||
const updatedChecks = data.checks.map((entry: { otp?: string }) => {
|
||||
|
||||
@@ -14,20 +14,16 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const checkDoc = electionDoc.collection('malware-checks').doc(auth_token)
|
||||
|
||||
const check = await checkDoc.get()
|
||||
if (!check.exists) {
|
||||
await pushover('Malware check not found', `${election_id}: ${auth_token}\nOTP: ${otp}`)
|
||||
return res.status(404).json({ error: 'No malware check found' })
|
||||
}
|
||||
|
||||
const malwareCheckError = malwareCheckErrorGenerator('download', election_id, auth_token, otp, res)
|
||||
if (!check.exists) return malwareCheckError('No malware check found')
|
||||
|
||||
const data = check.data()
|
||||
if (!data || !data.checks || !Array.isArray(data.checks)) return res.status(404).json({ error: 'Invalid check data' })
|
||||
if (!data || !data.checks || !Array.isArray(data.checks)) return malwareCheckError('Invalid check data')
|
||||
|
||||
// Find matching check entry by OTP
|
||||
const checkEntry = data.checks.find((entry: { otp?: string }) => entry.otp === otp)
|
||||
if (!checkEntry) {
|
||||
await pushover('Malware check, download: Invalid OTP', `${election_id}: ${auth_token}\nOTP: ${otp}`)
|
||||
return res.status(401).json({ error: 'Invalid OTP' })
|
||||
}
|
||||
if (!checkEntry) return malwareCheckError('Invalid OTP', 401)
|
||||
|
||||
// Check if already downloaded
|
||||
if (checkEntry.downloaded_at) {
|
||||
@@ -63,3 +59,16 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
encrypted_vote: storedEncryptedVote,
|
||||
})
|
||||
}
|
||||
|
||||
export function malwareCheckErrorGenerator(
|
||||
type: 'confirm' | 'decrypt-success' | 'download',
|
||||
election_id: string,
|
||||
auth_token: string,
|
||||
otp: string,
|
||||
res: NextApiResponse,
|
||||
) {
|
||||
return async function (error: string, errorCode = 404) {
|
||||
await pushover(`Malware check, ${type}: ${error}`, `${election_id}: ${auth_token}\nOTP: ${otp}`)
|
||||
return res.status(errorCode).json({ error })
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user