From f604c11a2a153b6073dca274b21105d0073523f7 Mon Sep 17 00:00:00 2001 From: Kenneth Seet <120318851+itstrueitstrueitsrealitsreal@users.noreply.github.com> Date: Sat, 6 Jul 2024 04:20:16 +0800 Subject: [PATCH 1/2] [#12872] Warn instructors not to share link with students (#13137) * Add caution to template and change tests * Update tests * Fix failing test * Change phrasing * Fix typo * Modify email template and tests * Fix typo --- src/main/java/teammates/logic/api/EmailGenerator.java | 10 +++++++--- .../java/teammates/sqllogic/api/SqlEmailGenerator.java | 10 +++++++--- ...instructorEmailFragment-instructorCopyPreamble.html | 8 ++++++++ .../emails/sessionClosingEmailCopyToInstructor.html | 8 ++++++++ ...losingEmailTestingSanitizationCopyToInstructor.html | 8 ++++++++ .../emails/sessionOpeningEmailCopyToInstructor.html | 8 ++++++++ ...peningEmailTestingSanitizationCopyToInstructor.html | 8 ++++++++ .../emails/sessionPublishedEmailCopyToInstructor.html | 8 ++++++++ .../emails/sessionReminderEmailCopyToInstructor.html | 8 ++++++++ .../sessionUnpublishedEmailCopyToInstructor.html | 8 ++++++++ 10 files changed, 78 insertions(+), 6 deletions(-) diff --git a/src/main/java/teammates/logic/api/EmailGenerator.java b/src/main/java/teammates/logic/api/EmailGenerator.java index e72708aa267..d7a6165b599 100644 --- a/src/main/java/teammates/logic/api/EmailGenerator.java +++ b/src/main/java/teammates/logic/api/EmailGenerator.java @@ -823,7 +823,7 @@ private EmailWrapper generateFeedbackSessionEmailBaseForNotifiedInstructors( "${feedbackSessionName}", SanitizationHelper.sanitizeForHtml(session.getFeedbackSessionName()), "${deadline}", SanitizationHelper.sanitizeForHtml( TimeHelper.formatInstant(endTime, session.getTimeZone(), DATETIME_DISPLAY_FORMAT)), - "${instructorPreamble}", fillUpInstructorPreamble(course), + "${instructorPreamble}", fillUpInstructorPreamble(course, session), "${sessionInstructions}", session.getInstructionsString(), "${submitUrl}", "{in the actual email sent to the students, this will be the unique link}", "${reportUrl}", "{in the actual email sent to the students, this will be the unique link}", @@ -1020,10 +1020,14 @@ private String fillUpInstructorRejoinAfterGoogleIdResetFragment(InstructorAttrib "${supportEmail}", Config.SUPPORT_EMAIL); } - private String fillUpInstructorPreamble(CourseAttributes course) { + private String fillUpInstructorPreamble(CourseAttributes course, FeedbackSessionAttributes session) { + var recoveryUrl = Config.getFrontEndAppUrl(Const.WebPageURIs.SESSIONS_LINK_RECOVERY_PAGE).toAbsoluteString(); return Templates.populateTemplate(EmailTemplates.FRAGMENT_INSTRUCTOR_COPY_PREAMBLE, "${courseId}", SanitizationHelper.sanitizeForHtml(course.getId()), - "${courseName}", SanitizationHelper.sanitizeForHtml(course.getName())); + "${courseName}", SanitizationHelper.sanitizeForHtml(course.getName()), + "${feedbackSessionName}", + SanitizationHelper.sanitizeForHtml(session.getFeedbackSessionName()), + "${sessionsRecoveryLink}", recoveryUrl); } /** diff --git a/src/main/java/teammates/sqllogic/api/SqlEmailGenerator.java b/src/main/java/teammates/sqllogic/api/SqlEmailGenerator.java index 6e9683f5213..322a4459c9c 100644 --- a/src/main/java/teammates/sqllogic/api/SqlEmailGenerator.java +++ b/src/main/java/teammates/sqllogic/api/SqlEmailGenerator.java @@ -851,7 +851,7 @@ private EmailWrapper generateFeedbackSessionEmailBaseForNotifiedInstructors( "${feedbackSessionName}", SanitizationHelper.sanitizeForHtml(session.getName()), "${deadline}", SanitizationHelper.sanitizeForHtml( TimeHelper.formatInstant(endTime, session.getCourse().getTimeZone(), DATETIME_DISPLAY_FORMAT)), - "${instructorPreamble}", fillUpInstructorPreamble(course), + "${instructorPreamble}", fillUpInstructorPreamble(course, session), "${sessionInstructions}", session.getInstructionsString(), "${submitUrl}", "{in the actual email sent to the students, this will be the unique link}", "${reportUrl}", "{in the actual email sent to the students, this will be the unique link}", @@ -1098,10 +1098,14 @@ private String fillUpInstructorRejoinAfterGoogleIdResetFragment(Instructor instr "${supportEmail}", Config.SUPPORT_EMAIL); } - private String fillUpInstructorPreamble(Course course) { + private String fillUpInstructorPreamble(Course course, FeedbackSession session) { + var recoveryUrl = Config.getFrontEndAppUrl(Const.WebPageURIs.SESSIONS_LINK_RECOVERY_PAGE).toAbsoluteString(); + return Templates.populateTemplate(EmailTemplates.FRAGMENT_INSTRUCTOR_COPY_PREAMBLE, "${courseId}", SanitizationHelper.sanitizeForHtml(course.getId()), - "${courseName}", SanitizationHelper.sanitizeForHtml(course.getName())); + "${courseName}", SanitizationHelper.sanitizeForHtml(course.getName()), + "${feedbackSessionName}", SanitizationHelper.sanitizeForHtml(session.getName()), + "${sessionsRecoveryLink}", recoveryUrl); } /** diff --git a/src/main/resources/instructorEmailFragment-instructorCopyPreamble.html b/src/main/resources/instructorEmailFragment-instructorCopyPreamble.html index 416b2d0329d..82708830ce5 100644 --- a/src/main/resources/instructorEmailFragment-instructorCopyPreamble.html +++ b/src/main/resources/instructorEmailFragment-instructorCopyPreamble.html @@ -1,4 +1,12 @@

+ Kindly note that this email simply serves as a preview of how the email will appear to the + students, and the link is not the actual link that the students will receive. + As such, please do not forward this email to students. + We recommend that you make the following announcement (edit content as you see fit) using an alternative means (e.g., your course announcements) to alert students: +


+ The TEAMMATES session ${feedbackSessionName} in course [${courseId}] ${courseName} is now open. + If you did not receive the unique access link via email, and you can't find it in your spam box either, go to this link to recover the access link. +
The email below has been sent to students of course: [${courseId}] ${courseName}.

=== Email message as seen by the students === diff --git a/src/test/resources/emails/sessionClosingEmailCopyToInstructor.html b/src/test/resources/emails/sessionClosingEmailCopyToInstructor.html index 28e230525fe..f9416466212 100644 --- a/src/test/resources/emails/sessionClosingEmailCopyToInstructor.html +++ b/src/test/resources/emails/sessionClosingEmailCopyToInstructor.html @@ -1,6 +1,14 @@

Hello Instructor1 Course1,

+ Kindly note that this email simply serves as a preview of how the email will appear to the + students, and the link is not the actual link that the students will receive. + As such, please do not forward this email to students. + We recommend that you make the following announcement (edit content as you see fit) using an alternative means (e.g., your course announcements) to alert students: +


+ The TEAMMATES session First feedback session in course [idOfTypicalCourse1] Typical Course 1 with 2 Evals is now open. + If you did not receive the unique access link via email, and you can't find it in your spam box either, go to this link to recover the access link. +
The email below has been sent to students of course: [idOfTypicalCourse1] Typical Course 1 with 2 Evals.

=== Email message as seen by the students === diff --git a/src/test/resources/emails/sessionClosingEmailTestingSanitizationCopyToInstructor.html b/src/test/resources/emails/sessionClosingEmailTestingSanitizationCopyToInstructor.html index 93225e513b0..9c301cae53c 100644 --- a/src/test/resources/emails/sessionClosingEmailTestingSanitizationCopyToInstructor.html +++ b/src/test/resources/emails/sessionClosingEmailTestingSanitizationCopyToInstructor.html @@ -1,6 +1,14 @@

Hello Instructor<script> alert('hi!'); </script>,

+ Kindly note that this email simply serves as a preview of how the email will appear to the + students, and the link is not the actual link that the students will receive. + As such, please do not forward this email to students. + We recommend that you make the following announcement (edit content as you see fit) using an alternative means (e.g., your course announcements) to alert students: +


+ The TEAMMATES session Normal feedback session name in course [idOfTestingSanitizationCourse] Testing<script> alert('hi!'); </script> is now open. + If you did not receive the unique access link via email, and you can't find it in your spam box either, go to this link to recover the access link. +
The email below has been sent to students of course: [idOfTestingSanitizationCourse] Testing<script> alert('hi!'); </script>.

=== Email message as seen by the students === diff --git a/src/test/resources/emails/sessionOpeningEmailCopyToInstructor.html b/src/test/resources/emails/sessionOpeningEmailCopyToInstructor.html index feba86d7794..e4609cb333c 100644 --- a/src/test/resources/emails/sessionOpeningEmailCopyToInstructor.html +++ b/src/test/resources/emails/sessionOpeningEmailCopyToInstructor.html @@ -1,6 +1,14 @@

Hello Instructor1 Course1,

+ Kindly note that this email simply serves as a preview of how the email will appear to the + students, and the link is not the actual link that the students will receive. + As such, please do not forward this email to students. + We recommend that you make the following announcement (edit content as you see fit) using an alternative means (e.g., your course announcements) to alert students: +


+ The TEAMMATES session First feedback session in course [idOfTypicalCourse1] Typical Course 1 with 2 Evals is now open. + If you did not receive the unique access link via email, and you can't find it in your spam box either, go to this link to recover the access link. +
The email below has been sent to students of course: [idOfTypicalCourse1] Typical Course 1 with 2 Evals.

=== Email message as seen by the students === diff --git a/src/test/resources/emails/sessionOpeningEmailTestingSanitizationCopyToInstructor.html b/src/test/resources/emails/sessionOpeningEmailTestingSanitizationCopyToInstructor.html index 764f6871064..440e5d80ec5 100644 --- a/src/test/resources/emails/sessionOpeningEmailTestingSanitizationCopyToInstructor.html +++ b/src/test/resources/emails/sessionOpeningEmailTestingSanitizationCopyToInstructor.html @@ -1,6 +1,14 @@

Hello Instructor<script> alert('hi!'); </script>,

+ Kindly note that this email simply serves as a preview of how the email will appear to the + students, and the link is not the actual link that the students will receive. + As such, please do not forward this email to students. + We recommend that you make the following announcement (edit content as you see fit) using an alternative means (e.g., your course announcements) to alert students: +


+ The TEAMMATES session Normal feedback session name in course [idOfTestingSanitizationCourse] Testing<script> alert('hi!'); </script> is now open. + If you did not receive the unique access link via email, and you can't find it in your spam box either, go to this link to recover the access link. +
The email below has been sent to students of course: [idOfTestingSanitizationCourse] Testing<script> alert('hi!'); </script>.

=== Email message as seen by the students === diff --git a/src/test/resources/emails/sessionPublishedEmailCopyToInstructor.html b/src/test/resources/emails/sessionPublishedEmailCopyToInstructor.html index f0892ba556a..93a87661bd9 100644 --- a/src/test/resources/emails/sessionPublishedEmailCopyToInstructor.html +++ b/src/test/resources/emails/sessionPublishedEmailCopyToInstructor.html @@ -1,6 +1,14 @@

Hello Instructor1 Course1,

+ Kindly note that this email simply serves as a preview of how the email will appear to the + students, and the link is not the actual link that the students will receive. + As such, please do not forward this email to students. + We recommend that you make the following announcement (edit content as you see fit) using an alternative means (e.g., your course announcements) to alert students: +


+ The TEAMMATES session First feedback session in course [idOfTypicalCourse1] Typical Course 1 with 2 Evals is now open. + If you did not receive the unique access link via email, and you can't find it in your spam box either, go to this link to recover the access link. +
The email below has been sent to students of course: [idOfTypicalCourse1] Typical Course 1 with 2 Evals.

=== Email message as seen by the students === diff --git a/src/test/resources/emails/sessionReminderEmailCopyToInstructor.html b/src/test/resources/emails/sessionReminderEmailCopyToInstructor.html index 0ebbf71fa27..d4c31609da6 100644 --- a/src/test/resources/emails/sessionReminderEmailCopyToInstructor.html +++ b/src/test/resources/emails/sessionReminderEmailCopyToInstructor.html @@ -1,6 +1,14 @@

Hello Instructor1 Course1,

+ Kindly note that this email simply serves as a preview of how the email will appear to the + students, and the link is not the actual link that the students will receive. + As such, please do not forward this email to students. + We recommend that you make the following announcement (edit content as you see fit) using an alternative means (e.g., your course announcements) to alert students: +


+ The TEAMMATES session First feedback session in course [idOfTypicalCourse1] Typical Course 1 with 2 Evals is now open. + If you did not receive the unique access link via email, and you can't find it in your spam box either, go to this link to recover the access link. +
The email below has been sent to students of course: [idOfTypicalCourse1] Typical Course 1 with 2 Evals.

=== Email message as seen by the students === diff --git a/src/test/resources/emails/sessionUnpublishedEmailCopyToInstructor.html b/src/test/resources/emails/sessionUnpublishedEmailCopyToInstructor.html index 9f5c8902d57..57f882f777a 100644 --- a/src/test/resources/emails/sessionUnpublishedEmailCopyToInstructor.html +++ b/src/test/resources/emails/sessionUnpublishedEmailCopyToInstructor.html @@ -1,6 +1,14 @@

Hello Instructor1 Course1,

+ Kindly note that this email simply serves as a preview of how the email will appear to the + students, and the link is not the actual link that the students will receive. + As such, please do not forward this email to students. + We recommend that you make the following announcement (edit content as you see fit) using an alternative means (e.g., your course announcements) to alert students: +


+ The TEAMMATES session First feedback session in course [idOfTypicalCourse1] Typical Course 1 with 2 Evals is now open. + If you did not receive the unique access link via email, and you can't find it in your spam box either, go to this link to recover the access link. +
The email below has been sent to students of course: [idOfTypicalCourse1] Typical Course 1 with 2 Evals.

=== Email message as seen by the students === From 836f63729859061b97f8b653806f14e433801c76 Mon Sep 17 00:00:00 2001 From: Rayson Yeap <88478542+Respirayson@users.noreply.github.com> Date: Sun, 7 Jul 2024 11:19:38 +0800 Subject: [PATCH 2/2] [#12578] `@` sign is shown as `@` when viewing essay question submission page (#13142) * Add decoding html entity functionality * Add unit tests --------- Co-authored-by: domoberzin <74132255+domoberzin@users.noreply.github.com> --- ...t-question-edit-answer-form.component.html | 2 +- ...uestion-edit-answer-form.component.spec.ts | 24 +++++++++++++++++++ ...ext-question-edit-answer-form.component.ts | 10 ++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/web/app/components/question-types/question-edit-answer-form/text-question-edit-answer-form.component.html b/src/web/app/components/question-types/question-edit-answer-form/text-question-edit-answer-form.component.html index bc9a583b9bf..5893d2ba784 100644 --- a/src/web/app/components/question-types/question-edit-answer-form/text-question-edit-answer-form.component.html +++ b/src/web/app/components/question-types/question-edit-answer-form/text-question-edit-answer-form.component.html @@ -1,5 +1,5 @@
- +
diff --git a/src/web/app/components/question-types/question-edit-answer-form/text-question-edit-answer-form.component.spec.ts b/src/web/app/components/question-types/question-edit-answer-form/text-question-edit-answer-form.component.spec.ts index c15aba100cd..555268b40b6 100644 --- a/src/web/app/components/question-types/question-edit-answer-form/text-question-edit-answer-form.component.spec.ts +++ b/src/web/app/components/question-types/question-edit-answer-form/text-question-edit-answer-form.component.spec.ts @@ -2,6 +2,7 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { FormsModule } from '@angular/forms'; import { TextQuestionEditAnswerFormComponent } from './text-question-edit-answer-form.component'; +import { FeedbackQuestionType } from '../../../../types/api-request'; import { RichTextEditorModule } from '../../rich-text-editor/rich-text-editor.module'; describe('TextQuestionEditAnswerFormComponent', () => { @@ -22,10 +23,33 @@ describe('TextQuestionEditAnswerFormComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(TextQuestionEditAnswerFormComponent); component = fixture.componentInstance; + component.questionDetails = { + shouldAllowRichText: false, + questionType: FeedbackQuestionType.TEXT, + questionText: 'Sample question', + recommendedLength: 50, + }; + component.responseDetails = { answer: '', questionType: FeedbackQuestionType.TEXT }; fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); + + it('should decode HTML entities for @ sign in plain-text mode', () => { + component.questionDetails.shouldAllowRichText = false; + component.responseDetails.answer = 'Test @ symbol'; + fixture.detectChanges(); + + expect(component.decodedAnswer).toBe('Test @ symbol'); + }); + + it('should decode HTML entities for apostrophe in plain-text mode', () => { + component.questionDetails.shouldAllowRichText = false; + component.responseDetails.answer = 'It's a test'; + fixture.detectChanges(); + + expect(component.decodedAnswer).toBe("It's a test"); + }); }); diff --git a/src/web/app/components/question-types/question-edit-answer-form/text-question-edit-answer-form.component.ts b/src/web/app/components/question-types/question-edit-answer-form/text-question-edit-answer-form.component.ts index 670b1659d89..ce5f5613016 100644 --- a/src/web/app/components/question-types/question-edit-answer-form/text-question-edit-answer-form.component.ts +++ b/src/web/app/components/question-types/question-edit-answer-form/text-question-edit-answer-form.component.ts @@ -26,6 +26,12 @@ export class TextQuestionEditAnswerFormComponent super(DEFAULT_TEXT_QUESTION_DETAILS(), DEFAULT_TEXT_RESPONSE_DETAILS()); } + decodeHtml(html: string): string { + const txt = document.createElement('textarea'); + txt.innerHTML = html; + return txt.value; + } + get wordCount(): number { return this.responseDetails.answer.split(/\s/g) .filter((item: string) => item.match(/\w/)).length; @@ -41,4 +47,8 @@ export class TextQuestionEditAnswerFormComponent return this.wordCount > lowerLimit && this.wordCount < upperLimit; } + + get decodedAnswer(): string { + return this.decodeHtml(this.responseDetails.answer); + } }