Fix auth modal feedback and production deploy config
Some checks failed
Build & Push Docker Image to Gitea Registry / build-and-push (push) Failing after 6s

This commit is contained in:
Kroonk
2026-05-20 17:25:15 +02:00
parent 6f96b26e4c
commit 5e996f791e
4 changed files with 77 additions and 66 deletions

View File

@@ -10,7 +10,7 @@ WORKDIR /opt/michess/
COPY . . COPY . .
RUN corepack enable && \ RUN corepack enable && \
corepack prepare pnpm@latest --activate && \ corepack prepare pnpm@9.15.9 --activate && \
pnpm config set store-dir /opt/michess/.pnpm-store && \ pnpm config set store-dir /opt/michess/.pnpm-store && \
pnpm install --no-frozen-lockfile pnpm install --no-frozen-lockfile

View File

@@ -16,69 +16,68 @@ export default function AuthModal() {
const [buttonLoading, setButtonLoading] = useState(false); const [buttonLoading, setButtonLoading] = useState(false);
const modalToggleRef = useRef<HTMLInputElement>(null); const modalToggleRef = useRef<HTMLInputElement>(null);
function closeModal() {
if (modalToggleRef.current?.checked) {
modalToggleRef.current.checked = false;
}
}
async function submitAuth(e: FormEvent<HTMLFormElement>) { async function submitAuth(e: FormEvent<HTMLFormElement>) {
e.preventDefault(); e.preventDefault();
const target = e.target as HTMLFormElement; const target = e.target as HTMLFormElement;
if (activeTab === "guest") { setServerMessage(null);
const guestName = target.elements.namedItem("guestName") as HTMLInputElement; setButtonLoading(true);
if (!guestName || !guestName.value) return;
setButtonLoading(true); try {
const user = await setGuestSession(guestName.value); if (activeTab === "guest") {
if (user) { const guestName = target.elements.namedItem("guestName") as HTMLInputElement;
session?.setUser(user); if (!guestName || !guestName.value) return;
if (modalToggleRef.current?.checked) {
modalToggleRef.current.checked = false; const user = await setGuestSession(guestName.value);
} if (typeof user === "string") {
} setServerMessage(user);
guestName.value = ""; } else if (user?.id) {
} else if (activeTab === "login") { session?.setUser(user);
const loginName = target.elements.namedItem("loginName") as HTMLInputElement; closeModal();
const loginPassword = target.elements.namedItem("loginPassword") as HTMLInputElement; guestName.value = "";
if (!loginName || !loginName.value || !loginPassword || !loginPassword.value) return; }
} else if (activeTab === "login") {
setButtonLoading(true); const loginName = target.elements.namedItem("loginName") as HTMLInputElement;
const user = await login(loginName.value, loginPassword.value); const loginPassword = target.elements.namedItem("loginPassword") as HTMLInputElement;
if (typeof user === "string") { if (!loginName || !loginName.value || !loginPassword || !loginPassword.value) return;
setServerMessage(user);
} else if (user?.id) { const user = await login(loginName.value, loginPassword.value);
session?.setUser(user); if (typeof user === "string") {
if (serverMessage) { setServerMessage(user);
setServerMessage(null); } else if (user?.id) {
} session?.setUser(user);
if (modalToggleRef.current?.checked) { closeModal();
modalToggleRef.current.checked = false; }
} } else if (activeTab === "register") {
} const registerName = target.elements.namedItem("registerName") as HTMLInputElement;
} else if (activeTab === "register") { const registerEmail = target.elements.namedItem("registerEmail") as HTMLInputElement;
const registerName = target.elements.namedItem("registerName") as HTMLInputElement; const registerPassword = target.elements.namedItem("registerPassword") as HTMLInputElement;
const registerEmail = target.elements.namedItem("registerEmail") as HTMLInputElement; if (!registerName || !registerName.value || !registerPassword || !registerPassword.value) {
const registerPassword = target.elements.namedItem("registerPassword") as HTMLInputElement; return;
if (!registerName || !registerName.value || !registerPassword || !registerPassword.value) { }
return;
} const user = await register(
registerName.value,
setButtonLoading(true); registerPassword.value,
const user = await register( registerEmail.value || undefined
registerName.value, );
registerPassword.value,
registerEmail.value || undefined if (typeof user === "string") {
); setServerMessage(user);
} else if (user?.id) {
if (typeof user === "string") { session?.setUser(user);
setServerMessage(user); closeModal();
} else if (user?.id) {
session?.setUser(user);
if (serverMessage) {
setServerMessage(null);
}
if (modalToggleRef.current?.checked) {
modalToggleRef.current.checked = false;
} }
} }
} finally {
setButtonLoading(false);
} }
setButtonLoading(false);
} }
useEffect(() => { useEffect(() => {

View File

@@ -1,6 +1,19 @@
import { API_URL } from "@/config"; import { API_URL } from "@/config";
import type { User } from "@michess/types"; import type { User } from "@michess/types";
const readErrorMessage = async (res: Response, fallback: string) => {
try {
const body = await res.json();
if (typeof body?.message === "string") {
return body.message;
}
} catch (err) {
// Response did not include a JSON error body.
}
return fallback;
};
export const fetchSession = async () => { export const fetchSession = async () => {
try { try {
const res = await fetch(`${API_URL}/v1/auth`, { const res = await fetch(`${API_URL}/v1/auth`, {
@@ -30,8 +43,10 @@ export const setGuestSession = async (name: string) => {
const user: User = await res.json(); const user: User = await res.json();
return user; return user;
} }
return await readErrorMessage(res, "Could not start guest session.");
} catch (err) { } catch (err) {
console.error(err); console.error(err);
return "Could not reach the server. Please try again.";
} }
}; };
@@ -48,12 +63,11 @@ export const register = async (name: string, password: string, email?: string) =
if (res.status === 201) { if (res.status === 201) {
const user: User = await res.json(); const user: User = await res.json();
return user; return user;
} else if (res.status === 409) {
const { message } = await res.json();
return message as string;
} }
return await readErrorMessage(res, "Registration failed. Please try again.");
} catch (err) { } catch (err) {
console.error(err); console.error(err);
return "Could not reach the server. Please try again.";
} }
}; };
@@ -70,12 +84,11 @@ export const login = async (name: string, password: string) => {
if (res.status === 200) { if (res.status === 200) {
const user: User = await res.json(); const user: User = await res.json();
return user; return user;
} else if (res.status === 404 || res.status === 401) {
const { message } = await res.json();
return message as string;
} }
return await readErrorMessage(res, "Login failed. Please try again.");
} catch (err) { } catch (err) {
console.error(err); console.error(err);
return "Could not reach the server. Please try again.";
} }
}; };
@@ -107,11 +120,10 @@ export const updateUser = async (name?: string, email?: string, password?: strin
if (res.status === 200) { if (res.status === 200) {
const user: User = await res.json(); const user: User = await res.json();
return user; return user;
} else if (res.status === 409) {
const { message } = await res.json();
return message as string;
} }
return await readErrorMessage(res, "Could not update settings. Please try again.");
} catch (err) { } catch (err) {
console.error(err); console.error(err);
return "Could not reach the server. Please try again.";
} }
}; };

View File

@@ -12,7 +12,7 @@ services:
PGPASSWORD: ${POSTGRES_PASSWORD:-changeme} PGPASSWORD: ${POSTGRES_PASSWORD:-changeme}
PORT: 3001 PORT: 3001
SESSION_SECRET: ${SESSION_SECRET:-change-this-secret-in-production} SESSION_SECRET: ${SESSION_SECRET:-change-this-secret-in-production}
CORS_ORIGIN: ${CORS_ORIGIN:-http://localhost:3000} CORS_ORIGIN: ${CORS_ORIGIN:-https://michess.mischlabs.de}
ADMIN_EMAIL: ${ADMIN_EMAIL:-} ADMIN_EMAIL: ${ADMIN_EMAIL:-}
APP_DIR: /opt/michess APP_DIR: /opt/michess
ports: ports: