diff --git a/extension/content/listener.js b/extension/content/listener.js new file mode 100644 index 0000000..61e3613 --- /dev/null +++ b/extension/content/listener.js @@ -0,0 +1,139 @@ +/** + * listener.js + * @license + * This file is part of Modern Kiosk + * + * Copyright (C) 2018-2019 - RacketLogger + * Copyright (C) 2019 - Universidad de El Salvador + * + * Modern Kiosk is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Modern Kiosk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Modern Kiosk. If not, see . + */ + +/** + * @file Content script injected in web pages to handle notifications, EKC and + * submit password. + * @requires passwordmodal + * @requires notifications + * @author Hector Castro + */ + +/** + * Listener/Handle requests for browser.notifications and + * browser.tabs.sendMessage from the background script. + * + * @async + * @function handleData + * @param {Object} request - request.ask_kiosk_password (if true show password + * modal), request.message and request.send_notification (if true show + * notification). + * @return {Promise} The data from the password modal. + */ +async function handleData(request) { + try { + if (request.ask_kiosk_password) { + // Callback Submit - resolve or reject a Promise + function Submit(resolve, reject) { + let passResult = input.value; + if (!passResult) { + reject(new Error("Password empty error")); + } else { + resolve(passResult); + } + } + //show/hide password modal and prevent user to click behind + let modalLauncher = (value) => { + if (value === "hide") { + cover.style.visibility = "hidden"; + passwordModal.style.visibility = "hidden"; + document.body.style.overflow = "visible"; + } else if (value === "show") { + cover.style.visibility = "visible"; + passwordModal.style.visibility = "visible"; + document.body.style.overflow = "hidden"; + } else { + throw new Error(`Param ${ value } not supported`); + } + } + + let getSubmit = new Promise((resolve, reject) => { + // Hide password modal when user submit password and resolve o reject + // a Promise + buttonSubmit.addEventListener("click", (e) => { + modalLauncher("hide"); + Submit(resolve, reject); + e.preventDefault(); + }, {once: true}); + + // Show password modal when user strike "Enter" or "NumpadEnter" or; + // hide password modal when user strike "Escape" and reject Promise + input.addEventListener("keyup", (e) => { + if (e.defaultPrevented) { + return; + } + switch (e.code) { + case "Enter": + case "NumpadEnter": + modalLauncher("hide"); + Submit(resolve, reject); + break; + case "Escape": + modalLauncher("hide"); + reject(new Error("User striked Escape")); + break; + } + e.preventDefault(); + }, true); + // Hide password modal when user click close button and reject Promise + closeButton.addEventListener("click", (e) => { + modalLauncher("hide"); + reject(new Error("User closed modal dialog")); + e.preventDefault(); + }, false); + }); + + console.log("Message from the background script:"); + console.log("Ask for password"); + + // Show password modal + modalLauncher("show"); + + // await for the user enter password, return input.value + let password = await getSubmit.then(value => { + return value; + }).catch(error => { console.log(error.message); }); + + if (password) { + input.value = ""; + if (!checkbox.checked) { + return Promise.resolve({response: password, preferences: false}); + } else { + return Promise.resolve({response: password, preferences: true}); + } + } else { + input.value = ""; + return Promise.resolve({response: false}); + } + } else if (request.send_notification) { + containerNotify.style.visibility = "visible"; + notify.textContent = request.message; + } else { + throw new Error("Request failed..."); + } + } catch (error) { + console.log("Message from the background script failed:", error); + } +} + +browser.runtime.onMessage.addListener(handleData); + diff --git a/extension/content/notifications.js b/extension/content/notifications.js new file mode 100644 index 0000000..dbd5e75 --- /dev/null +++ b/extension/content/notifications.js @@ -0,0 +1,94 @@ +/** + * notifications.js + * @license + * This file is part of Modern Kiosk + * + * Copyright (C) 2018-2019 - RacketLogger + * Copyright (C) 2019 - Universidad de El Salvador + * + * Modern Kiosk is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Modern Kiosk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Modern Kiosk. If not, see . + */ + +/** + * @file Content script injected in web pages to create modals for notifications + * @author Hector Castro + */ + +"use strict"; + +// Create div for modal container +const containerNotify = document.createElement("div"); +containerNotify.id = "messageModal"; +containerNotify.className = "message_container_mk"; +containerNotify.style.position = "fixed"; +containerNotify.style.left = "75%"; +containerNotify.style.top = "85%"; +containerNotify.style.marginLeft = "-100px"; +containerNotify.style.marginTop = "-100px"; +containerNotify.style.padding = "15px"; +containerNotify.style.width = "300px"; +containerNotify.style.border = "3px solid silver"; +containerNotify.style.borderRadius = "0.5em"; +containerNotify.style.visibility = "hidden"; +containerNotify.style.backgroundColor = "gray"; + +// Create div notify +const notify = document.createElement("div"); +notify.className = "notification_mk"; +notify.style.width = "100%"; +notify.style.padding = "0px"; +notify.style.marginTop = "15px"; +notify.style.border = "0px"; +notify.style.borderRadius = "0px"; +notify.style.backgroundColor = "gray"; +notify.style.font = "normal bold 12px Helvetica,Arial,sans-serif"; +notify.style.color = "black"; + +// Create div title +const titleNotify = document.createElement("div"); +titleNotify.className = "title_container_mk"; +titleNotify.style.display = "inherit"; +titleNotify.style.position = "absolute"; +titleNotify.style.height = "27px"; +titleNotify.style.width = "100%"; +titleNotify.style.padding = "0px"; +titleNotify.style.marginLeft = "-15px"; +titleNotify.style.marginTop = "-15px"; +titleNotify.style.border = "0px"; +titleNotify.style.borderRadius = "0px"; +titleNotify.style.backgroundColor = "silver"; + +// Create close button +const closeBtn = document.createElement("a"); +closeBtn.textContent = "[\u00D7]"; +closeBtn.style.cursor = "pointer"; +closeBtn.style.font = "normal bold 12px Helvetica,Arial,sans-serif"; +closeBtn.style.color = "black"; +closeBtn.style.textAlign = "right"; +closeBtn.style.cssFloat = "right"; +closeBtn.style.backgroundColor = "silver"; +closeBtn.setAttribute("aria-label", "Close"); + +// Append elements to body +titleNotify.appendChild(closeBtn); +containerNotify.appendChild(titleNotify); +containerNotify.appendChild(notify); +document.body.appendChild(containerNotify); + +// Hide container when user click in close button +closeBtn.addEventListener("click", (e) => { + containerNotify.style.visibility = "hidden"; + e.preventDefault(); +}, false); + diff --git a/extension/content/passwordmodal.js b/extension/content/passwordmodal.js new file mode 100644 index 0000000..49ca423 --- /dev/null +++ b/extension/content/passwordmodal.js @@ -0,0 +1,160 @@ +/** + * passwordmodal.js + * @license + * This file is part of Modern Kiosk + * + * Copyright (C) 2018-2019 - RacketLogger + * Copyright (C) 2019 - Universidad de El Salvador + * + * Modern Kiosk is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Modern Kiosk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Modern Kiosk. If not, see . + */ + +/** + * @file Content script injected in web pages. Shows a modal when the browser is + * in Kiosk Mode and is set it up to accept password in conjunction with startup + * in fullscreen mode. Called when user strike EKC combination (Ctr + Shift + U) + * @author Hector Castro + */ + +"use strict"; + +// Create curtain or cover to prevent user interact with elements behind +const cover = document.createElement("div"); +cover.id = "curtainModal"; +cover.className = "curtain_mk"; +cover.style.position = "fixed"; +cover.style.top = "0px"; +cover.style.left = "0px"; +cover.style.height = "100%"; +cover.style.width = "100%"; +cover.style.visibility = "hidden"; +cover.style.backgroundColor = "gray"; +cover.style.opacity = ".7"; +cover.style.zIndex = "1000"; + +// Create div for password modal container +const passwordModal = document.createElement("div"); +passwordModal.id = "passwordModal"; +passwordModal.className = "password_container_mk"; +passwordModal.style.position = "fixed"; +passwordModal.style.left = "50%"; +passwordModal.style.top = "50%"; +passwordModal.style.marginLeft = "-100px"; +passwordModal.style.marginTop = "-100px"; +passwordModal.style.padding = "15px"; +passwordModal.style.width = "360px"; +passwordModal.style.border = "3px solid palevioletred"; +passwordModal.style.borderRadius = "0.5em"; +passwordModal.style.visibility = "hidden"; +passwordModal.style.backgroundColor = "white"; +passwordModal.style.zIndex = "1001"; + +// Create div title +const title = document.createElement("div"); +title.className = "title_container_mk"; +title.style.display = "inherit"; +title.style.position = "absolute"; +title.style.height = "27px"; +title.style.width = "100%"; +title.style.padding = "0px"; +title.style.marginLeft = "-15px"; +title.style.marginTop = "-15px"; +title.style.border = "0px"; +title.style.borderRadius = "0px"; +title.style.backgroundColor = "palevioletred"; + +// Create close button +const closeButton = document.createElement("a"); +closeButton.textContent = "[\u00D7]"; +closeButton.className = "close_button_mk"; +closeButton.style.cursor = "pointer"; +closeButton.style.font = "normal bold 12px Helvetica,Arial,sans-serif"; +closeButton.style.color = "white"; +closeButton.style.textAlign = "right"; +closeButton.style.cssFloat = "right"; +closeButton.style.backgroundColor = "palevioletred"; +closeButton.setAttribute("aria-label", "Close"); + +// Create label for inpunt type password +const labelForInput = document.createElement("label"); +labelForInput.textContent = "\ud83d\udddd Please enter kiosk password:"; +labelForInput.htmlFor = "password_input"; +labelForInput.className = "label_input_mk"; +labelForInput.style.display = "block"; +labelForInput.style.marginTop = "15px"; +labelForInput.style.marginBottom = "5px"; +labelForInput.style.font = "normal bold 12px Helvetica,Arial,sans-serif"; +labelForInput.style.color = "black"; + +// Create input type password +const input = document.createElement("input"); +input.className = "password_class_mk"; +input.id = "password_input"; +input.type = "password"; +input.style.display = "inline-block"; +input.style.position = "relative"; +input.style.boxSizing = "border-box"; +input.style.marginBottom = "12px"; +input.style.width = "100%"; +input.style.boxShadow = "0px 0px 6px gray"; +input.style.borderRadius = "3px"; +input.style.backgroundColor = "gold"; + +// Create button submit +const buttonSubmit = document.createElement("button"); +buttonSubmit.className = "button_submit_mk"; +buttonSubmit.textContent = "Submit"; +buttonSubmit.style.border = "1px solid darknarange"; +buttonSubmit.style.cssFloat = "right"; +buttonSubmit.style.backgroundColor = "gold"; + +// Create checkbox preferences +const checkbox = document.createElement("input"); +checkbox.id = "check_preferences"; +checkbox.type = "checkbox"; +checkbox.className = "checkbox_preferences_mk"; +checkbox.style.display = "inline-block"; +checkbox.style.marginBottom = "1px"; +checkbox.style.verticalAlign = "middle"; + +// Create label for checkbox preferences +const labelForCheckbox = document.createElement("label"); +labelForCheckbox.className = "label_checkbox_mk"; +labelForCheckbox.textContent = "Close and show preferences"; +labelForCheckbox.htmlFor = "check_preferences"; +labelForCheckbox.style.display = "inline-block"; +labelForCheckbox.style.font = "normal bold 12px Helvetica,Arial,sans-serif"; +labelForCheckbox.style.color = "black"; +labelForCheckbox.style.wordWrap = "break-word"; + +// Append elements to body +passwordModal.appendChild(title); +title.appendChild(closeButton); +passwordModal.appendChild(labelForInput); +passwordModal.appendChild(input); +passwordModal.appendChild(buttonSubmit); +passwordModal.appendChild(checkbox); +passwordModal.appendChild(labelForCheckbox); +document.body.appendChild(cover); +document.body.appendChild(passwordModal); + +// See for input transition +input.addEventListener("focusin", (e) => { + e.target.style.border = "1px solid #79589F"; +}, false); + +input.addEventListener("focusout", (e) => { + e.target.style.border = "1px none white"; +}, false); + diff --git a/extension/icons/Cancel.svg b/extension/icons/Cancel.svg new file mode 100644 index 0000000..fd95fd4 --- /dev/null +++ b/extension/icons/Cancel.svg @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/extension/icons/Globe.svg b/extension/icons/Globe.svg new file mode 100644 index 0000000..57899c1 --- /dev/null +++ b/extension/icons/Globe.svg @@ -0,0 +1,4 @@ + + diff --git a/extension/icons/Hide.svg b/extension/icons/Hide.svg new file mode 100644 index 0000000..518d72b --- /dev/null +++ b/extension/icons/Hide.svg @@ -0,0 +1,19 @@ + + + + + + diff --git a/extension/icons/Preferences.svg b/extension/icons/Preferences.svg new file mode 100644 index 0000000..e5fcb51 --- /dev/null +++ b/extension/icons/Preferences.svg @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/extension/icons/Secure.svg b/extension/icons/Secure.svg new file mode 100644 index 0000000..425474c --- /dev/null +++ b/extension/icons/Secure.svg @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/extension/icons/Show.svg b/extension/icons/Show.svg new file mode 100644 index 0000000..54dbca5 --- /dev/null +++ b/extension/icons/Show.svg @@ -0,0 +1,16 @@ + + + diff --git a/extension/icons/TopSites.svg b/extension/icons/TopSites.svg new file mode 100644 index 0000000..2112961 --- /dev/null +++ b/extension/icons/TopSites.svg @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/extension/mk_utils.js b/extension/mk_utils.js new file mode 100644 index 0000000..dd84dd1 --- /dev/null +++ b/extension/mk_utils.js @@ -0,0 +1,58 @@ +/** + * mk_utils.js + * @license + * This file is part of Modern Kiosk + * + * Copyright (C) 2018-2019 - RacketLogger + * Copyright (C) 2019 - Universidad de El Salvador + * + * Modern Kiosk is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Modern Kiosk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Modern Kiosk. If not, see . + */ + +/** + * @file Background script for the web-extension to display notifications + * @author Carlos Puchol + * @author Hector Castro + */ + +/** + * Notifications to users + * @function mkNotifications + * @param {string} id To refer this notification. + * @param {string} message Message to display. + */ +function mkNotifications(id, message) { + browser.notifications.create(id, { + "type": "basic", + "iconUrl": browser.extension.getURL("icons/mk.svg"), + "title": "Modern Kiosk Notifications", + "message": message + }); +} + + +/** + * Notifications to users when browser status is in full screen + * useful when some OS does not show notifications in full screen + * @function mkToContentNotify + * @param {string} tabid Tab where notification will display + * @param {string} message Message to display. + */ +function mkToContentNotify(tabid, msg_content) { + browser.tabs.sendMessage( + tabid, + {send_notification: true, message: msg_content} + ); +} +