diff --git a/main.go b/main.go index 67b2fa7..d808ea3 100644 --- a/main.go +++ b/main.go @@ -20,9 +20,9 @@ import ( _ "embed" ) -const VERSION = "v11"; +const VERSION = "v10"; const LISTEN_HOST = "0.0.0.0"; -const DB_SCHEMA = 13 +const DB_SCHEMA = 12 var ( flagPort int @@ -64,23 +64,22 @@ func main() {// {{{ go connectionManager.BroadcastLoop() static = http.FileServer(http.Dir(config.Application.Directories.Static)) - http.HandleFunc("/css_updated", cssUpdateHandler) - http.HandleFunc("/session/create", sessionCreate) - http.HandleFunc("/session/retrieve", sessionRetrieve) + http.HandleFunc("/css_updated", cssUpdateHandler) + http.HandleFunc("/session/create", sessionCreate) + http.HandleFunc("/session/retrieve", sessionRetrieve) http.HandleFunc("/session/authenticate", sessionAuthenticate) - http.HandleFunc("/user/password", userPassword) - http.HandleFunc("/node/tree", nodeTree) - http.HandleFunc("/node/retrieve", nodeRetrieve) - http.HandleFunc("/node/create", nodeCreate) - http.HandleFunc("/node/update", nodeUpdate) - http.HandleFunc("/node/rename", nodeRename) - http.HandleFunc("/node/delete", nodeDelete) - http.HandleFunc("/node/upload", nodeUpload) - http.HandleFunc("/node/download", nodeDownload) - http.HandleFunc("/node/search", nodeSearch) - http.HandleFunc("/key/retrieve", keyRetrieve) - http.HandleFunc("/key/create", keyCreate) - http.HandleFunc("/key/counter", keyCounter) + http.HandleFunc("/node/tree", nodeTree) + http.HandleFunc("/node/retrieve", nodeRetrieve) + http.HandleFunc("/node/create", nodeCreate) + http.HandleFunc("/node/update", nodeUpdate) + http.HandleFunc("/node/rename", nodeRename) + http.HandleFunc("/node/delete", nodeDelete) + http.HandleFunc("/node/upload", nodeUpload) + http.HandleFunc("/node/download", nodeDownload) + http.HandleFunc("/node/search", nodeSearch) + http.HandleFunc("/key/retrieve", keyRetrieve) + http.HandleFunc("/key/create", keyCreate) + http.HandleFunc("/key/counter", keyCounter) http.HandleFunc("/ws", websocketHandler) http.HandleFunc("/", staticHandler) @@ -202,37 +201,6 @@ func sessionAuthenticate(w http.ResponseWriter, r *http.Request) {// {{{ }) }// }}} -func userPassword(w http.ResponseWriter, r *http.Request) {// {{{ - var err error - var ok bool - var session Session - - if session, _, err = ValidateSession(r, true); err != nil { - responseError(w, err) - return - } - - req := struct { - CurrentPassword string - NewPassword string - }{} - if err = parseRequest(r, &req); err != nil { - responseError(w, err) - return - } - - ok, err = session.UpdatePassword(req.CurrentPassword, req.NewPassword) - if err != nil { - responseError(w, err) - return - } - - responseData(w, map[string]interface{}{ - "OK": true, - "CurrentPasswordOK": ok, - }) -}// }}} - func nodeTree(w http.ResponseWriter, r *http.Request) {// {{{ var err error var session Session diff --git a/session.go b/session.go index 53d163e..2457eb3 100644 --- a/session.go +++ b/session.go @@ -91,7 +91,7 @@ func (session *Session) Authenticate(username, password string) (authenticated b FROM public.user WHERE username=$1 AND - password=password_hash(SUBSTRING(password FROM 1 FOR 32), $2::bytea) + password=$2 `, username, password, diff --git a/sql/0013.sql b/sql/0013.sql deleted file mode 100644 index d8fb23d..0000000 --- a/sql/0013.sql +++ /dev/null @@ -1,34 +0,0 @@ -/* Required for the gen_random_bytes function */ -CREATE EXTENSION pgcrypto; - -CREATE FUNCTION password_hash(salt_hex char(32), pass bytea) -RETURNS char(96) -LANGUAGE plpgsql -AS -$$ -BEGIN - RETURN ( - SELECT - salt_hex || - encode( - sha256( - decode(salt_hex, 'hex') || /* salt in binary */ - pass /* password */ - ), - 'hex' - ) - ); -END; -$$; - -/* Password has to be able to accommodate 96 characters instead of previous 64. - * It can't be char(96), because then the password would be padded to 96 characters. */ -ALTER TABLE public."user" ALTER COLUMN "password" TYPE varchar(96) USING "password"::varchar; - -/* Update all users with salted and hashed passwords */ -UPDATE public.user -SET password = password_hash( encode(gen_random_bytes(16),'hex'), password::bytea); - -/* After the password hashing, all passwords are now hex encoded 32 characters salt and 64 characters hash, - * and the varchar type is not longer necessary. */ -ALTER TABLE public."user" ALTER COLUMN "password" TYPE char(96) USING "password"::varchar; diff --git a/static/css/main.css b/static/css/main.css index 552928f..63d21b9 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -55,13 +55,6 @@ button { border: 2px solid #000; box-shadow: 5px 5px 8px 0px rgba(0, 0, 0, 0.5); z-index: 1025; - width: min-content; -} -#menu .section { - padding: 16px 16px 0px 16px; - font-weight: bold; - white-space: nowrap; - color: #c84a37; } #menu .item { padding: 16px; @@ -144,7 +137,7 @@ button { header { display: grid; grid-area: header; - grid-template-columns: min-content 1fr repeat(4, min-content); + grid-template-columns: min-content 1fr repeat(3, min-content); align-items: center; padding: 8px 0px; color: #333c11; @@ -168,13 +161,17 @@ header .name { padding-left: 16px; font-size: 1.25em; } -header .search, -header .add, +header .add { + padding-right: 16px; + cursor: pointer; +} +header .add img { + cursor: pointer; + height: 24px; +} header .keys { padding-right: 16px; } -header .search img, -header .add img, header .keys img { cursor: pointer; height: 24px; @@ -279,11 +276,6 @@ header .menu { margin-bottom: 32px; font-size: 1.5em; } -#notes-version { - margin-top: 64px; - color: #888; - text-align: center; -} #node-content.encrypted { color: #a00; } @@ -546,19 +538,6 @@ header .menu { #app.node.toggle-tree #tree { display: none; } -#profile-settings { - color: #333; - padding: 16px; -} -#profile-settings .passwords { - display: grid; - grid-template-columns: min-content 200px; - grid-gap: 8px 16px; - margin-bottom: 16px; -} -#profile-settings .passwords div { - white-space: nowrap; -} @media only screen and (max-width: 932px) { #app.node { grid-template-areas: "header" "crumbs" "child-nodes" "name" "content" "files" "blank"; diff --git a/static/images/search.svg b/static/images/search.svg deleted file mode 100644 index 28b3b5f..0000000 --- a/static/images/search.svg +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/static/js/node.mjs b/static/js/node.mjs index 6f1b4bf..282614c 100644 --- a/static/js/node.mjs +++ b/static/js/node.mjs @@ -57,7 +57,7 @@ export class NodeUI extends Component { case 'node': if(node.ID == 0) { page = html` - ${children.length > 0 ? html`
${children}
Notes version ${window._VERSION}
` : html``} + ${children.length > 0 ? html`
${children}
` : html``} ` } else { let padlock = '' @@ -86,10 +86,6 @@ export class NodeUI extends Component { page = html`<${Keys} nodeui=${this} />` break - case 'profile-settings': - page = html`<${ProfileSettings} nodeui=${this} />` - break - case 'search': page = html`<${Search} nodeui=${this} />` break @@ -104,10 +100,9 @@ export class NodeUI extends Component {
this.saveNode()}>
document.getElementById('app').classList.toggle('toggle-tree')} />
Notes
- -
this.createNode(evt)}>
-
{ evt.stopPropagation(); this.showPage('keys')}}>
- +
this.createNode(evt)}>
+
{ evt.stopPropagation(); this.showPage('keys')}}>
+
@@ -218,11 +213,7 @@ export class NodeUI extends Component { this.node.value.create(name, nodeID=>this.goToNode(nodeID)) }//}}} saveNode() {//{{{ - let nodeContent = this.nodeContent.current - if(this.page.value != 'node' || nodeContent === null) - return - - let content = nodeContent.contentDiv.current.value + let content = this.nodeContent.current.contentDiv.current.value this.node.value.setContent(content) this.node.value.save(()=>this.props.app.nodeModified.value = false) }//}}} @@ -556,14 +547,10 @@ class Menu extends Component { return html`
nodeui.menu.value = false}>
` @@ -801,77 +788,4 @@ class Search extends Component { }//}}} } -class ProfileSettings extends Component { - render({ nodeui }, {}) {//{{{ - return html` -
-

User settings

- -

Password

-
-
Current
- this.keyHandler(evt)} /> - -
New
- this.keyHandler(evt)} /> - -
Repeat
- this.keyHandler(evt)} /> -
- - -
` - }//}}} - componentDidMount() {//{{{ - document.getElementById('current-password').focus() - }//}}} - - keyHandler(evt) {//{{{ - let handled = true - - switch(evt.key.toUpperCase()) { - case 'ENTER': - this.updatePassword() - break - - default: - handled = false - } - - if(handled) { - evt.preventDefault() - evt.stopPropagation() - } - }//}}} - updatePassword() {//{{{ - let curr_pass = document.getElementById('current-password').value - let pass1 = document.getElementById('new-password1').value - let pass2 = document.getElementById('new-password2').value - - try { - if(pass1.length < 4) { - throw new Error('Password has to be at least 4 characters long') - } - - if(pass1 != pass2) { - throw new Error(`Passwords don't match`) - } - - window._app.current.request('/user/password', { - CurrentPassword: curr_pass, - NewPassword: pass1, - }) - .then(res=>{ - if(res.CurrentPasswordOK) - alert('Password is changed successfully') - else - alert('Current password is invalid') - }) - } catch(err) { - alert(err.message) - } - - }//}}} -} - // vim: foldmethod=marker diff --git a/static/less/main.less b/static/less/main.less index c885ec8..7435f57 100644 --- a/static/less/main.less +++ b/static/less/main.less @@ -56,14 +56,6 @@ button { border: 2px solid #000; box-shadow: 5px 5px 8px 0px rgba(0,0,0,0.5); z-index: 1025; - width: min-content; - - .section { - padding: 16px 16px 0px 16px; - font-weight: bold; - white-space: nowrap; - color: @accent_3; - } .item { padding: 16px; @@ -162,7 +154,7 @@ button { header { display: grid; grid-area: header; - grid-template-columns: min-content 1fr repeat(4, min-content); + grid-template-columns: min-content 1fr repeat(3, min-content); align-items: center; padding: 8px 0px; color: darken(@accent_1, 35%); @@ -189,7 +181,17 @@ header { font-size: 1.25em; } - .search, .add, .keys { + .add { + padding-right: 16px; + cursor: pointer; + + img { + cursor: pointer; + height: 24px; + } + } + + .keys { padding-right: 16px; img { @@ -322,12 +324,6 @@ header { font-size: 1.5em; } -#notes-version { - margin-top: 64px; - color: #888; - text-align: center; -} - #node-content.encrypted { color: #a00; } @@ -621,22 +617,6 @@ header { } -#profile-settings { - color: #333; - padding: 16px; - - .passwords { - display: grid; - grid-template-columns: min-content 200px; - grid-gap: 8px 16px; - margin-bottom: 16px; - - div { - white-space: nowrap; - } - } -} - @media only screen and (max-width: 932px) { #app.node { .layout-crumbs(); diff --git a/user.go b/user.go deleted file mode 100644 index 0d9b4ee..0000000 --- a/user.go +++ /dev/null @@ -1,37 +0,0 @@ -package main - -import ( - // Standard - "database/sql" -) - -func (session Session) UpdatePassword(currPass, newPass string) (ok bool, err error) { - var result sql.Result - var rowsAffected int64 - - result, err = db.Exec(` - UPDATE public.user - SET - password = password_hash( - /* salt in hex */ - ENCODE(gen_random_bytes(16), 'hex'), - - /* password */ - $1::bytea - ) - WHERE - id = $2 AND - password=password_hash(SUBSTRING(password FROM 1 FOR 32), $3::bytea) - RETURNING id - `, - newPass, - session.UserID, - currPass, - ) - - if rowsAffected, err = result.RowsAffected(); err != nil { - return - } - - return rowsAffected > 0, nil -}