juice-shop
98 строк · 2.6 Кб
1import { type NextFunction, type Request, type Response } from 'express'
2import * as accuracy from '../lib/accuracy'
3
4const challengeUtils = require('../lib/challengeUtils')
5const fs = require('fs')
6const yaml = require('js-yaml')
7
8const FixesDir = 'data/static/codefixes'
9
10interface codeFix {
11fixes: string[]
12correct: number
13}
14
15type cache = Record<string, codeFix>
16
17const CodeFixes: cache = {}
18
19export const readFixes = (key: string) => {
20if (CodeFixes[key]) {
21return CodeFixes[key]
22}
23const files = fs.readdirSync(FixesDir)
24const fixes: string[] = []
25let correct: number = -1
26for (const file of files) {
27if (file.startsWith(`${key}_`)) {
28const fix = fs.readFileSync(`${FixesDir}/${file}`).toString()
29const metadata = file.split('_')
30const number = metadata[1]
31fixes.push(fix)
32if (metadata.length === 3) {
33correct = parseInt(number, 10)
34correct--
35}
36}
37}
38
39CodeFixes[key] = {
40fixes,
41correct
42}
43return CodeFixes[key]
44}
45
46interface FixesRequestParams {
47key: string
48}
49
50interface VerdictRequestBody {
51key: string
52selectedFix: number
53}
54
55export const serveCodeFixes = () => (req: Request<FixesRequestParams, Record<string, unknown>, Record<string, unknown>>, res: Response, next: NextFunction) => {
56const key = req.params.key
57const fixData = readFixes(key)
58if (fixData.fixes.length === 0) {
59res.status(404).json({
60error: 'No fixes found for the snippet!'
61})
62return
63}
64res.status(200).json({
65fixes: fixData.fixes
66})
67}
68
69export const checkCorrectFix = () => async (req: Request<Record<string, unknown>, Record<string, unknown>, VerdictRequestBody>, res: Response, next: NextFunction) => {
70const key = req.body.key
71const selectedFix = req.body.selectedFix
72const fixData = readFixes(key)
73if (fixData.fixes.length === 0) {
74res.status(404).json({
75error: 'No fixes found for the snippet!'
76})
77} else {
78let explanation
79if (fs.existsSync('./data/static/codefixes/' + key + '.info.yml')) {
80const codingChallengeInfos = yaml.load(fs.readFileSync('./data/static/codefixes/' + key + '.info.yml', 'utf8'))
81const selectedFixInfo = codingChallengeInfos?.fixes.find(({ id }: { id: number }) => id === selectedFix + 1)
82if (selectedFixInfo?.explanation) explanation = res.__(selectedFixInfo.explanation)
83}
84if (selectedFix === fixData.correct) {
85await challengeUtils.solveFixIt(key)
86res.status(200).json({
87verdict: true,
88explanation
89})
90} else {
91accuracy.storeFixItVerdict(key, false)
92res.status(200).json({
93verdict: false,
94explanation
95})
96}
97}
98}
99