feat(api): implement chestny-znak web app with True API integration
- Fastify backend with auth (CryptoPro CAdES-BES), KM check, UPD parsing - React frontend with auth page, code check, XML upload, results table - Client-side signing via crypto-pro 2.3.0 (browser plugin) - Token caching with auto-refresh, retry with exponential backoff - Input validation schemas, file size limits, global 401 interceptor - Docker compose with backend + frontend (nginx) services
This commit is contained in:
+25
-13
@@ -1,6 +1,6 @@
|
||||
import type { FastifyInstance } from 'fastify'
|
||||
import { parseUpdXml } from '../services/upd-parser.js'
|
||||
import { checkCodesAuth } from '../services/cises-service.js'
|
||||
import { checkCodesAuth, AppError } from '../services/cises-service.js'
|
||||
|
||||
export async function updRoutes(app: FastifyInstance): Promise<void> {
|
||||
app.post('/api/upload-upd', async (request, reply) => {
|
||||
@@ -13,24 +13,36 @@ export async function updRoutes(app: FastifyInstance): Promise<void> {
|
||||
const xmlContent = buffer.toString('utf-8')
|
||||
const fileName = data.filename
|
||||
|
||||
const parsed = await parseUpdXml(xmlContent, fileName)
|
||||
let parsed
|
||||
try {
|
||||
parsed = await parseUpdXml(xmlContent, fileName)
|
||||
} catch {
|
||||
return reply.status(400).send({ error: 'Invalid XML file' })
|
||||
}
|
||||
|
||||
if (parsed.codes.length === 0) {
|
||||
return reply.status(400).send({ error: 'No marking codes found in UPD' })
|
||||
}
|
||||
|
||||
const checkResults = await checkCodesAuth({ codes: parsed.codes })
|
||||
try {
|
||||
const checkResults = await checkCodesAuth({ codes: parsed.codes })
|
||||
|
||||
return {
|
||||
document: {
|
||||
number: parsed.documentNumber,
|
||||
date: parsed.documentDate,
|
||||
seller: parsed.sellerName,
|
||||
buyer: parsed.buyerName,
|
||||
fileName: parsed.fileName,
|
||||
},
|
||||
codesFound: parsed.codes.length,
|
||||
results: checkResults,
|
||||
return {
|
||||
document: {
|
||||
number: parsed.documentNumber,
|
||||
date: parsed.documentDate,
|
||||
seller: parsed.sellerName,
|
||||
buyer: parsed.buyerName,
|
||||
fileName: parsed.fileName,
|
||||
},
|
||||
codesFound: parsed.codes.length,
|
||||
results: checkResults,
|
||||
}
|
||||
} catch (err) {
|
||||
if (err instanceof AppError) {
|
||||
return reply.status(err.statusCode).send({ error: err.message })
|
||||
}
|
||||
throw err
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user