diff options
| author | Nathan Reiner <nathan@nathanreiner.xyz> | 2025-11-25 09:27:51 +0100 |
|---|---|---|
| committer | Nathan Reiner <nathan@nathanreiner.xyz> | 2025-11-25 09:27:51 +0100 |
| commit | 605b03bfbd36e41819000ee0aed80df3c767b069 (patch) | |
| tree | 2458e1432d0673fe86b560dd20e1392136580f54 | |
| parent | dc36b1684c4da47defe8d3941ef60efb7cd8087e (diff) | |
fix login dialog and logout
| -rw-r--r-- | src/routes/api/session/root.zig | 4 | ||||
| -rw-r--r-- | src/storage/session-manager/root.zig | 6 | ||||
| -rw-r--r-- | static/api/session.js | 4 | ||||
| -rw-r--r-- | static/index.js | 3 | ||||
| -rw-r--r-- | static/pages/login/index.css | 4 | ||||
| -rw-r--r-- | static/pages/login/index.js | 71 |
6 files changed, 55 insertions, 37 deletions
diff --git a/src/routes/api/session/root.zig b/src/routes/api/session/root.zig index c8c2223..a889869 100644 --- a/src/routes/api/session/root.zig +++ b/src/routes/api/session/root.zig @@ -1,7 +1,7 @@ const HandlerInfo = @import("../../handler-info.zig"); pub const current: HandlerInfo = .from_type(@import("current.zig")); -pub const drop: HandlerInfo = .from_type(@import("renew.zig")); -pub const renew: HandlerInfo = .from_type(@import("drop.zig")); +pub const drop: HandlerInfo = .from_type(@import("drop.zig")); +pub const renew: HandlerInfo = .from_type(@import("renew.zig")); pub const @"is-valid": HandlerInfo = .from_type(@import("is-valid.zig")); pub const @"is-online": HandlerInfo = .from_type(@import("is-online.zig")); diff --git a/src/storage/session-manager/root.zig b/src/storage/session-manager/root.zig index 8a59f21..db95629 100644 --- a/src/storage/session-manager/root.zig +++ b/src/storage/session-manager/root.zig @@ -46,13 +46,13 @@ pub fn renew(self: *Self, storage: *Storage, fingerprint: []const u8) !*Session pub fn remove(self: *Self, storage: *Storage, fingerprint: []const u8) void { self.rw_lock.lockShared(); - if (self.cache.getPtr(fingerprint)) |session| { + if (self.cache.contains(fingerprint)) { self.rw_lock.unlockShared(); self.rw_lock.lock(); defer self.rw_lock.unlock(); - session.deinit(storage.allocator); - _ = self.cache.remove(fingerprint); + const kv = self.cache.fetchRemove(fingerprint) orelse return; + kv.value.deinit(storage.allocator); } else { self.rw_lock.unlockShared(); } diff --git a/static/api/session.js b/static/api/session.js index 870709f..6e14d55 100644 --- a/static/api/session.js +++ b/static/api/session.js @@ -9,6 +9,10 @@ export async function is_valid() { return result.is_valid; } +export async function drop() { + const result = await rest.get('/api/session/drop'); +} + export async function is_online() { try { const result = await rest.get('/api/session/is-online'); diff --git a/static/index.js b/static/index.js index e67d234..338d636 100644 --- a/static/index.js +++ b/static/index.js @@ -59,7 +59,8 @@ const month_select = MonthSelect.new({ const upload_bar = UploadBar.new(); const settings = SettingsView.new({ - onlogout: () => { + onlogout: async () => { + await api.session.drop(); login.show(); main.active_view = image_viewer; settings.profile = null; diff --git a/static/pages/login/index.css b/static/pages/login/index.css index f4a99ba..d9d0f41 100644 --- a/static/pages/login/index.css +++ b/static/pages/login/index.css @@ -37,7 +37,7 @@ background: #0000; } -#box button { +#box #submit { border-top-left-radius: 0px; border-bottom-left-radius: 0px; background: var(--page-background); @@ -46,7 +46,7 @@ background: #0000; } -#username { +#username-label { position: absolute; top: calc(50% - 40px); left: 50%; diff --git a/static/pages/login/index.js b/static/pages/login/index.js index 2cdd4c6..dae12e6 100644 --- a/static/pages/login/index.js +++ b/static/pages/login/index.js @@ -1,13 +1,14 @@ import icons from 'icons'; import * as sfw from 'sfw'; -const { Div, Label, H1: Title, Input, Button } = sfw.element.native; +const { Div, Label, H1: Title, Input, Button, Form } = sfw.element.native; const css = await sfw.css(import.meta.url, './index.css'); export default class LoginView extends sfw.element.Container { #container - #input #user + #username + #password #comment constructor() { @@ -16,30 +17,43 @@ export default class LoginView extends sfw.element.Container { this.onlogin = () => {}; this.onpassword = () => {}; - this.#user = null; - this.body.append( this.#container = Div.new({ id: 'container', children: [ Div.new({ id: 'title', innerText: 'Memora' }), this.#user = Div.new({ - id: 'username', + id: 'username-label', onclick: () => this.#reset(), }), - Div.new({ + Form.new({ id: 'box', + onsubmit: (e) => e.preventDefault(), children: [ - this.#input = Input.new({ + this.#username = Input.new({ + id: 'username', placeholder: 'Username', autocomplete: 'username', onkeydown: (e) => { if (e.key === 'Enter') { - return this.#next(); + return this.#go_to_password(); + } + }, + }), + this.#password = Input.new({ + id: 'password', + placeholder: 'Password', + autocomplete: 'current-password', + type: 'password', + style: { display: 'none' }, + onkeydown: (e) => { + if (e.key === 'Enter') { + return this.#login(); } }, }), Button.new({ + id: 'submit', children: [ icons.next ], onclick: () => this.#next(), }), @@ -58,31 +72,30 @@ export default class LoginView extends sfw.element.Container { ); } - async #next() { - if (this.#input.value === '') return; - - if (this.#user.innerText) { - await this.onlogin(this.#user.innerText, this.#input.value); - this.#user.innerText = ''; - this.#input.value = ''; - this.#input.placeholder = 'Username'; - this.#input.autocomplete = 'username'; - this.#input.type = 'text'; + #next() { + if (this.#username.style.display == '') { + this.#login(); } else { - await this.onpassword(this.#input.value); - this.#user.innerText = this.#input.value; - this.#input.value = ''; - this.#input.placeholder = 'Password'; - this.#input.autocomplete = 'current-password'; - this.#input.type = 'password'; + this.#go_to_password(); } } + #go_to_password() { + if (this.#username.value === '') return; + + this.#username.style.display = 'none'; + this.#password.style.display = ''; + this.#password.focus(); + } + + async #login() { + await this.onlogin(this.#username.value, this.#password.value); + this.#reset(); + } + #reset() { - this.#user.innerText = ''; - this.#input.value = ''; - this.#input.placeholder = 'Username'; - this.#input.type = 'text'; + this.#username.value = ''; + this.#password.value = ''; } set comment(value) { @@ -99,6 +112,6 @@ export default class LoginView extends sfw.element.Container { } focus() { - this.#input.focus(); + this.#username.focus(); } } |