diff --git a/authentication/pkg.go b/authentication/pkg.go index c0b9a2e..9eb6245 100644 --- a/authentication/pkg.go +++ b/authentication/pkg.go @@ -8,9 +8,6 @@ import ( "github.com/jmoiron/sqlx" "github.com/lib/pq" - // Internal - appUser "notes2/user" - // Standard "database/sql" "encoding/hex" @@ -30,6 +27,12 @@ type Manager struct { ExpireDays int } +type User struct { + ID int + Username string + Name string +} + func httpError(w http.ResponseWriter, err error) { // {{{ j, _ := json.Marshal(struct { OK bool @@ -162,16 +165,16 @@ func (mngr *Manager) AuthenticationHandler(w http.ResponseWriter, r *http.Reques mngr.log.Info("authentication", "username", request.Username, "status", "accepted") j, _ := json.Marshal(struct { OK bool - User appUser.User + User User Token string }{true, user, token}) w.Write(j) } // }}} -func (mngr *Manager) Authenticate(username, password string) (authenticated bool, user appUser.User, err error) { // {{{ +func (mngr *Manager) Authenticate(username, password string) (authenticated bool, user User, err error) { // {{{ var row *sql.Row row = mngr.db.QueryRow(` - SELECT id, username, name, preferences + SELECT id, username, name FROM public.user WHERE LOWER(username) = LOWER($1) AND @@ -180,21 +183,13 @@ func (mngr *Manager) Authenticate(username, password string) (authenticated bool username, password, ) - var data []byte - err = row.Scan(&user.ID, &user.Username, &user.Name, &data) + err = row.Scan(&user.ID, &user.Username, &user.Name) if err != nil && err.Error() == "sql: no rows in result set" { err = nil authenticated = false return } if err != nil { - authenticated = false - return - } - - err = json.Unmarshal(data, &user.Preferences) - if err != nil { - authenticated = false return } @@ -283,7 +278,7 @@ func (mngr *Manager) ChangePassword(username, currentPassword, newPassword strin changed = (rowsAffected == 1) return } // }}} -func (mngr *Manager) NewClientUUID(user appUser.User) (clientUUID string, err error) { // {{{ +func (mngr *Manager) NewClientUUID(user User) (clientUUID string, err error) { // {{{ // Each client session has its own UUID. // Loop through until a unique one is established. var proposedClientUUID string diff --git a/main.go b/main.go index 6e3cf94..2917566 100644 --- a/main.go +++ b/main.go @@ -4,7 +4,6 @@ import ( // Internal "notes2/authentication" "notes2/html_template" - appUser "notes2/user" "os" // Standard @@ -24,7 +23,7 @@ import ( "text/template" ) -const VERSION = "v29" +const VERSION = "v25" const CONTEXT_USER = 1 const SYNC_PAGINATION = 200 @@ -135,8 +134,6 @@ func main() { // {{{ http.HandleFunc("/offline", pageOffline) http.HandleFunc("/user/authenticate", AuthManager.AuthenticationHandler) - http.HandleFunc("GET /user/preferences", authenticated(actionUserGetPreferences)) - http.HandleFunc("POST /user/preferences", authenticated(actionUserSetPreferences)) http.HandleFunc("/sync/from_server/count/{sequence}", authenticated(actionSyncFromServerCount)) http.HandleFunc("/sync/from_server/{sequence}/{offset}", authenticated(actionSyncFromServer)) @@ -181,7 +178,7 @@ func authenticated(fn func(http.ResponseWriter, *http.Request)) func(http.Respon } // User object is added to the context for the next handler. - user := appUser.NewUser(claims) + user := NewUser(claims) r = r.WithContext(context.WithValue(r.Context(), CONTEXT_USER, user)) Log.Debug("webserver", "op", "request", "method", r.Method, "url", r.URL.String(), "username", user.Username, "client", user.ClientUUID) @@ -269,7 +266,7 @@ func actionSyncFromServer(w http.ResponseWriter, r *http.Request) { // {{{ // The purpose of the Client UUID is to avoid // sending nodes back once again to a client that // just created or modified it. - user := getUserSession(r) + user := getUser(r) changedFrom, _ := strconv.Atoi(r.PathValue("sequence")) offset, _ := strconv.Atoi(r.PathValue("offset")) @@ -292,7 +289,7 @@ func actionSyncFromServerCount(w http.ResponseWriter, r *http.Request) { // {{{ // The purpose of the Client UUID is to avoid // sending nodes back once again to a client that // just created or modified it. - user := getUserSession(r) + user := getUser(r) changedFrom, _ := strconv.Atoi(r.PathValue("sequence")) count, err := NodesCount(user.UserID, uint64(changedFrom), user.ClientUUID) @@ -312,7 +309,7 @@ func actionSyncFromServerCount(w http.ResponseWriter, r *http.Request) { // {{{ w.Write(j) } // }}} func actionNodeRetrieve(w http.ResponseWriter, r *http.Request) { // {{{ - user := getUserSession(r) + user := getUser(r) var err error uuid := r.PathValue("uuid") @@ -328,7 +325,7 @@ func actionNodeRetrieve(w http.ResponseWriter, r *http.Request) { // {{{ }) } // }}} func actionNodeHistoryRetrieve(w http.ResponseWriter, r *http.Request) { // {{{ - user := getUserSession(r) + user := getUser(r) var err error uuid := r.PathValue("uuid") @@ -351,7 +348,7 @@ func actionNodeHistoryRetrieve(w http.ResponseWriter, r *http.Request) { // {{{ }) } // }}} func actionNodeHistoryCount(w http.ResponseWriter, r *http.Request) { // {{{ - user := getUserSession(r) + user := getUser(r) var err error uuid := r.PathValue("uuid") @@ -363,12 +360,12 @@ func actionNodeHistoryCount(w http.ResponseWriter, r *http.Request) { // {{{ } responseData(w, map[string]any{ - "OK": true, - "Count": count, + "OK": true, + "Count": count, }) } // }}} func actionSyncToServer(w http.ResponseWriter, r *http.Request) { // {{{ - user := getUserSession(r) + user := getUser(r) body, _ := io.ReadAll(r.Body) var request struct { @@ -392,47 +389,6 @@ func actionSyncToServer(w http.ResponseWriter, r *http.Request) { // {{{ }) } // }}} -func actionUserGetPreferences(w http.ResponseWriter, r *http.Request) { // {{{ - user := getUserSession(r) - prefs, err := user.Preferences() - if err != nil { - httpError(w, err) - return - } - - responseData(w, map[string]any{ - "OK": true, - "Preferences": prefs, - }) -} // }}} -func actionUserSetPreferences(w http.ResponseWriter, r *http.Request) { // {{{ - session := getUserSession(r) - - // Verify the "default" profile is still there. - var newPrefs map[string]appUser.UserPreferences - body, _ := io.ReadAll(r.Body) - err := json.Unmarshal(body, &newPrefs) - if err != nil { - httpError(w, err) - return - } - - if _, found := newPrefs["default"]; !found { - httpError(w, fmt.Errorf("'default' profile missing.")) - return - } - - err = session.SetPreferences(newPrefs) - if err != nil { - httpError(w, err) - return - } - - responseData(w, map[string]any{ - "OK": true, - }) -} // }}} - func createNewUser(username string) { // {{{ reader := bufio.NewReader(os.Stdin) @@ -475,8 +431,7 @@ func changePassword(username string) { // {{{ fmt.Printf("\nPassword changed\n") } // }}} -func getUserSession(r *http.Request) appUser.UserSession { // {{{ - user, _ := r.Context().Value(CONTEXT_USER).(appUser.UserSession) - user.Db = db +func getUser(r *http.Request) UserSession { // {{{ + user, _ := r.Context().Value(CONTEXT_USER).(UserSession) return user } // }}} diff --git a/sql/00010.sql b/sql/00010.sql deleted file mode 100644 index ecd8ab4..0000000 --- a/sql/00010.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE public."user" ADD preferences jsonb DEFAULT '{}' NOT NULL; diff --git a/static/css/markdown.css b/static/css/markdown.css index 832d4a2..1ecbc94 100644 --- a/static/css/markdown.css +++ b/static/css/markdown.css @@ -102,11 +102,6 @@ border: 1px solid #ccc; padding: 2px 4px; border-radius: 4px; - - &.copy { - border: var(--markdown-copy-border); - background-color: var(--markdown-copy-background); - } } pre { @@ -116,14 +111,6 @@ border-radius: 4px; white-space: pre-wrap; - &.copy { - border: var(--markdown-copy-border); - background-color: var(--markdown-copy-background); - code { - background-color: inherit !important; - } - } - code { border: unset; padding: unset; diff --git a/static/css/notes2.css b/static/css/notes2.css index 7fdea0b..2d9f074 100644 --- a/static/css/notes2.css +++ b/static/css/notes2.css @@ -15,9 +15,6 @@ --menu-item-hover-color: #f4f4f4; --font-monospace: "Liberation Mono", monospace; - - --markdown-copy-border: 1px solid #0a0; - --markdown-copy-background: #e3f4d7; } html { @@ -73,10 +70,9 @@ button { 1fr; } - /* The other pages just gets the whole page without dividing it up. */ - &:not(.page-node) { + &.page-history { grid-template-areas: - "tree-expander tree pad1 n2-page pad2" + "tree-expander tree pad1 n2-pagehistory pad2" ; grid-template-columns: @@ -246,6 +242,7 @@ button { #notes2 { &.page-node { + #page-root { display: none; } @@ -260,7 +257,7 @@ button { display: contents; n2-pagestorage { - grid-area: n2-page; + grid-area: content; } } } @@ -268,14 +265,9 @@ button { &.page-history { #page-history { display: grid; - grid-area: n2-page; - } - } + grid-area: n2-pagehistory; - &.page-preferences { - #page-preferences { - display: block; - grid-area: n2-page; + n2-pagehistory {} } } @@ -287,6 +279,7 @@ button { #page-root { display: contents !important; } + } } diff --git a/static/images/icon_menu.svg b/static/images/icon_menu.svg index cfdd1e8..e60bdee 100644 --- a/static/images/icon_menu.svg +++ b/static/images/icon_menu.svg @@ -2,18 +2,18 @@ + transform="translate(-146.57917,-92.339583)"> +
`
+ return ``
+ (token.escaped ? code : escapeHtmlEntities(code, true))
+ '
\n'
}
- return `'
+ (token.escaped ? code : escapeHtmlEntities(code, true))
@@ -285,7 +260,7 @@ export class MarkedPosition {
},
codespan(token) {
- return `${escapeHtmlEntities(token.text, true)}`
+ return `${escapeHtmlEntities(token.text, true)}`
},
br(token) {
diff --git a/static/js/page_preferences.mjs b/static/js/page_preferences.mjs
deleted file mode 100644
index 9655278..0000000
--- a/static/js/page_preferences.mjs
+++ /dev/null
@@ -1,283 +0,0 @@
-import { CustomHTMLElement } from "./lib/custom_html_element.mjs"
-import { API } from './api.mjs'
-
-export class N2PagePreferences extends CustomHTMLElement {
- static {// {{{
- this.tmpl = document.createElement('template')
- this.tmpl.innerHTML = `
-
- Preferences
-
- Changes preferences to not download images or files on the device doesn't remove the already downloaded data.
-
-
- Device preference set
-
-
-
-
-
-
-
- `
- }// }}}
- constructor() {// {{{
- super(true)
- this.sets = []
-
- this.elNewSet.addEventListener('click', () => this.newSet())
- this.elSave.addEventListener('click', () => this.save())
- this.elDevPreferenceSet.addEventListener('change', event=>this.changePreferenceSet(event))
-
- window._mbus.subscribe('SHOW_PAGE', async event => {
- if (event.detail.data?.page == 'preferences') {
- this.sets = await this.getPreferenceSets()
- this.render()
- }
- })
-
- window._mbus.subscribe('PREFERENCE_SET_MODIFIED', () => this.preferencesModified())
- window._mbus.subscribe('PREFERENCE_SET_DELETE', event => this.preferencesDelete(event.detail.data.set))
- }// }}}
- sortSets(a, b) {// {{{
- if (a.name == 'default') return -1
- if (b.name == 'default') return 1
-
- if (a.name.toLowerCase() < b.name.toLowerCase()) return -1
- if (a.name.toLowerCase() > b.name.toLowerCase()) return 1
-
- return 0
- }// }}}
- async render() {// {{{
- try {
- this.sets.sort(this.sortSets)
- this.elSets.replaceChildren(...this.sets)
-
- const setNames = this.sets.entries().map(([i, set]) => {
- const optn = document.createElement('option')
- optn.innerText = set.name
- return optn
- })
- this.elDevPreferenceSet.replaceChildren(...setNames)
- } catch (e) {
- console.error(e)
- alert(e.message)
- }
- }// }}}
- async getPreferenceSets() {// {{{
- const userData = localStorage.getItem('user')
- if (userData === null)
- throw new Error('Could not find user in localStorage')
-
- const user = JSON.parse(userData)
- const prefsData = user.Preferences
-
- if (prefsData === undefined)
- throw new Error('User object is missing preferences')
-
- if (!prefsData.hasOwnProperty('default'))
- throw new Error('The "default" preferences set is missing')
-
- return Object.keys(prefsData).map(name => new N2PreferenceSet(name, prefsData[name]))
- }// }}}
- async retrieveServerPreferences() {// {{{
- try {
- API.query('GET', '/user/preferences')
- } catch (e) {
- console.error(e)
- alert(`Error retrieving preferences: ${e.message}`)
- }
- }// }}}
- changePreferenceSet(event) {// {{{
- this.preferencesModified()
- }// }}}
- newSet() {// {{{
- let name = prompt("Name for new preference set")
- if (!name)
- return
-
- name = name.trim()
- if (name === '')
- return
-
- if (name == 'default') {
- alert(`Name can't be "default".`)
- return
- }
-
- const exists = this.sets.some(s => s.name.toLowerCase() == name.toLowerCase())
- if (exists) {
- alert(`Set with name "${name}" already exist.`)
- return
- }
-
- this.sets.push(new N2PreferenceSet(name, {}))
- this.preferencesModified()
- this.render()
- }// }}}
- preferencesModified() {// {{{
- this.elSave.removeAttribute('disabled')
- }// }}}
- preferencesDelete(deleteSet) {// {{{
- if (deleteSet.name == 'default') {
- alert("Can't delete the default set.")
- return
- }
-
- if (!confirm(`Confirm deleting "${deleteSet.name}"`))
- return
-
- this.sets = this.sets.filter(set => {
- return !(set.name === deleteSet.name)
- })
-
- this.preferencesModified()
- this.render()
- }// }}}
- async save() {// {{{
- try {
- let newPrefs = {}
- this.sets.forEach(s => {
- const setState = s.getState()
- newPrefs[setState.name] = setState.state
- })
-
- // Throws exception on both HTTP and application errors.
- await API.query('POST', '/user/preferences', newPrefs)
-
- const userData = localStorage.getItem('user')
- const user = JSON.parse(userData)
- user.Preferences = newPrefs
- localStorage.setItem('user', JSON.stringify(user))
- localStorage.setItem('device_preference_set', this.elDevPreferenceSet.value)
- _mbus.dispatch('DEVICE_PREFERENCE_SET_UPDATED')
- } catch (e) {
- console.error(e)
- alert(e.message)
- } finally {
- this.elSave.setAttribute('disabled', true)
- }
-
- }// }}}
-}
-customElements.define('n2-pagepreferences', N2PagePreferences)
-
-// Preferences is a set of preferences, of which there can be many named.
-export class N2PreferenceSet extends CustomHTMLElement {
- static {// {{{
- this.tmpl = document.createElement('template')
- this.tmpl.innerHTML = `
-
-
-
-
- ✘
-
-
-
-
-
-
-
- `
- }// }}}
- constructor(name, data) {// {{{
- super(true)
- this.name = name
- this.data = data
- this.render()
-
- // Enable the save button when settings are modified.
- this.allFields().forEach(f =>
- f.addEventListener('input', () => _mbus.dispatch('PREFERENCE_SET_MODIFIED'))
- )
-
- this.elName.addEventListener('click', () => this.updateName())
- this.elDelete.addEventListener('click', () => this.deleteSet())
- }// }}}
- updateName() {// {{{
- if (this.name == 'default') {
- alert('Can not change name of the default profile.')
- return
- }
-
- const name = prompt("Change name", this.name)
- if (!name)
- return
-
- this.name = name
- this.render()
- _mbus.dispatch('PREFERENCE_SET_MODIFIED')
- }// }}}
- deleteSet() {// {{{
- _mbus.dispatch('PREFERENCE_SET_DELETE', { set: this })
- }// }}}
- render() {// {{{
- this.elName.innerText = this.name
-
- this.fieldDownloadImages.checked = this.data.DownloadImages
- this.fieldDownloadFiles.checked = this.data.DownloadFiles
- }// }}}
- getState() {// {{{
- const name = this.name.trim()
- if (name === '')
- throw new Error('Name can not be empty.')
-
- return {
- name: this.name.trim(),
- state: this.fieldValues(),
- }
- }// }}}
-}
-customElements.define('n2-preferenceset', N2PreferenceSet)
diff --git a/static/js/page_storage.mjs b/static/js/page_storage.mjs
index a007130..931a718 100644
--- a/static/js/page_storage.mjs
+++ b/static/js/page_storage.mjs
@@ -13,10 +13,7 @@ export class N2PageStorage extends CustomHTMLElement {
constructor() {
super()
- window._mbus.subscribe('SHOW_PAGE', event => {
- if (event.detail.data?.page == 'storage')
- this.render()
- })
+ window._mbus.subscribe('SHOW_PAGE', () => this.render())
}
async render() {
const countNodes = await globalThis.nodeStore.nodeCount()
diff --git a/static/js/sidebar.mjs b/static/js/sidebar.mjs
index 6cd5814..129b9d1 100644
--- a/static/js/sidebar.mjs
+++ b/static/js/sidebar.mjs
@@ -128,7 +128,6 @@ export class N2Sidebar extends CustomHTMLElement {
this.elSearch.addEventListener('click', () => _mbus.dispatch('op-search'))
this.elSync.addEventListener('click', () => _sync.run())
this.elLogo.addEventListener('click', () => _app.goToNode(ROOT_NODE, false, false))
- this.elSettings.addEventListener('click', ()=> _mbus.dispatch('SHOW_PAGE', { page: 'preferences' }))
this.elHideTree.addEventListener('click', event => {
event.stopPropagation()
_mbus.dispatch('TREE_EXPANSION', { expand: false })
@@ -198,8 +197,9 @@ export class N2Sidebar extends CustomHTMLElement {
this.expandedNodes[UUID] = false
return this.expandedNodes[UUID]
}//}}}
- async setNodeExpanded(node, value) {//{{{
+ setNodeExpanded(node, value) {//{{{
let expanded = this.expandedNodes[node.UUID]
+
if (expanded === undefined) {
this.expandedNodes[node.UUID] = false
expanded = false
@@ -249,6 +249,8 @@ export class N2Sidebar extends CustomHTMLElement {
// Holding shift down does it recursively.
case Space:
case 'Enter':
+ if (n.UUID === ROOT_NODE)
+ return
const expanded = this.getNodeExpanded(n.UUID)
if (event.shiftKey) {
this.recursiveExpand(n, !expanded)
@@ -257,31 +259,38 @@ export class N2Sidebar extends CustomHTMLElement {
}
break
+ case 'g':
case 'Home':
this.navigateTop()
break
+ case 'G':
case 'End':
this.navigateBottom()
break
+ case 'j':
case 'ArrowDown':
await this.navigateDown(this.selectedNode)
break
+ case 'k':
case 'ArrowUp':
await this.navigateUp(this.selectedNode)
break
+ case 'h':
case 'ArrowLeft':
await this.navigateLeft(this.selectedNode)
break
+ case 'l':
case 'ArrowRight':
await this.navigateRight(this.selectedNode)
break
default:
+ // nonsole.log(event.key)
handled = false
}
@@ -403,26 +412,23 @@ export class N2Sidebar extends CustomHTMLElement {
}//}}}
async navigateTop() {//{{{
const root = await nodeStore.get(ROOT_NODE)
- _mbus.dispatch("GO_TO_NODE", { nodeUUID: root.UUID, dontPush: false, dontExpand: true })
+ if (root.Children.length === 0)
+ return
+ _mbus.dispatch("GO_TO_NODE", { nodeUUID: root.Children[0]?.UUID, dontPush: false, dontExpand: true })
}//}}}
async navigateBottom() {//{{{
- const orphaned = await nodeStore.get(ORPHANED_NODE)
-
- if (!orphaned.hasChildren() || this.getNodeExpanded(orphaned.UUID)) {
- _mbus.dispatch("GO_TO_NODE", { nodeUUID: orphaned.UUID, dontPush: false, dontExpand: true })
+ const root = await nodeStore.get(ROOT_NODE)
+ if (root.Children.length === 0)
return
- }
- /* TODO - fix this when orphaned nodes are implemented.
- const toplevel = orphaned.Children[orphaned.Children.length - 1]
+ const toplevel = root.Children[root.Children.length - 1]
const toplevelExpanded = this.getNodeExpanded(toplevel?.UUID)
if (toplevelExpanded) {
const lastnode = this.getLastExpandedNode(toplevel)
_mbus.dispatch("GO_TO_NODE", { nodeUUID: lastnode?.UUID, dontPush: false, dontExpand: true })
} else
- _mbus.dispatch("GO_TO_NODE", { nodeUUID: orphaned.Children[orphaned.Children.length - 1]?.UUID, dontPush: false, dontExpand: true })
- */
+ _mbus.dispatch("GO_TO_NODE", { nodeUUID: root.Children[root.Children.length - 1]?.UUID, dontPush: false, dontExpand: true })
}//}}}
getParentWithNextSibling(node) {//{{{
@@ -443,10 +449,6 @@ export class N2Sidebar extends CustomHTMLElement {
if (state)
await this.setNodeExpanded(node, true)
- // An expanded node needs to have its children fetched.
- if (!node.hasFetchedChildren())
- await node.fetchChildren()
-
for (const child of node.Children)
await this.recursiveExpand(child, state)
@@ -575,12 +577,7 @@ export class N2TreeNode extends CustomHTMLElement {
this.rendered = false
this.dragNode = null
- this.elExpandToggle.addEventListener('click', event => {
- if (this.node.hasChildren())
- this.expandNode(event)
- else
- _mbus.dispatch('TREE_NODE_SELECTED', this.node)
- })
+ this.elExpandToggle.addEventListener('click', () => this.sidebar.setNodeExpanded(this.node, !this.sidebar.getNodeExpanded(this.node.UUID)))
this.elName.addEventListener('click', () => _mbus.dispatch('TREE_NODE_SELECTED', this.node))
_mbus.subscribe(`NODE_EXPAND_${node.UUID}`, _state => {
@@ -595,7 +592,6 @@ export class N2TreeNode extends CustomHTMLElement {
this.elName.addEventListener('dragenter', event => this.dragEnter(event))
this.elName.addEventListener('dragleave', event => this.dragLeave(event))
}// }}}
-
dragStart(e) {// {{{
if (this.node.isModified()) {
alert('Save note before moving it.')
@@ -658,16 +654,6 @@ export class N2TreeNode extends CustomHTMLElement {
_app.dragIcon.icon('')
this.classList.remove('drag-target')
}// }}}
-
- async expandNode(event) {// {{{
- const expanded = _app.sidebar.getNodeExpanded(this.node.UUID)
-
- if (event.shiftKey) {
- _app.sidebar.recursiveExpand(this.node, !expanded)
- } else {
- _app.sidebar.setNodeExpanded(this.node, !expanded)
- }
- }// }}}
async fetchChildren(force_fetch) {//{{{
if (this.children_populated && !force_fetch)
return
diff --git a/static/js/sync.mjs b/static/js/sync.mjs
index daa603f..fe72c3f 100644
--- a/static/js/sync.mjs
+++ b/static/js/sync.mjs
@@ -90,7 +90,6 @@ export class Sync {
nodeStore.setAppState('latest_sync_node', currMax)
} catch (e) {
console.error('sync node tree', e)
- alert(e.message)
} finally {
syncEnd = Date.now()
const duration = (syncEnd - syncStart) / 1000
@@ -158,8 +157,8 @@ export class Sync {
_mbus.dispatch('SYNC_UPLOADED', { count: nodesToSend.length })
} catch (e) {
- console.error(e)
- alert(e.message)
+ console.trace(e)
+ alert(e.error)
return
}
}
diff --git a/user.go b/user.go
new file mode 100644
index 0000000..b1c2abf
--- /dev/null
+++ b/user.go
@@ -0,0 +1,27 @@
+package main
+
+import (
+ // External
+ "github.com/golang-jwt/jwt/v5"
+)
+
+type UserSession struct {
+ UserID int
+ Username string
+ Password string
+ Name string
+ ClientUUID string
+}
+
+func NewUser(claims jwt.MapClaims) (u UserSession) {
+ uid, _ := claims["uid"].(float64)
+ name, _ := claims["name"].(string)
+ username, _ := claims["login"].(string)
+ clientUUID, _ := claims["cid"].(string)
+
+ u.UserID = int(uid)
+ u.Username = username
+ u.Name = name
+ u.ClientUUID = clientUUID
+ return
+}
diff --git a/user/pkg.go b/user/pkg.go
deleted file mode 100644
index bcdfac8..0000000
--- a/user/pkg.go
+++ /dev/null
@@ -1,63 +0,0 @@
-package user
-
-import (
- // External
- "github.com/golang-jwt/jwt/v5"
- "github.com/jmoiron/sqlx"
-
- // Standard
- "encoding/json"
-)
-
-type User struct {
- ID int
- Username string
- Name string
- Preferences map[string]UserPreferences
-}
-
-type UserSession struct {
- UserID int
- Username string
- Password string
- Name string
- ClientUUID string
- Db *sqlx.DB
-}
-
-type UserPreferences struct {
- DownloadImages bool
- DownloadFiles bool
-}
-
-func NewUser(claims jwt.MapClaims) (u UserSession) {
- uid, _ := claims["uid"].(float64)
- name, _ := claims["name"].(string)
- username, _ := claims["login"].(string)
- clientUUID, _ := claims["cid"].(string)
-
- u.UserID = int(uid)
- u.Username = username
- u.Name = name
- u.ClientUUID = clientUUID
- return
-}
-
-func (u UserSession) Preferences() (prefs map[string]UserPreferences, err error) {
- row := u.Db.QueryRow(`SELECT preferences FROM public.user WHERE id=$1`, u.UserID)
-
- var data []byte
- err = row.Scan(&data)
- if err != nil {
- return
- }
-
- err = json.Unmarshal(data, &prefs)
- return
-}
-
-func (u UserSession) SetPreferences(prefs map[string]UserPreferences) (err error) {
- j, _ := json.Marshal(prefs)
- _, err = u.Db.Exec(`UPDATE public.user SET preferences=$2 WHERE id=$1`, u.UserID, j)
- return
-}
diff --git a/views/pages/notes2.gotmpl b/views/pages/notes2.gotmpl
index 2755aea..d54c71d 100644
--- a/views/pages/notes2.gotmpl
+++ b/views/pages/notes2.gotmpl
@@ -32,10 +32,9 @@
-
-
-
-
+
+
+
@@ -47,7 +46,6 @@
import {App} from "/js/{{ .VERSION }}/app.mjs"
import {API} from 'api'
import {Sync} from 'sync'
- import { } from '/js/{{ .VERSION }}/page_preferences.mjs'
import { } from '/js/{{ .VERSION }}/page_storage.mjs'
import { } from '/js/{{ .VERSION }}/page_history.mjs'
import { } from '/js/{{ .VERSION }}/file.mjs'