Merge pull request #23 from neharanadee/main

Fixes security vulnerabilites and adds html-react parser package
This commit is contained in:
Lee Stott 2022-02-10 15:03:12 +00:00 коммит произвёл GitHub
Родитель dca587daeb 0e30061946
Коммит 68036f6b09
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
18 изменённых файлов: 4709 добавлений и 10104 удалений

Просмотреть файл

@ -17,5 +17,7 @@ namespace Assessment.App.Database.Model
public List<string> Options { get; set; }
public int Answer { get; set; }
public string TextType{get;set;}
}
}

Просмотреть файл

@ -10,5 +10,7 @@ namespace Assessment.App.Functions.Student.Dto
public string Description { get; set; }
public List<string> Options { get; set; }
public int ChosenOption { get; set; }
public string TextType{get;set;}
}
}

Просмотреть файл

@ -131,6 +131,7 @@ namespace Assessment.App.Functions.Student
Description = item.Description,
Options = item.Options,
ChosenOption = chosenOption,
TextType=item.TextType
});
}

Просмотреть файл

@ -180,6 +180,8 @@ namespace Assessment.App.Functions.Teacher
Name = questionItem.Name,
Options = questionItem.Options,
LastModified = DateTime.UtcNow,
TextType = questionItem.TextType
});
return new OkObjectResult(new CreateQuestionResponse() {Id = id});
}

14735
client/package-lock.json сгенерированный

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -16,12 +16,16 @@
"fast-xml-parser": "^4.0.1",
"file-saver": "^2.0.5",
"gift-pegjs": "^0.2.1",
"html-react-parser": "^1.4.6",
"nth-check": "^2.0.1",
"react": "^17.0.2",
"react-countdown-circle-timer": "^2.5.4",
"react-dev-utils": "^12.0.0",
"react-dom": "^17.0.2",
"react-grid-system": "^7.3.1",
"react-helmet": "^6.1.0",
"react-router-dom": "^5.3.0",
"resolve-url-loader": "^5.0.0",
"typescript": "^4.4.2",
"web-vitals": "^2.1.0"
},
@ -32,13 +36,14 @@
"@testing-library/react": "^12.0.0",
"@testing-library/user-event": "^13.2.1",
"@types/file-saver": "^2.0.3",
"@types/html-to-text": "^8.0.1",
"@types/jest": "^27.0.1",
"@types/react-helmet": "^6.1.2",
"@types/react-router-dom": "^5.1.8",
"@types/selenium-webdriver": "^4.0.15",
"azure-functions-core-tools": "^3.0.3904",
"concurrently": "^6.4.0",
"react-scripts": "^4.0.3",
"react-scripts": "^5.0.0",
"selenium-webdriver": "^4.0.0-rc-1"
},
"scripts": {

Просмотреть файл

@ -1,4 +1,3 @@
import React from "react";
import {
ChoiceGroup,
IChoiceGroupOption,
@ -15,6 +14,9 @@ import {Col, Container, Row} from "react-grid-system";
const optionRootClass = mergeStyles({display: 'flex', alignItems: 'baseline'});
const textFieldStyles: Partial<ITextFieldStyles> = {fieldGroup: {width: 350}};
interface EditQuestionComponentProps {
question: Question;
setQuestion: (f: (oldValue: Question) => Question) => void;
@ -100,6 +102,24 @@ export const EditQuestionComponent = (
setQuestion(q => ({...q, description: newValue || ''}))
}
/>
</Col>
</Row>
<br/>
<Row>
<Col md={2}>
<Label style={{textAlign: "left"}}>Text format</Label>
</Col>
<Col md={6}>
<TextField
id="textType-input"
rows={1}
value={question.textType}
onChange={(_: any, newValue?: string) =>
setQuestion(q => ({...q, textType: newValue || ''}))
}
/>
</Col>
</Row>
<br/>

Просмотреть файл

@ -3,12 +3,23 @@ import {StudentQuestion} from '../model/StudentQuestion';
import {ChoiceGroup, IChoiceGroupOption} from '@fluentui/react/lib/ChoiceGroup';
import { Label } from "@fluentui/react";
import { getTheme } from '@fluentui/react';
import parse from 'html-react-parser';
interface StudentQuestionComponentProps {
question: StudentQuestion;
selectedOption: number;
setSelectedOption: (choice: number) => void;
}
var getDisplay = (x:string, texttype:string)=> {
console.log("text type is");
console.log(texttype);
if (texttype === "html" || texttype === "text/html"){
x = x.replaceAll('\\n','<br>')
return parse(x)
}
// Need to handle case where texttype is markdown
return x
}
export const StudentQuestionComponent = (
{question, selectedOption, setSelectedOption}: StudentQuestionComponentProps
@ -31,7 +42,8 @@ export const StudentQuestionComponent = (
<br/>
<div style={{margin: '30px', textAlign: 'left'}}>
<Label style={{textAlign: 'left', fontSize: '25px'}}>Question</Label>
<p>{question.description}</p>
<p>{getDisplay(question.description, question.textType)}</p>
{console.log(question)}
<ChoiceGroup
selectedKey={selectedOption.toString()}
onChange={(_: any, option) => {

Просмотреть файл

@ -188,6 +188,7 @@ export class FakeRepository implements IRepository {
lastModified: new Date(),
options: ["True", "False"],
answer: 0,
textType:"text",
},
'1': {
id: '1',
@ -200,6 +201,7 @@ export class FakeRepository implements IRepository {
"Deep learning is used in robots",
],
answer: 1,
textType:"text"
},
'2': {
id: '2',
@ -212,6 +214,7 @@ export class FakeRepository implements IRepository {
"Both of the above",
],
answer: 2,
textType:"text"
},
'3': {
id: '3',
@ -225,6 +228,7 @@ export class FakeRepository implements IRepository {
"All of the above",
],
answer: 3,
textType:"text"
},
'4': {
id: '4',
@ -238,6 +242,7 @@ export class FakeRepository implements IRepository {
"Software Models",
],
answer: 1,
textType:"text"
},
'5': {
id: '5',
@ -251,6 +256,7 @@ export class FakeRepository implements IRepository {
"5",
],
answer: 2,
textType:"text"
},
'6': {
id: '6',
@ -264,6 +270,7 @@ export class FakeRepository implements IRepository {
"Self-regulation",
],
answer: 0,
textType:"text"
},
'7': {
id: '7',
@ -277,6 +284,7 @@ export class FakeRepository implements IRepository {
"All of the above",
],
answer: 3,
textType:"text"
},
'8': {
id: '8',
@ -290,6 +298,7 @@ export class FakeRepository implements IRepository {
"All of the above",
],
answer: 3,
textType:"text"
},
}
}

Просмотреть файл

@ -5,4 +5,5 @@ export interface Question {
lastModified: Date,
options: string[],
answer: number,
textType:string,
}

Просмотреть файл

@ -4,4 +4,5 @@ export interface StudentQuestion {
description: string,
options: string[],
chosenOption: number,
textType:string,
}

Просмотреть файл

@ -2,7 +2,6 @@ import { parse, GIFTQuestion, TextChoice, TextFormat } from "gift-pegjs";
import { ParsedQuestionBank } from "./ParsedQuestionBank";
import { AssessmentAppParser } from "./Parser";
import { Question } from "../Question";
import * as React from "react";
// Currently only parses in MCQs and TFs
export class GiftParser extends AssessmentAppParser{
@ -40,6 +39,7 @@ export class GiftParser extends AssessmentAppParser{
lastModified: new Date (),
options: answerTexts,
answer: correctAnswer,
textType:stem.format
}
questions.push(question);
@ -51,10 +51,11 @@ export class GiftParser extends AssessmentAppParser{
const question: Question = {
id: "",
name: this.removeTags(stem.text),
description: this.removeTags(stem.text),
description: stem.text,
lastModified: new Date (),
options: ["True", "False"],
answer: ans? 0:1,
textType:stem.format
}
questions.push(question);
}

Просмотреть файл

@ -17,8 +17,6 @@ export class MicrosoftOSCParser extends AssessmentAppParser{
var answerTexts = Array();
var correctAnswer = 0;
var counter = 0;
console.log("Read a new question");
console.log(question.questionText);
for (let option of question.answerOptions){
answerTexts.push(option.answerText)
if (option.isCorrect == "true"){
@ -35,6 +33,7 @@ export class MicrosoftOSCParser extends AssessmentAppParser{
lastModified: new Date (),
options: answerTexts,
answer: correctAnswer,
textType:"text"
}
questions.push(questionToSave);
}

Просмотреть файл

@ -16,6 +16,7 @@ export class OriginalAppParser extends AssessmentAppParser{
lastModified: new Date (),
options: rawQuestion.options,
answer: rawQuestion.answer,
textType: rawQuestion.textType
}
questions.push(question);
}

Просмотреть файл

@ -26,7 +26,6 @@ export class QTIParser extends AssessmentAppParser{
continue; // As we currently only support MCQs
}
var questionText = currQuestion['presentation']['material']['mattext']['#text'];
questionText = this.removeTags(questionText); // Clean any html tags
questionText = questionText.split('\n')[1];
// Get all options
@ -48,6 +47,7 @@ export class QTIParser extends AssessmentAppParser{
lastModified: new Date (),
options: answerTexts,
answer: correctAnswer,
textType:currQuestion['presentation']['material']['mattext']['@_texttype'],
}
questions.push(question);

Просмотреть файл

@ -21,6 +21,7 @@ export const NewQuestionPage = () => {
lastModified: new Date(),
options: ['', ''],
answer: -1,
textType:""
});
const {bankId} = useParams<NewQuestionPageParams>();
const repositoryContext = React.useContext(RepositoryContext);

Просмотреть файл

@ -23,6 +23,7 @@ export const QuestionPage = () => {
lastModified: new Date(),
options: ['', ''],
answer: -1,
textType:"text"
});
const [savedQuestion, setSavedQuestion] = useState<Question>({
id: "",
@ -31,6 +32,7 @@ export const QuestionPage = () => {
lastModified: new Date(),
options: ['', ''],
answer: -1,
textType:"text"
})
const {id} = useParams<QuestionPageParams>();
const repositoryContext = React.useContext(RepositoryContext);

3
package-lock.json сгенерированный
Просмотреть файл

@ -1,3 +0,0 @@
{
"lockfileVersion": 1
}