Fix login flow after rollback
This commit is contained in:
@@ -1,10 +1,9 @@
|
|||||||
packaging_format = 2
|
packaging_format = 2
|
||||||
id = "albumik"
|
id = "albumik"
|
||||||
name = "Albumik"
|
name = "Albumik"
|
||||||
logo = "assets/albumik-logo.png"
|
|
||||||
description.en = "Lightweight private photo album with folder permissions and guest uploads"
|
description.en = "Lightweight private photo album with folder permissions and guest uploads"
|
||||||
description.pl = "Lekki prywatny album zdjęć z katalogami, gośćmi i akceptacją zdjęć"
|
description.pl = "Lekki prywatny album zdjęć z katalogami, gośćmi i akceptacją zdjęć"
|
||||||
version = "0.1.2~ynh1"
|
version = "0.1.0~ynh1"
|
||||||
maintainers = ["Filip"]
|
maintainers = ["Filip"]
|
||||||
|
|
||||||
[upstream]
|
[upstream]
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
source ./_common.sh
|
||||||
source "$SCRIPT_DIR/_common.sh"
|
|
||||||
|
|
||||||
mkdir -p "$YNH_BACKUP_DIR"
|
mkdir -p "$YNH_BACKUP_DIR"
|
||||||
tar -C / -czf "$YNH_BACKUP_DIR/albumik-data.tar.gz" "${data_dir#/}" "${config_dir#/}" "${install_dir#/}" 2>/dev/null || true
|
tar -C / -czf "$YNH_BACKUP_DIR/albumik-data.tar.gz" "${data_dir#/}" "${config_dir#/}" "${install_dir#/}" 2>/dev/null || true
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
source ./_common.sh
|
||||||
source "$SCRIPT_DIR/_common.sh"
|
|
||||||
|
|
||||||
# YunoHost install args
|
# YunoHost install args
|
||||||
# packaging v2 passes these variables to scripts.
|
# packaging v2 passes these variables to scripts.
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
source ./_common.sh
|
||||||
source "$SCRIPT_DIR/_common.sh"
|
|
||||||
|
|
||||||
domain=$(yunohost app setting "$app" domain 2>/dev/null || echo "")
|
domain=$(yunohost app setting "$app" domain 2>/dev/null || echo "")
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
source ./_common.sh
|
||||||
source "$SCRIPT_DIR/_common.sh"
|
|
||||||
|
|
||||||
if [ -f "$YNH_BACKUP_DIR/albumik-data.tar.gz" ]; then
|
if [ -f "$YNH_BACKUP_DIR/albumik-data.tar.gz" ]; then
|
||||||
tar -C / -xzf "$YNH_BACKUP_DIR/albumik-data.tar.gz"
|
tar -C / -xzf "$YNH_BACKUP_DIR/albumik-data.tar.gz"
|
||||||
|
|||||||
@@ -1,22 +1,13 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
source ./_common.sh
|
||||||
source "$SCRIPT_DIR/_common.sh"
|
|
||||||
|
|
||||||
app="${YNH_APP_INSTANCE_NAME:-albumik}"
|
|
||||||
|
|
||||||
|
systemctl stop "$app" 2>/dev/null || true
|
||||||
mkdir -p "$install_dir"
|
mkdir -p "$install_dir"
|
||||||
|
|
||||||
rm -rf "$install_dir/backend" "$install_dir/web" "$install_dir/doc"
|
rm -rf "$install_dir/backend" "$install_dir/web" "$install_dir/doc"
|
||||||
|
cp -a backend web doc "$install_dir"/
|
||||||
cp -a "$YNH_APP_BASEDIR/backend" "$YNH_APP_BASEDIR/web" "$YNH_APP_BASEDIR/doc" "$install_dir"/
|
|
||||||
|
|
||||||
chown -R "$app:$app" "$install_dir"
|
chown -R "$app:$app" "$install_dir"
|
||||||
|
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl restart "$app"
|
systemctl start "$app"
|
||||||
|
systemctl reload nginx || true
|
||||||
nginx -t
|
|
||||||
systemctl reload nginx
|
|
||||||
|
|
||||||
echo "Albumik upgraded"
|
echo "Albumik upgraded"
|
||||||
|
|||||||
93
web/app.js
93
web/app.js
@@ -155,7 +155,7 @@ $('#loginForm').addEventListener('submit', async e=>{
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
$('#loginError').textContent = '';
|
$('#loginError').textContent = '';
|
||||||
const fd = new FormData(e.currentTarget);
|
const fd = new FormData(e.currentTarget);
|
||||||
try { await api('/api/login', {method:'POST', body: JSON.stringify(Object.fromEntries(fd))}); await init(); }
|
try { await api('/api/login', {method:'POST', body: JSON.stringify(Object.fromEntries(fd))}); window.location.href = '/'; return; }
|
||||||
catch(err){ $('#loginError').textContent = err.message; }
|
catch(err){ $('#loginError').textContent = err.message; }
|
||||||
});
|
});
|
||||||
$('#logoutBtn').addEventListener('click', async()=>{ await api('/api/logout',{method:'POST',body:'{}'}); location.reload(); });
|
$('#logoutBtn').addEventListener('click', async()=>{ await api('/api/logout',{method:'POST',body:'{}'}); location.reload(); });
|
||||||
@@ -221,94 +221,3 @@ $('#rejectPhotoBtn').addEventListener('click', async()=>{
|
|||||||
});
|
});
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
function renderAccountView() {
|
|
||||||
const main = document.querySelector("#content") || document.querySelector("main") || document.querySelector(".main");
|
|
||||||
if (!main) return;
|
|
||||||
|
|
||||||
const user = state.user || {};
|
|
||||||
main.innerHTML = `
|
|
||||||
<div class="header">
|
|
||||||
<h1>Moje konto</h1>
|
|
||||||
<p>Zmień swoje hasło i sprawdź informacje o koncie.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card account-card" style="padding:24px;margin-top:24px;">
|
|
||||||
<h2>Dane konta</h2>
|
|
||||||
<div class="list-row"><strong>Login</strong><span>${escapeHtml(user.username || '')}</span></div>
|
|
||||||
<div class="list-row"><strong>Nazwa</strong><span>${escapeHtml(user.display_name || '')}</span></div>
|
|
||||||
<div class="list-row"><strong>Rola</strong><span>${escapeHtml(user.role || '')}</span></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card account-card" style="padding:24px;margin-top:18px;">
|
|
||||||
<h2>Zmiana hasła</h2>
|
|
||||||
<form id="changePasswordForm">
|
|
||||||
<div class="field">
|
|
||||||
<label>Obecne hasło</label>
|
|
||||||
<input name="current_password" type="password" required />
|
|
||||||
</div>
|
|
||||||
<div class="field">
|
|
||||||
<label>Nowe hasło</label>
|
|
||||||
<input name="new_password" type="password" minlength="8" required />
|
|
||||||
</div>
|
|
||||||
<div class="field">
|
|
||||||
<label>Powtórz nowe hasło</label>
|
|
||||||
<input name="repeat_password" type="password" minlength="8" required />
|
|
||||||
</div>
|
|
||||||
<div class="form-error" id="changePasswordError"></div>
|
|
||||||
<button class="primary-btn" type="submit" style="margin-top:16px;">Zmień hasło</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
document.querySelector("#changePasswordForm")?.addEventListener("submit", async (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
const fd = new FormData(e.currentTarget);
|
|
||||||
const current_password = fd.get("current_password");
|
|
||||||
const new_password = fd.get("new_password");
|
|
||||||
const repeat_password = fd.get("repeat_password");
|
|
||||||
const err = document.querySelector("#changePasswordError");
|
|
||||||
|
|
||||||
if (new_password !== repeat_password) {
|
|
||||||
err.textContent = "Nowe hasła nie są takie same.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const res = await api("/api/me/password", {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({ current_password, new_password })
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
err.textContent = res.error || "Nie udało się zmienić hasła.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
err.style.color = "#16a34a";
|
|
||||||
err.textContent = "Hasło zostało zmienione.";
|
|
||||||
e.currentTarget.reset();
|
|
||||||
} catch (ex) {
|
|
||||||
err.textContent = "Błąd połączenia z serwerem.";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function escapeHtml(value) {
|
|
||||||
return String(value ?? "")
|
|
||||||
.replaceAll("&", "&")
|
|
||||||
.replaceAll("<", "<")
|
|
||||||
.replaceAll(">", ">")
|
|
||||||
.replaceAll('"', """)
|
|
||||||
.replaceAll("'", "'");
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener("click", (e) => {
|
|
||||||
const btn = e.target.closest("[data-view='account']");
|
|
||||||
if (!btn) return;
|
|
||||||
e.preventDefault();
|
|
||||||
state.currentView = "account";
|
|
||||||
document.querySelectorAll(".nav-btn").forEach(b => b.classList.remove("active"));
|
|
||||||
btn.classList.add("active");
|
|
||||||
renderAccountView();
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -4,15 +4,15 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<title>Albumik</title>
|
<title>Albumik</title>
|
||||||
<link rel="stylesheet" href="/styles.css" />
|
<link rel="stylesheet" href="styles.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="login" class="login-shell hidden">
|
<div id="login" class="login-shell hidden">
|
||||||
<div class="login-card">
|
<div class="login-card">
|
||||||
<img class="login-logo-small" src="/assets/albumik-logo.png" alt="Albumik" />
|
<div class="brand-badge">A</div>
|
||||||
<h1>Albumik</h1>
|
<h1>Albumik</h1>
|
||||||
<p>Lekki prywatny album zdjęć na Twoim serwerze.</p>
|
<p>Lekki prywatny album zdjęć na Twoim serwerze.</p>
|
||||||
<form id="loginForm">
|
<form id="loginForm" method="post">
|
||||||
<label>Login</label>
|
<label>Login</label>
|
||||||
<input name="username" autocomplete="username" placeholder="admin" required />
|
<input name="username" autocomplete="username" placeholder="admin" required />
|
||||||
<label>Hasło</label>
|
<label>Hasło</label>
|
||||||
@@ -21,7 +21,6 @@
|
|||||||
<div id="loginError" class="error-line"></div>
|
<div id="loginError" class="error-line"></div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="app" class="app hidden">
|
<div id="app" class="app hidden">
|
||||||
@@ -40,7 +39,6 @@
|
|||||||
<button class="nav-item" data-view="tags"><span>Tagi</span></button>
|
<button class="nav-item" data-view="tags"><span>Tagi</span></button>
|
||||||
<button class="nav-item admin-only" data-view="users"><span>Użytkownicy</span></button>
|
<button class="nav-item admin-only" data-view="users"><span>Użytkownicy</span></button>
|
||||||
<button class="nav-item admin-only" data-view="logs"><span>Dziennik</span></button>
|
<button class="nav-item admin-only" data-view="logs"><span>Dziennik</span></button>
|
||||||
<button class="nav-btn" data-view="account">Moje konto</button>
|
|
||||||
</nav>
|
</nav>
|
||||||
<div class="sidebar-footer">
|
<div class="sidebar-footer">
|
||||||
<div id="currentUser" class="current-user"></div>
|
<div id="currentUser" class="current-user"></div>
|
||||||
@@ -192,6 +190,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
||||||
<script src="/app.js"></script>
|
<script src="app.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
640
web/styles.css
640
web/styles.css
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user