diff --git a/bin/web/routes/static.js b/bin/web/routes/static.js index 9019c1f..b66cd59 100644 --- a/bin/web/routes/static.js +++ b/bin/web/routes/static.js @@ -95,6 +95,29 @@ let getRoutes = async () => { } })); + /** + * settings page + * @url /settings + * @method GET + */ + route.get('/settings', asyncer(async (req, res, next) => { + if(req.session && req.session.user) { + // query user + user = await db.getUser(req.session.user.id); + + if(user.reply) { + group = await db.getGroup(user.reply.group); + return res.render('settings', { + session: req.session, + cfg: cfg, + user: user.reply, + group: group.reply + }); + } + else + return res.render('error/404'); + } else { + return res.render('login', { session: req.session, cfg: cfg }); } })); diff --git a/bin/web/views/settings.pug b/bin/web/views/settings.pug new file mode 100644 index 0000000..707378c --- /dev/null +++ b/bin/web/views/settings.pug @@ -0,0 +1,93 @@ +extends blocks/layout.pug +append var + if(session && session.user) + - var breadcrumb = {0: {"name": cfg.app.name, "href": "/"}, 1: {"name": "Settings", "active": true}}; + - var title = "Settings"; + +mixin setting(name, id, inputId, hidden, inputType, inputValue, inputPlaceholder, inputIcon, inputDisabled) + .uk-margin(id=id) + label.uk-form-label(for=inputId)=name + if(inputIcon) + .uk-inline.uk-width-1-1 + span.uk-form-icon(uk-icon="icon: "+inputIcon) + if(inputDisabled == "disabled") + input.uk-input(id=inputId, type=inputType, value=inputValue, placeholder=inputPlaceholder, disabled) + else + input.uk-input(id=inputId, type=inputType, value=inputValue, placeholder=inputPlaceholder) + else + input.uk-input(id=inputId, type=inputType, value=inputValue, placeholder=inputPlaceholder) + //-.uk-card.uk-card-default + .uk-card-header.uk-card-primary + h3.uk-card-title=name + .uk-card-body + p=id + .uk-card-footer.uk-flex.uk-flex-right + a.uk-button.uk-button-default.uk-button-primary(href="/api/redirect?id="+id) Login + +mixin settings() + form(class="uk-child-width-expand uk-margin-bottom", uk-grid) + fieldset.uk-fieldset + h1 Settings + + h2 Profile + +setting('', 'lorem-ipsum', 'form-profile-username', 'false', 'text', user.nickname, '', 'user', 'disabled') + +setting('', 'lorem-ipsum', 'form-profile-email', 'false', 'text', user.email, 'john.doe@example.com', 'mail') + div(class="uk-flex uk-flex-between uk-margin-bottom", uk-grid) + div(class="uk-width-2-3@m") + #profile_msg.uk-alert(data-uk-alert).uk-hidden + a.uk-close-alt.uk-alert-close(href="#") + p + div + a(onclick="saveProfile(event)").uk-button.uk-button-primary Save + + h2 Password + +setting('Password', 'form-password', 'form-security-password', 'false', 'password', '', '') + +setting('Reenter Password', 'form-repassword', 'form-security-repassword', 'false', 'password', '', '') + div(class="uk-flex uk-flex-between uk-margin-bottom", uk-grid) + div(class="uk-width-2-3@m") + #password_msg.uk-alert(data-uk-alert).uk-hidden + a.uk-close-alt.uk-alert-close(href="#") + p + div + a(onclick="savePassword(event)").uk-button.uk-button-primary Save + + + div(class="uk-flex uk-flex-between uk-margin-bottom", uk-grid) + div(class="uk-width-2-3@m uk-flex-column") + h2 Multifactor Authentication + #mfa_msg.uk-alert(data-uk-alert).uk-hidden + a.uk-close-alt.uk-alert-close(href="#") + p + div + if(user.mfa && user.mfa.active) + a(onclick="switchMFA(event)").uk-button.uk-button-primary Disable + if(!user.mfa || !user.mfa.active) + a(onclick="switchMFA(event)").uk-button.uk-button-primary Enable + if(user.mfa && user.mfa.active) + div(class="uk-flex uk-flex-between uk-margin-bottom", uk-grid) + div(class="uk-width-1-1") + if(user.mfa.data) + //- sort by number + - user.mfa.data.sort(function(a, b) {return a.no - b.no; }) + each option in user.mfa.data + .uk-card.uk-card-default.uk-card-body.uk-margin-bottom.uk-width-1-1 + .uk-flex.uk-flex-between + div + h3.uk-card-title= "Authentication Layer: "+option.no + div + p= "type: " + span.uk-badge= option.type + .uk-flex.uk-flex-between + div + a.uk-button.uk-button-default(onclick="showMFASecret(event)", id="secret.show."+option.type+"."+option.no) Show/Hide Secret + div + a.uk-button.uk-button-primary(onclick="removeMFA(event)", id="secret.remove."+option.type+"."+option.no) remove Layer + p(class="secret uk-hidden", id="secret."+option.type+"."+option.no, data-secret=option.data)= "SECRET: " + option.data + + +append content + if(session && session.user) + .uk-container + +settings() + else + include blocks/login.pug diff --git a/res/web/js/custom.js b/res/web/js/custom.js index b135ae8..6a70640 100644 --- a/res/web/js/custom.js +++ b/res/web/js/custom.js @@ -70,6 +70,101 @@ function cancelRequest() { }; } +// '/settings', shows MFA Secret on button click +function showMFASecret(e) { + let secret = document.getElementById(e.target.id).parentNode.parentNode.parentNode.getElementsByClassName("secret")[0]; + if(!secret.classList.contains("uk-hidden")) { + secret.classList.add("uk-hidden"); + } else { + secret.classList.remove("uk-hidden"); + let secretData = secret.dataset.secret; + let options = secret.id.split("."); + // @TODO + switch (options[1]) { + case "HOTP": + break; + case "TOTP": + break; + case "WebAuthn": + break; + default: + + } + } + return false; +} +// @TODO +// '/settings', removes MFA Layer +function removeMFA(e) { + return false; +} + +// '/settings', saves Profile +function saveProfile(e) { + let email = document.getElementById("form-profile-email").value; + + let data = { + "email": email + }; + + let ajax = new XMLHttpRequest(); + ajax.open("POST", "/api/settings", true); + ajax.setRequestHeader('Content-Type', 'application/json; charset=UTF-8'); + ajax.send(JSON.stringify(data)); + ajax.onload = () => { + let json = JSON.parse(ajax.responseText); + let box = document.getElementById("profile_msg"); + + box.classList.remove("uk-hidden"); + box.classList.remove("uk-alert-success"); + box.classList.remove("uk-alert-danger"); + + if(json.message && json.message == "msg.settings.update.successful") { + + box.classList.add("uk-alert-success"); + box.getElementsByTagName("p")[0].innerHTML = "Update was successfully"; + } else if(json.message) { + box.classList.add("uk-alert-danger"); + box.getElementsByTagName("p")[0].innerHTML = "Update failed"; + } + }; + return false; +} + +// '/settings', saves Password +function savePassword(e) { + let pass = document.getElementById("form-security-password").value; + let repass = document.getElementById("form-security-repassword").value; + + let data = { + "password": pass, + "repassword": repass + }; + + let ajax = new XMLHttpRequest(); + ajax.open("POST", "/api/settings", true); + ajax.setRequestHeader('Content-Type', 'application/json; charset=UTF-8'); + ajax.send(JSON.stringify(data)); + ajax.onload = () => { + let json = JSON.parse(ajax.responseText); + let box = document.getElementById("password_msg"); + + box.classList.remove("uk-hidden"); + box.classList.remove("uk-alert-success"); + box.classList.remove("uk-alert-danger"); + + if(json.message && json.message == "msg.settings.update.successful") { + + box.classList.add("uk-alert-success"); + box.getElementsByTagName("p")[0].innerHTML = "Update was successfully"; + } else if(json.message) { + box.classList.add("uk-alert-danger"); + box.getElementsByTagName("p")[0].innerHTML = "Update failed"; + } + }; + return false; +} + // @url: https://stackoverflow.com/a/901144 function getParameterByName(name) { let url = window.location.href;