diff --git a/ansible/roles/schulcloud-client-core/templates/deployment.yml.j2 b/ansible/roles/schulcloud-client-core/templates/deployment.yml.j2 index a112fb178f..d4a237bbad 100644 --- a/ansible/roles/schulcloud-client-core/templates/deployment.yml.j2 +++ b/ansible/roles/schulcloud-client-core/templates/deployment.yml.j2 @@ -5,6 +5,13 @@ metadata: namespace: {{ NAMESPACE }} labels: app: client + app.kubernetes.io/part-of: schulcloud-verbund + app.kubernetes.io/version: {{ SCHULCLOUD_CLIENT_IMAGE_TAG }} + app.kubernetes.io/name: client + app.kubernetes.io/component: client + app.kubernetes.io/managed-by: ansible + git.branch: {{ SCHULCLOUD_CLIENT_BRANCH_NAME }} + git.repo: {{ SCHULCLOUD_CLIENT_REPO_NAME }} spec: replicas: {{ CLIENT_REPLICAS|default("1", true) }} strategy: @@ -21,9 +28,16 @@ spec: metadata: labels: app: client + app.kubernetes.io/part-of: schulcloud-verbund + app.kubernetes.io/version: {{ SCHULCLOUD_CLIENT_IMAGE_TAG }} + app.kubernetes.io/name: client + app.kubernetes.io/component: client + app.kubernetes.io/managed-by: ansible + git.branch: {{ SCHULCLOUD_CLIENT_BRANCH_NAME }} + git.repo: {{ SCHULCLOUD_CLIENT_REPO_NAME }} annotations: spec: - securityContext: + securityContext: runAsUser: 1000 runAsGroup: 1000 fsGroup: 1000 diff --git a/config/default.schema.json b/config/default.schema.json index 669fad5355..54a54a0195 100644 --- a/config/default.schema.json +++ b/config/default.schema.json @@ -64,14 +64,14 @@ "type": "string", "description": "comma separated list of roles which GLOBAL_ANNOUNCEMENT_TEXT is shown to" }, - "BETTERMARKS_ANNOUNCEMENT_ENABLED": { + "DASHBOARD_ANNOUNCEMENT_ENABLED": { "type": "boolean", "default": false, - "description": "enbale bettermarks announcement, shown to all user roles specified in BETTERMARKS_ANNOUNCEMENT_ROLES" + "description": "enbale announcement on dashboard, shown to all user roles specified in DASHBOARD_ANNOUNCEMENT_ROLES" }, - "BETTERMARKS_ANNOUNCEMENT_ROLES": { + "DASHBOARD_ANNOUNCEMENT_ROLES": { "type": "string", - "description": "comma separated list of roles which bettermarks announcement is shown to" + "description": "comma separated list of roles which dashboard announcement is shown to" }, "GLOBAL_LOGIN_ANNOUNCEMENT_TYPE": { "type": "string", @@ -593,6 +593,11 @@ "default": false, "description": "Changes the login flow to one that supports user login migrations" }, + "FEATURE_H5P_EDITOR_ENABLED": { + "type": "boolean", + "default": false, + "description": "If enabled, adds H5P editor to course topics." + }, "FEATURE_SHOW_NEW_CLASS_VIEW_ENABLED": { "type": "boolean", "default": false, @@ -602,6 +607,11 @@ "type": "boolean", "default": false, "description": "Enables to get groups of type class in courses" + }, + "FEATURE_NEST_SYSTEMS_API_ENABLED": { + "type": "boolean", + "default": true, + "description": "Uses the v3 api over the v1 api for systems" } }, "allOf": [ diff --git a/config/global.js b/config/global.js index 738efbfe1a..38a81cdfb4 100644 --- a/config/global.js +++ b/config/global.js @@ -41,6 +41,7 @@ const { FEATURE_BUTTONS_ON_LOGINPAGE_ENABLED, FEATURE_SHOW_NEW_CLASS_VIEW_ENABLED, FEATURE_GROUPS_IN_COURSE_ENABLED, + FEATURE_NEST_SYSTEMS_API_ENABLED, } = process.env; const exp = { @@ -84,6 +85,7 @@ const exp = { FEATURE_BUTTONS_ON_LOGINPAGE_ENABLED, FEATURE_SHOW_NEW_CLASS_VIEW_ENABLED, FEATURE_GROUPS_IN_COURSE_ENABLED, + FEATURE_NEST_SYSTEMS_API_ENABLED, }; // eslint-disable-next-line no-console diff --git a/controllers/administration.js b/controllers/administration.js index 36f50e2fcf..586f3431d9 100644 --- a/controllers/administration.js +++ b/controllers/administration.js @@ -21,7 +21,7 @@ const timesHelper = require('../helpers/timesHelper'); const router = express.Router(); const upload = multer({ storage: multer.memoryStorage() }); -const { HOST, CONSENT_WITHOUT_PARENTS_MIN_AGE_YEARS } = require('../config/global'); +const { HOST, CONSENT_WITHOUT_PARENTS_MIN_AGE_YEARS, FEATURE_NEST_SYSTEMS_API_ENABLED } = require('../config/global'); const { isUserHidden } = require('../helpers/users'); // eslint-disable-next-line no-unused-vars @@ -466,8 +466,8 @@ const getDetailHandler = (service) => function detailHandler(req, res, next) { .catch(next); }; -const getDeleteHandler = (service, redirectUrl) => function deleteHandler(req, res, next) { - api(req) +const getDeleteHandler = (service, redirectUrl, apiVersion = 'v1') => function deleteHandler(req, res, next) { + api(req, { version: apiVersion }) .delete(`/${service}/${req.params.id}`) .then(() => { if (redirectUrl) { @@ -1617,7 +1617,8 @@ const renderClassEdit = (req, res, next) => { class: currentClass, gradeLevels, isCustom, - referrer: '/administration/classes/', + referrer: Configuration.get('FEATURE_SHOW_NEW_CLASS_VIEW_ENABLED') + ? '/administration/groups/classes/' : '/administration/classes/', }); }, ); @@ -1848,7 +1849,8 @@ router.get( students: filterStudents(res, students), schoolUsesLdap: res.locals.currentSchoolData.ldapSchoolIdentifier, notes, - referrer: '/administration/classes/', + referrer: Configuration.get('FEATURE_SHOW_NEW_CLASS_VIEW_ENABLED') + ? '/administration/groups/classes/' : '/administration/classes/', consentsMissing: usersWithoutConsent.length !== 0, consentNecessary, // eslint-disable-next-line max-len @@ -1953,7 +1955,7 @@ router.post( 'ADMIN_VIEW', ); if (isAdmin) { - res.redirect('/administration/classes/'); + Configuration.get('FEATURE_SHOW_NEW_CLASS_VIEW_ENABLED') ? res.redirect('/administration/groups/classes/') : res.redirect('/administration/classes/'); } else { res.redirect(`/administration/classes/${data._id}/manage`); } @@ -2764,7 +2766,7 @@ router.get('/systems/:id', getDetailHandler('systems')); router.delete( '/systems/:id', removeSystemFromSchoolHandler, - getDeleteHandler('systems'), + getDeleteHandler('systems', undefined, FEATURE_NEST_SYSTEMS_API_ENABLED === 'true' ? 'v3' : 'v1'), ); router.get('/rss/:id', async (req, res) => { @@ -2878,27 +2880,34 @@ router.use( const getSystemsBody = (systems) => systems.map((item) => { const name = getSSOTypes().filter((type) => item.type === type.value); let tableActions = []; - const editable = (item.type === 'ldap' && item.ldapConfig.provider === 'general') - || item.type === 'moodle' || item.type === 'iserv'; - const hasSystemPermission = permissionsHelper.userHasPermission(res.locals.currentUser, 'SYSTEM_EDIT'); + const editable = item.ldapConfig?.provider === 'general'; + const hasSystemEditPermission = permissionsHelper.userHasPermission(res.locals.currentUser, 'SYSTEM_EDIT'); + const hasSystemCreatePermission = permissionsHelper.userHasPermission(res.locals.currentUser, 'SYSTEM_CREATE'); - if (editable && hasSystemPermission) { - tableActions = tableActions.concat([ - { - link: item.type === 'ldap' ? `/administration/ldap/config?id=${item._id}` - : `/administration/systems/${item._id}`, - class: item.type === 'ldap' ? 'btn-edit-ldap' : 'btn-edit', - icon: 'edit', - title: res.$t('administration.controller.link.editEntry'), - }, - { - link: `/administration/systems/${item._id}`, - class: 'btn-delete--systems', - icon: 'trash-o', - method: 'delete', - title: res.$t('administration.controller.link.deleteEntry'), - }, - ]); + if (editable) { + if (hasSystemEditPermission) { + tableActions = tableActions.concat([ + { + link: item.type === 'ldap' ? `/administration/ldap/config?id=${item._id}` + : `/administration/systems/${item._id}`, + class: item.type === 'ldap' ? 'btn-edit-ldap' : 'btn-edit', + icon: 'edit', + title: res.$t('administration.controller.link.editEntry'), + }, + ]); + } + + if (hasSystemCreatePermission) { + tableActions = tableActions.concat([ + { + link: `/administration/systems/${item._id}`, + class: 'btn-delete--systems', + icon: 'trash-o', + method: 'delete', + title: res.$t('administration.controller.link.deleteEntry'), + }, + ]); + } } return [ item.type === 'ldap' && item.ldapConfig.active === false diff --git a/controllers/dashboard.js b/controllers/dashboard.js index 5892c76eae..b04039d5fa 100644 --- a/controllers/dashboard.js +++ b/controllers/dashboard.js @@ -230,7 +230,7 @@ router.get('/', (req, res, next) => { qs: { $limit: 1, $sort: { - createdAt: -1, + publishedAt: -1, }, }, }) @@ -262,7 +262,7 @@ router.get('/', (req, res, next) => { const newestRelease = newestReleases[0] || {}; const newRelease = !!( Date.parse(userPreferences.releaseDate) - < Date.parse(newestRelease.createdAt) + < Date.parse(newestRelease.publishedAt) ); const roles = user.roles.map((role) => role.name); let homeworksFeedbackRequired = []; @@ -278,7 +278,7 @@ router.get('/', (req, res, next) => { if (newRelease || !userPreferences.releaseDate) { api(req) .patch(`/users/${user._id}`, { - json: { 'preferences.releaseDate': newestRelease.createdAt }, + json: { 'preferences.releaseDate': newestRelease.publishedAt }, }) .catch(() => { warn('failed to update user preference releaseDate'); diff --git a/controllers/firstLogin.js b/controllers/firstLogin.js index 89e79bb008..f0be51c83e 100644 --- a/controllers/firstLogin.js +++ b/controllers/firstLogin.js @@ -197,7 +197,7 @@ router.get('/', async (req, res, next) => { } // EMAIL - if (!res.locals.currentUser.source) { + if (!(res.locals.currentUser.source || res.locals.currentPayload.isExternalUser)) { // only display the confirm email page if the user was not generated from an external source submitPageIndex += 1; sections.push('email'); diff --git a/controllers/login.js b/controllers/login.js index c541f2f131..a48eb871fb 100644 --- a/controllers/login.js +++ b/controllers/login.js @@ -18,11 +18,6 @@ const { } = require('../helpers'); const { LoginSchoolsCache } = require('../helpers/cache'); -Handlebars.registerHelper('oauthLink', (id) => { - const apiUrl = `${Configuration.get('PUBLIC_BACKEND_URL')}/v3/sso/login/${id}`; - return apiUrl; -}); - // SSO Login router.get('/tsp-login/', (req, res, next) => { const { @@ -353,26 +348,6 @@ router.all('/', async (req, res, next) => { } }); -const mapErrorCodeToTranslation = (errorCode) => { - switch (errorCode) { - case 'sso_user_notfound': - return 'login.text.userNotFound'; - case 'sso_oauth_access_denied': - return 'login.text.accessDenied'; - case 'sso_jwt_problem': - case 'sso_oauth_invalid_request': - case 'sso_oauth_unsupported_response_type': - case 'sso_auth_code_step': - return 'login.text.oauthCodeStep'; - case 'sso_internal_error': - return 'login.text.internalError'; - case 'sso_user_not_found_after_provisioning': - return 'login.text.userNotFoundInUnprovisionedSchool'; - default: - return 'login.text.loginFailed'; - } -}; - const renderLogin = async (req, res) => { await authHelper.clearCookie(req, res); @@ -381,20 +356,6 @@ const renderLogin = async (req, res) => { let oauthErrorLogout = false; - // TODO N21-1374: remove old login flow - if (req.query.error) { - res.locals.notification = { - type: 'danger', - message: res.$t(mapErrorCodeToTranslation(req.query.error), { - systemName: 'moin.schule', - shortTitle: res.locals.theme.short_title, - }), - }; - if (req.query.provider === 'iserv' && req.query.error !== 'sso_oauth_access_denied') { - oauthErrorLogout = true; - } - } - if (req.session.oauth2Logout) { oauthErrorLogout = req.session.oauth2Logout.provider; diff --git a/helpers/handlebars/middleware.js b/helpers/handlebars/middleware.js index c3549eede1..a6f02c45b2 100644 --- a/helpers/handlebars/middleware.js +++ b/helpers/handlebars/middleware.js @@ -209,18 +209,18 @@ module.exports = (req, res, next) => { ]; if (newClassViewEnabled) { - teacherChildren.splice(3, 0, { - name: res.$t('global.sidebar.link.administrationClassesNew'), - testId: 'Klassen (neu)', + teacherChildren.splice(2, 1, { + name: res.$t('global.sidebar.link.administrationClasses'), + testId: 'Klassen', icon: // eslint-disable-next-line max-len '', isExternalIcon: true, link: '/administration/groups/classes', }); - teacherChildrenWithoutStudents.splice(2, 0, { - name: res.$t('global.sidebar.link.administrationClassesNew'), - testId: 'Klassen (neu)', + teacherChildrenWithoutStudents.splice(1, 1, { + name: res.$t('global.sidebar.link.administrationClasses'), + testId: 'Klassen', icon: // eslint-disable-next-line max-len '', isExternalIcon: true, @@ -298,9 +298,9 @@ module.exports = (req, res, next) => { ]; if (newClassViewEnabled) { - adminChildItems.splice(4, 0, { - name: res.$t('global.sidebar.link.administrationClassesNew'), - testId: 'Klassen (neu)', + adminChildItems.splice(3, 1, { + name: res.$t('global.sidebar.link.administrationClasses'), + testId: 'Klassen', icon: // eslint-disable-next-line max-len '', isExternalIcon: true, diff --git a/locales/de.json b/locales/de.json index 6405bed5de..af0b547285 100644 --- a/locales/de.json +++ b/locales/de.json @@ -1249,6 +1249,7 @@ "toTask": "Zur Aufgabe" }, "text": { + "announcement": "Nehmen Sie an unserer Zufriedenheitsumfrage teil und helfen Sie uns, die Cloud zu verbessern. Hier geht’s zur Befragung.", "emptyHomeworksInfo": "Keine gestellten Aufgaben. Du findest alle Aufgaben im Aufgaben-Bereich.", "emptyNewsInfo": "Bisher gibt es keine News.", "graded": "Bewertet", @@ -1256,8 +1257,7 @@ "noDueDate": "Kein Abgabedatum festgelegt", "noMaterialsYetLookAtOthers": "Sie haben noch keine eigenen Materialien erstellt. Sie können sich aber auch Inspiration in Materialien Ihrer Kolleg:innen holen. Schauen Sie doch im \"Meine Materialien\"-Abschnitt vorbei.", "noNews": "Keine Neuigkeiten", - "notFound": "Keine aktuellen Einträge vorhanden.", - "bettermarksAnnouncement": "Neues bei bettermarks: Jetzt auch Unterrichtseinheiten für Klasse 5 und 6 neben den Übungs- und Testaufgaben für Jahrgangsstufe 4 bis 13!" + "notFound": "Keine aktuellen Einträge vorhanden." } }, "dataprivacy": { @@ -1751,7 +1751,6 @@ "addons": "Add-ons", "administration": "Administration", "administrationClasses": "Klassen", - "administrationClassesNew": "Klassen (neu)", "administrationCourses": "Kurse" } }, @@ -3184,7 +3183,8 @@ "geoGebraWorksheet": "GeoGebra Arbeitsblatt", "material": "Lern-Material", "neXboard": "neXboard", - "text": "Text" + "text": "Text", + "h5p": "H5P" }, "input": { "brainstormAboutXYZ": "Brainstorming zum Thema XYZ", @@ -3225,5 +3225,10 @@ "text": { "nextcloudLink": "Wir arbeiten an einem neuen Dateibereich. Dort können ab jetzt alle neuen Dateien gespeichert und verwaltet werden (Dateibereich öffnen). Alle Team-Mitglieder haben automatisch Zugriff auf die dort gespeicherten Dateien. Alle bereits bestehenden Dateien in der {{title}} sind weiterhin hier verfügbar." } + }, + "h5p": { + "text": { + "createAfterFirstSave": "H5P Inhalte können erst nach dem ersten Speichern erstellt werden." + } } } diff --git a/locales/en.json b/locales/en.json index 526a7536ba..5017a2e332 100644 --- a/locales/en.json +++ b/locales/en.json @@ -1249,6 +1249,7 @@ "toTask": "To the task" }, "text": { + "announcement": "Take part in our satisfaction survey and help us improve the cloud. Click here for the survey. (German language only).", "emptyHomeworksInfo": "No assigned tasks. You can find all tasks in the tasks area.", "emptyNewsInfo": "So far there is no news.", "graded": "Graded", @@ -1256,8 +1257,7 @@ "noDueDate": "No submission date set", "noMaterialsYetLookAtOthers": "You have not yet created your own materials. But you can also get inspiration from your colleagues' materials. Check out the \"My Materials\" section .", "noNews": "No news", - "notFound": "No active entries found.", - "bettermarksAnnouncement": "New at bettermarks: Now also teaching units for grade 5 and 6 in addition to the practice and test items for grades 4 to 13!" + "notFound": "No active entries found." } }, "dataprivacy": { @@ -1751,7 +1751,6 @@ "addons": "Add-ons", "administration": "Administration", "administrationClasses": "Classes", - "administrationClassesNew": "Classes (new)", "administrationCourses": "Courses" } }, @@ -3184,7 +3183,8 @@ "geoGebraWorksheet": "GeoGebra worksheet", "material": "Learning material", "neXboard": "neXboard", - "text": "Text" + "text": "Text", + "h5p": "H5P" }, "input": { "brainstormAboutXYZ": "Brainstorming on the topic XYZ", @@ -3225,5 +3225,10 @@ "text": { "nextcloudLink": "We are working on a new file space. From now on, all new files can be saved and managed there (open file area). All team members automatically have access to the files stored there. All already existing files in the {{title}} are still available here." } + }, + "h5p": { + "text": { + "createAfterFirstSave": "H5P contents can only be created after the first save." + } } } diff --git a/locales/es.json b/locales/es.json index 77376893ce..e8d2b2aa0a 100644 --- a/locales/es.json +++ b/locales/es.json @@ -1249,6 +1249,7 @@ "toTask": "A la tarea" }, "text": { + "announcement": "Participe en nuestra encuesta de satisfacción y ayúdenos a mejorar la nube. Haga clic aquí para acceder a la encuesta (solo en alemán).", "emptyHomeworksInfo": "No hay tareas asignadas. Puedes encontrarar todas las tareas en el área de tareas.", "emptyNewsInfo": "Hasta el momento no hay noticias.", "graded": "Calificado", @@ -1256,8 +1257,7 @@ "noDueDate": "No se ha fijado una fecha de envío", "noMaterialsYetLookAtOthers": "Aún no has creado tus propios materiales. También puedes inspirarte en los materiales de tus compañeros. Consulta la sección \"Mis materiales\".", "noNews": "No hay noticias", - "notFound": "No se han encontrado entradas activas.", - "bettermarksAnnouncement": "Novedad en bettermarks: ¡Ahora también unidades didácticas para 5º y 6º curso, además de las tareas de práctica y examen para 4º a 13º curso!" + "notFound": "No se han encontrado entradas activas." } }, "dataprivacy": { @@ -1751,7 +1751,6 @@ "addons": "Complementos", "administration": "Administración", "administrationClasses": "Clases", - "administrationClassesNew": "Clases (nuevo)", "administrationCourses": "Cursos" } }, @@ -3184,7 +3183,8 @@ "geoGebraWorksheet": "Hoja de trabajo de GeoGebra", "material": "Material de aprendizaje", "neXboard": "neXboard", - "text": "Texto" + "text": "Texto", + "h5p": "H5P" }, "input": { "brainstormAboutXYZ": "Lluvia de ideas sobre el tema XYZ", @@ -3225,5 +3225,10 @@ "text": { "nextcloudLink": "Estamos trabajando en un nuevo espacio de archivos. A partir de ahora, todos los archivos nuevos se pueden guardar y administrar allí (área de archivos abiertos). Todos los miembros del equipo tienen acceso automáticamente a los archivos almacenados allí. Todos los archivos existentes en {{title}} todavía están disponibles aquí." } + }, + "h5p": { + "text": { + "createAfterFirstSave": "Los contenidos H5P solo se pueden crear después del primer guardado." + } } } diff --git a/locales/uk.json b/locales/uk.json index 967cae688c..156f5008a5 100644 --- a/locales/uk.json +++ b/locales/uk.json @@ -9,6 +9,7 @@ "welcome": "Вітаємо" }, "text": { + "announcement": "Візьміть участь у нашому опитуванні та допоможіть нам покращити хмару. Натисніть тут, щоб отримати доступ до опитування (лише німецькою мовою).", "notFound": "Активних записів не знайдено.", "emptyHomeworksInfo": "Усі домашні завдання показуються в розділі домашніх завдань.", "emptyNewsInfo": "Немає останніх новин. Перегляньте розділ новин, щоб бути в курсі.", @@ -16,8 +17,7 @@ "noDueDate": "Дата подання не встановлена", "noMaterialsYetLookAtOthers": "Ви ще не створили власні матеріали. Але ви також можете черпати натхнення з матеріалів своїх колег. Перевірте Розділ «Мої матеріали».", "graded": "Оцінено", - "handedIn": "Подані", - "bettermarksAnnouncement": "Нове на bettermarks: тепер також навчальні блоки для 5 та 6 класів на додаток до практичних та тестових завдань для 4-13 класів!" + "handedIn": "Подані" }, "img_alt": { "showAppointmentInTeam": "Показати призначення в команді", @@ -252,7 +252,6 @@ "link": { "addons": "Доповнення", "administrationClasses": "Класи", - "administrationClassesNew": "Класи (новий)", "administrationCourses": "Курси", "administration": "Адміністрація" } @@ -2175,7 +2174,8 @@ "text": "Текст", "material": "Навчальний матеріал", "etherpad": "Etherpad", - "neXboard": "neXboard" + "neXboard": "neXboard", + "h5p": "H5P" }, "label": { "descriptionEtherpad": "Опис Etherpad", @@ -3234,5 +3234,10 @@ "text": { "nextcloudLink": "Ми працюємо над новим файловим простором. Відтепер усі нові файли можна зберігати та керувати ними (відкрита область файлів). Усі члени команди автоматично мають доступ до файлів, які там зберігаються. Усі існуючі файли в {{title}} все ще доступні тут." } + }, + "h5p": { + "text": { + "createAfterFirstSave": "Вміст H5P можна створити лише після першого збереження." + } } } diff --git a/package-lock.json b/package-lock.json index e42f54eb31..762eb0f5e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4710,9 +4710,9 @@ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, "node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" }, "node_modules/body-parser": { "version": "1.20.1", @@ -5044,25 +5044,28 @@ } }, "node_modules/browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", + "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", "dependencies": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", + "bn.js": "^5.2.1", + "browserify-rsa": "^4.1.0", "create-hash": "^1.2.0", "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", + "elliptic": "^6.5.4", "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" + "parse-asn1": "^5.1.6", + "readable-stream": "^3.6.2", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 4" } }, "node_modules/browserify-sign/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -28270,9 +28273,9 @@ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" }, "body-parser": { "version": "1.20.1", @@ -28548,25 +28551,25 @@ } }, "browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", + "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", + "bn.js": "^5.2.1", + "browserify-rsa": "^4.1.0", "create-hash": "^1.2.0", "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", + "elliptic": "^6.5.4", "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" + "parse-asn1": "^5.1.6", + "readable-stream": "^3.6.2", + "safe-buffer": "^5.2.1" }, "dependencies": { "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", diff --git a/static/scripts/login.js b/static/scripts/login.js index f8f1c01710..1c49e4c6fe 100644 --- a/static/scripts/login.js +++ b/static/scripts/login.js @@ -153,16 +153,9 @@ $(document).ready(() => { }); if ($oauthErrorLogout && $oauthSystems.length > 0 && $oauthErrorLogout.eq(0).text()) { - const logoutErrorOrProvider = $oauthErrorLogout.eq(0).text(); - - let $loginButton; - if (logoutErrorOrProvider === 'true') { - // TODO N21-1374: remove old login flow - $loginButton = $oauthSystems.find('.btn-oauth[data-provider="iserv"]'); - } else if (logoutErrorOrProvider !== 'false') { - $loginButton = $oauthSystems.find(`.btn-oauth[data-provider="${logoutErrorOrProvider}"]`); - } + const provider = $oauthErrorLogout.eq(0).text(); + const $loginButton = $oauthSystems.find(`.btn-oauth[data-provider="${provider}"]`); if ($loginButton && $loginButton.length > 0 && $loginButton.eq(0).data('logout')) { const logoutWindow = window.open($loginButton.eq(0).data('logout')); window.focus(); @@ -173,16 +166,6 @@ $(document).ready(() => { } } - // TODO N21-1374: remove old login flow - $oauthSystems.each((index, element) => { - const $oauthButton = $(element).find('.btn-oauth').eq(0); - - // eslint-disable-next-line func-names - $oauthButton.on('click', function () { - window.location.href = $(this).data('href'); - }); - }); - $cloudButton.on('click', () => { showHideButtonsMenu(false); showHideLdapLoginForm(false); diff --git a/static/scripts/topicEdit.js b/static/scripts/topicEdit.js index d1081b63c7..1a71490199 100644 --- a/static/scripts/topicEdit.js +++ b/static/scripts/topicEdit.js @@ -326,7 +326,7 @@ class TopicBlockList extends React.Component { * Render the list items. */ render() { - const neXboardEnabled = ($contentBlocksContainer.data('nexboardenabled') === true); + const h5pEditorEnabled = ($contentBlocksContainer.data('h5peditorenabled') === true); return (
{contentType}
+{{{$t "dashboard.text.bettermarksAnnouncement"}}}
+ {{#hasConfig "DASHBOARD_ANNOUNCEMENT_ENABLED"}} + {{#hasConfig "DASHBOARD_ANNOUNCEMENT_ROLES"}} + {{#ifeq (getConfig "DASHBOARD_ANNOUNCEMENT_ENABLED") true}} + {{#ifneq (getConfig "DASHBOARD_ANNOUNCEMENT_ROLES") ""}} + {{#if (userHasRoleFromArray (getConfig "DASHBOARD_ANNOUNCEMENT_ROLES") ../currentUser)}} +{{{$t "dashboard.text.announcement"}}}
{{content.contentType}}
+