From 8a6719fe268281a8031f819e06ca646f6eaf20fe Mon Sep 17 00:00:00 2001 From: Luka Vandervelden Date: Thu, 2 Jan 2020 10:40:45 +0100 Subject: [PATCH] client/ split to a separate repository. Repository URL is https://git.karchnu.fr/WeirdOS/authd-maquettec.git --- client/authws.ls | 141 --------------- client/bulma.ls | 39 ----- client/index.html | 12 -- client/index.ls | 92 ---------- client/login-form.ls | 221 ------------------------ client/style.sass | 9 - client/user-admin-panel.ls | 63 ------- client/user-configuration-panel.ls | 267 ----------------------------- 8 files changed, 844 deletions(-) delete mode 100644 client/authws.ls delete mode 100644 client/bulma.ls delete mode 100644 client/index.html delete mode 100644 client/index.ls delete mode 100644 client/login-form.ls delete mode 100644 client/style.sass delete mode 100644 client/user-admin-panel.ls delete mode 100644 client/user-configuration-panel.ls diff --git a/client/authws.ls b/client/authws.ls deleted file mode 100644 index d0f2eb7..0000000 --- a/client/authws.ls +++ /dev/null @@ -1,141 +0,0 @@ -bulma = require "./bulma.ls" -h = require 'maquette' .h - -AuthWS = (socket-url) -> - self = {} - - request-types = { - "get-token": 0 - "add-user": 1 - "get-user": 2 - "get-user-by-credentials": 3 - "mod-user": 4 - "register": 5 - "get-extra": 6 - "set-extra": 7 - "update-password": 8 - "list-users": 9 - } - - response-types = { - "error": 0 - "token": 1 - "user": 2 - "user-added": 3 - "user-edited": 4 - "extra": 5 - "extra-updated": 6 - "users-list": 7 - } - - # TODO: naming convention - # users can record functions to run on events - self.user-on-socket-error = [] - self.user-on-socket-close = [] - - self.callbacks = {} - for key, value of response-types - self.callbacks[value] = [] - - self.add-event-listener = (type, callback) -> - type = response-types[type] - - self.callbacks[type] ++= [callback] - - self.open-socket = -> - self.socket := new WebSocket socket-url - - self.socket.onerror = (event) -> - for f in self.user-on-socket-error - f event - self.socket.close! - - self.socket.onclose = (event) -> - for f in self.user-on-socket-close - f event - - self.socket.onmessage = (event) -> - message = JSON.parse(event.data) - - for f in self.callbacks[message.mtype] - f JSON.parse(message.payload) - - self.reopen = -> - self.socket.close! - self.open-socket! - - self.open-socket! - - self.send = (type, opts) -> - self.socket.send JSON.stringify { mtype: type, payload: opts } - - self.get-token = (login, password) -> - self.send request-types[\get-token], JSON.stringify { - login: login - password: password - } - - self.get-user-by-credentials = (login, password) -> - self.send request-types[\get-user-by-credentials], JSON.stringify { - login: login - password: password - } - - self.login = (login, password) -> - self.get-token login, password - self.get-user-by-credentials login, password - - - self.get-user = (uid) -> - self.send request-types[\get-user], JSON.stringify { - uid: uid - } - - self.register = (login, password) -> - self.send request-types[\register], JSON.stringify { - login: login - password: password - } - - self.get-extra = (token, name) -> - self.send request-types[\get-extra], JSON.stringify { - token: token - name: name - } - - self.set-extra = (token, name, extra) -> - self.send request-types[\set-extra], JSON.stringify { - token: token - name: name - extra: extra - } - - self.update-password = (login, old-password, new-password) -> - self.send request-types[\update-password], JSON.stringify { - login: login - old_password: old-password - new_password: new-password - } - - self.list-users = (token) -> - self.send request-types[\list-users], JSON.stringify { - token: token - } - - # TODO: authd overhaul required - #self.add-user = (login, password) -> - # self.send request-types[\add-user], JSON.stringify { - # login: login - # password: password - # } - - # TODO: authd overhaul required - #self.mod-user = (uid) -> - # self.send request-types[\mod-user], JSON.stringify { - # uid: uid - # } - - self - -module.exports = AuthWS - diff --git a/client/bulma.ls b/client/bulma.ls deleted file mode 100644 index ad315a6..0000000 --- a/client/bulma.ls +++ /dev/null @@ -1,39 +0,0 @@ - -h = require 'maquette' .h - -module.exports = { - box: (args, children) -> - h \div.box args, children - title: (level, args, label) -> - if not label - label = args - args = {} - - h "div.title.is-#{level}", args, [label] - label: (args, label) -> - if not label - label = args - args = {} - - h \label.label args, [label] - input: (args, children) -> - h \input.input args, children - - # FIXME: Use only args and add args.label and args.input? - # Or maybe args.name and args.type could be used directly? - field: (args, children) -> - h \div.field args, children - - modal: (args, content) -> - h \div.modal args, [ - h \div.modal-background args.background - h \div.modal-content [args.content] - ] - - form: (method, url, content) -> - h \form.form { - action: url - method: method - }, content -} - diff --git a/client/index.html b/client/index.html deleted file mode 100644 index 0417d01..0000000 --- a/client/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - AuthD - - - - - - - - diff --git a/client/index.ls b/client/index.ls deleted file mode 100644 index 4b47414..0000000 --- a/client/index.ls +++ /dev/null @@ -1,92 +0,0 @@ -maquette = require "maquette" - -{create-projector, h} = maquette - -projector = create-projector! - -bulma = require "./bulma.ls" - -AuthWS = require "./authws.ls" - -LoginForm = require "./login-form.ls" -UserConfigurationPanel = require "./user-configuration-panel.ls" -UserAdminPanel = require "./user-admin-panel.ls" - -model = { - token: void -} - -authws-url = "ws://localhost:9999/auth.JSON" - -document.add-event-listener \DOMContentLoaded -> - user-config-panel = void - user-admin-panel = void - - login-form = LoginForm { - enable-registration: true - authws-url: authws-url - - on-login: (user, token) -> - model.user := user - model.token := token - - if user.groups.find (== "authd") - user-admin-panel := UserAdminPanel { - authws-url: authws-url - user: model.user - token: model.token - - on-model-update: -> - projector.schedule-render! - on-logout: -> - model.token := void - model.user := void - } - else - user-config-panel := UserConfigurationPanel { - authws-url: authws-url - user: model.user - token: model.token - - on-model-update: -> - projector.schedule-render! - on-logout: -> - model.token := void - model.user := void - } - - projector.schedule-render! - on-error: (error) -> - projector.schedule-render! - } - - projector.append document.body, -> - h \div.body [ - if model.token == void - h \div.section.hero.is-fullheight [ - h \div.hero-body [ - h \div.container [ - h \div.columns [ - h \div.column [] - h \div.column.is-3 [ - login-form.render! - ] - h \div.column [] - ] - ] - ] - ] - else if user-config-panel - h \div.section [ - h \div.container [ - user-config-panel.render! - ] - ] - else if user-admin-panel - h \div.section [ - h \div.container [ - user-admin-panel.render! - ] - ] - ] - diff --git a/client/login-form.ls b/client/login-form.ls deleted file mode 100644 index 90f08a7..0000000 --- a/client/login-form.ls +++ /dev/null @@ -1,221 +0,0 @@ -maquette = require "maquette" - -{h} = maquette - -bulma = require "./bulma.ls" - -AuthWS = require "./authws.ls" - -LoginForm = (args) -> - args or= {} - - self = { - on-login: args.on-login || -> - on-error: args.on-error || -> - schedule-render: args.schedule-render || -> - current-view: "login" - - enable-registration: args.enable-registration || false - registrating: false - - input: { - login: "" - password: "" - repeat-password: "" - } - locked-input: true - - error: void - - authws-url: args.authws-url || - ((if location.protocol == 'https' then 'wss' else 'ws') + - '://' + location.hostname + ":9999/auth.JSON") - } - - - auth-ws = AuthWS self.authws-url - - auth-ws.socket.onopen = -> - self.locked-input := false - self.schedule-render! - - auth-ws.user-on-socket-error.push (...) -> - self.error = "socket error" - self.on-error ... - - auth-ws.add-event-listener \token, (message) -> - self.error := void - - self.token = message.token - self.locked-input := false - - if self.user - self.on-login self.user, self.token - - auth-ws.add-event-listener \user, (message) -> - self.error := void - - self.user = message.user - - if self.token - self.on-login self.user, self.token - - auth-ws.add-event-listener \user-added, (message) -> - {login, password} = {self.input.login, self.input.password} - - console.log "user added, duh" - - self.user := message.user - - auth-ws.get-token login, password - - auth-ws.add-event-listener \error, (message) -> - # We’ll get another error that’s clearer. Dropping that one. - if message.reason == "user not found" - return - - self.error := message.reason - self.locked-input := false - - self.on-error message.reason - - self.render = -> - if self.error == "socket error" - return h \div.notification.is-danger [ - h \div.title.is-4 [ "WebSocket error!" ] - h \p [ "Cannot connect to authd." ] - ] - - h \form.form.login-form { - key: self - onsubmit: (e) -> - {login, password} = {self.input.login, self.input.password} - - self.locked-input := true - - if self.registrating - auth-ws.register login, password - else - auth-ws.get-token login, password - auth-ws.get-user-by-credentials login, password - - e.prevent-default! - }, [ - h \div.field {key: \login} [ - bulma.label "Login" - bulma.input { - type: "text" - id: "login" - name: "login" - classes: { - "is-danger": self.error == "invalid credentials" - } - disabled: self.locked-input - oninput: (e) -> - self.input.login = e.target.value - } - ] - - h \div.field {key: \password} [ - bulma.label "Password" - bulma.input { - type: "password" - id: "password" - name: "password" - classes: { - "is-danger": self.error == "invalid credentials" - } - oninput: (e) -> - self.input.password = e.target.value - disabled: self.locked-input - } - ] - - if self.registrating - h \div.field {key: \password-repeat} [ - bulma.label "Password (reapeat)" - bulma.input { - type: \password - id: \password-repeat - name: \password-repeat - classes: { - "is-danger": self.input.password != self.input.repeat-password - } - disabled: self.locked-input - oninput: (e) -> - self.input.repeat-password = e.target.value - } - ] - - if self.error - h \div.field {key: \error-notification} [ - h \div.notification.is-danger [ - self.error - ] - ] - - if self.registrating - h \div.field.is-grouped {key: \login-button} [ - if self.input.login == "" - h \button.button.is-static.is-fullwidth { - type: \submit - } [ - "(empty login)" - ] - else if self.input.password != self.input.repeat-password - h \button.button.is-static.is-fullwidth { - type: \submit - } [ - "(passwords don’t match)" - ] - else if self.input.password == "" - h \button.button.is-static.is-fullwidth { - type: \submit - } [ - "(empty password)" - ] - else - h \button.button.is-success.is-fullwidth { - type: \submit - } [ - "Register!" - ] - ] - else - h \div.field.is-grouped {key: \login-button} [ - h \button.button.is-fullwidth.is-success { - type: \submit - } [ - "Log in!" - ] - ] - - h \div.field.level {key: \extra-buttons} [ - #h \div.level-left [ - # h \a.link [ "(lala, remember me?)" ] - #] - - if self.enable-registration - h \div.level-right [ - if self.registrating - h \a.link { - onclick: (e) -> - self.registrating := false - } [ - "Log in" - ] - else - h \a.link { - onclick: (e) -> - self.registrating := true - } [ - "Create account!" - ] - ] - ] - ] - - self - -module.exports = LoginForm - diff --git a/client/style.sass b/client/style.sass deleted file mode 100644 index 78c4ff6..0000000 --- a/client/style.sass +++ /dev/null @@ -1,9 +0,0 @@ -@charset "utf-8" - -//@import "../node_modules/bulmaswatch/superhero/_variables.scss" - -// Import Bulma core -@import "../node_modules/bulma/bulma" - -//@import "../node_modules/bulmaswatch/superhero/_overrides.scss" - diff --git a/client/user-admin-panel.ls b/client/user-admin-panel.ls deleted file mode 100644 index 69fa625..0000000 --- a/client/user-admin-panel.ls +++ /dev/null @@ -1,63 +0,0 @@ -{h} = require "maquette" - -AuthWS = require "./authws.ls" - -UserAdminPanel = (args) -> - self = { - token: args.token - authws-url: args.authws-url - on-logout: args.on-logout || -> - on-model-update: args.on-model-update || -> - users: [] - } - - authws = AuthWS self.authws-url - - authws.socket.onopen = -> - authws.list-users self.token - - authws.add-event-listener \users-list (message) -> - self.users = message.users - - self.on-model-update! - - self.render = -> - h \div.section [ - h \div.container [ - h \table.table.is-fullwidth [ - h \thead [ - h \tr [ - h \th [ "Login" ] - h \th [ "UID" ] - h \th [ "GID" ] - ] - ] - h \tbody [ - for user in self.users - h \tr {key: user.uid} [ - h \td [ - user.login - ] - h \td [ - user.uid.toString! - ] - h \td [ - user.gid.toString! - ] - ] - ] - ] - ] - h \div.button { - onclick: -> - self.on-logout! - self.on-model-update! - } [ - "Log out" - ] - ] - - self - -module.exports = UserAdminPanel - diff --git a/client/user-configuration-panel.ls b/client/user-configuration-panel.ls deleted file mode 100644 index bc11d81..0000000 --- a/client/user-configuration-panel.ls +++ /dev/null @@ -1,267 +0,0 @@ - -{h} = require "maquette" - -AuthWS = require "./authws.ls" - -get-full-name = (self) -> - full-name = self.profile && self.profile.full-name || "" - if full-name == "" - self.user.login - else - full-name - -default-side-bar-renderer = (self) -> - h \div { key: \side-bar } [ - h \figure.image.is-128x128.is-clipped [ - if self.profile && self.profile.avatar - h \img { - src: self.profile.avatar - alt: "Avatar of #{get-full-name self}" - } - ] - ] - -default-heading-renderer = (self) -> - full-name = get-full-name self - - h \div.section {key: \heading} [ - h \div.media [ - h \div.media-content [ - h \div.title.is-2 [ full-name ] - - if full-name != self.user.login - h \div.title.is-3.subtitle [ - self.user.login - ] - ] - - if self.on-logout - h \div.media-right [ - h \a { - onclick: -> - self.on-logout! - } [ "Logout" ] - ] - ] - ] - - -Fields = { - render-text-input: (token, auth-ws, key, inputs, model, on-request) -> - upload = -> - console.log "clickity click", key, inputs[key], inputs - return unless inputs[key] - - payload = {} - for _key, value of model - payload[_key] = value - payload[key] = inputs[key] - - inputs[key] := void - - on-request! - auth-ws.set-extra token, "profile", payload - - h \div.field.has-addons {key: key} [ - h \div.control.is-expanded [ - h \input.input { - value: inputs[key] || model[key] - oninput: (e) -> - console.log "input for",key - inputs[key] := e.target.value - } - ] - h \div.control [ - h \div.button { - onclick: upload - } [ "Update" ] - ] - ] -} - -UserConfigurationPanel = (args) -> - self = { - user: args.user || {} - profile: args.profile - token: args.token - authws-url: args.authws-url || - ((if location.protocol == 'https' then 'wss' else 'ws') + - '://' + location.hostname + ":9999/auth.JSON") - - side-bar-renderer: args.side-bar-renderer || default-side-bar-renderer - heading-renderer: args.heading-renderer || default-heading-renderer - - on-model-update: args.on-model-update || -> - on-logout: args.on-logout || void - - model: args.model || [ - ["fullName", "Full Name", "string"] - ["avatar", "Profile Picture", "image-url"] - ["email", "Mail Address", "string"] - ] - - input: {} - } - - auth-ws = AuthWS self.authws-url - - auth-ws.add-event-listener \extra, (message) -> - if message.name == "profile" - console.log "got profile", message.extra - self.profile = message.extra || {} - - self.on-model-update! - - auth-ws.add-event-listener \extra-updated, (message) -> - if message.name == "profile" - console.log "got profile", message.extra - self.profile = message.extra || {} - - self.on-model-update! - - auth-ws.add-event-listener \error, (message) -> - self.error := message.reason - - self.on-model-update! - - # Profile updates would be a \extra-updated, so this is specific to the - # password. - auth-ws.add-event-listener \user-edited, (message) -> - self.input["password.old"] := void - self.input["password.new"] := void - self.input["password.new2"] := void - self.success := "password" - self.on-model-update! - - unless self.profile - auth-ws.socket.onopen = -> - auth-ws.get-extra self.token, "profile" - - self.render = -> - h \div.columns { - key: self - } [ - h \div.column.is-narrow [ - self.side-bar-renderer self - ] - h \div.column [ - self.heading-renderer self - - if self.profile - h \div.box {key: \profile} [ - h \div.form [ - h \div.title.is-4 [ "Profile" ] - - for element in self.model - [key, label, type] = element - - switch type - when "string", "image-url" - h \div.field { key: key } [ - h \div.label [ label ] - Fields.render-text-input self.token, auth-ws, key, self.input, self.profile, (-> self.error := void) - ] - ] - ] - else - # FIXME: urk, ugly loader. - h \div.button.is-loading - - h \div.box { key: \password } [ - h \div.title.is-4 [ "Password" ] - h \div.label [ "Old password" ] - h \div.control [ - h \input.input { - type: \password - value: self.input["password.old"] - oninput: (e) -> - self.input["password.old"] = e.target.value - } - - if self.error == "invalid credentials" - h \div.help.is-danger [ - "The old password was invalid!" - ] - ] - h \div.label [ "New password" ] - h \div.control [ - h \input.input { - type: \password - value: self.input["password.new"] - oninput: (e) -> - self.input["password.new"] = e.target.value - } - ] - h \div.label [ "New password (repeat)" ] - h \div.field.has-addons [ - h \div.control.is-expanded [ - h \input.input { - type: \password - value: self.input["password.new2"] - oninput: (e) -> - self.input["password.new2"] = e.target.value - } - ] - h \div.control [ - h \div.button { - classes: { - "is-danger": self.input["password.new"] && self.input["password.new"] != self.input["password.new2"] - "is-static": (!self.input["password.new"]) && self.input["password.new"] != self.input["password.new2"] - } - onclick: -> - if self.input["password.new"] != self.input["password.new2"] - return - - self.error := void - auth-ws.update-password self.user.login, self.input["password.old"], self.input["password.new"] - - } [ "Update" ] - ] - ] - - if self.success == "password" - h \div.help.is-success [ - "Password successfully updated!" - ] - ] - - if self.show-developer - h \div.box {key: \passwd} [ - h \div.title.is-4 [ "Permissions" ] - - h \div.form [ - h \div.field {key: \uid} [ - h \div.label [ "User ID" ] - h \div.control [ self.user.uid.to-string! ] - ] - - h \div.field {key: \gid} [ - h \div.label [ "Group ID" ] - h \div.control [ self.user.gid.to-string! ] - ] - - h \div.field {key: \groups} [ - h \div.label [ "Groups" ] - h \div.control.is-grouped [ - h \div.tags self.user.groups.map (group) -> - h \div.tag [ group ] - ] - ] - ] - ] - else - h \a.is-pulled-right.is-small.has-text-grey { - key: \passwd - onclick: -> - self.show-developer := true - self.on-model-update! - } [ - "Show developer data!" - ] - ] - ] - - self - -module.exports = UserConfigurationPanel -