From 20abd199c381eeab138563af897b54ecadc57bae Mon Sep 17 00:00:00 2001 From: Guillermo Serrahima Date: Thu, 12 Mar 2026 11:09:46 +0100 Subject: Implemented OAuth login --- frontend/login.html | 25 +++++++++++++++++++++++++ frontend/src/login.ts | 16 ++++++++++++++++ frontend/src/main.ts | 12 +++++++++++- frontend/src/style.css | 17 +++++++++++++++++ frontend/vite.config.ts | 13 +++++++++++++ 5 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 frontend/login.html create mode 100644 frontend/src/login.ts create mode 100644 frontend/vite.config.ts (limited to 'frontend') diff --git a/frontend/login.html b/frontend/login.html new file mode 100644 index 0000000..0f5ba0b --- /dev/null +++ b/frontend/login.html @@ -0,0 +1,25 @@ + + + + + + llostre - login + + + +
+

log in to llostre

+
+ + +
+
+
+ + + diff --git a/frontend/src/login.ts b/frontend/src/login.ts new file mode 100644 index 0000000..d8054c0 --- /dev/null +++ b/frontend/src/login.ts @@ -0,0 +1,16 @@ +const loginForm = document.getElementById('login-form') as HTMLFormElement; +const handleInput = document.getElementById('handle-input') as HTMLInputElement; +const loginError = document.getElementById('login-error') as HTMLDivElement; + +loginForm.addEventListener('submit', async (e) => { + e.preventDefault(); + const handle = handleInput.value.trim(); + + if (!handle) { + loginError.textContent = 'please enter a handle'; + return; + } + + loginError.textContent = ''; + window.location.href = `/api/login?handle=${encodeURIComponent(handle)}`; +}); diff --git a/frontend/src/main.ts b/frontend/src/main.ts index 20c3bea..4868365 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -68,6 +68,14 @@ function renderAuthor(note: any): string { } async function main() { + const sessionCheck = await fetch('/api/session', { + credentials: 'include' + }); + if (!sessionCheck.ok) { + window.location.href = '/login.html'; + throw new Error('not authenticated'); + } + const app = document.querySelector('#app'); if (!app) { console.error('App container not found'); @@ -77,7 +85,9 @@ async function main() { app.innerHTML = '
'; try { - const response = await fetch('http://localhost:8080/api/posts'); + const response = await fetch('/api/posts', { + credentials: 'include' + }); if (!response.ok) throw new Error(`HTTP ${response.status}`); const notes = await response.json(); diff --git a/frontend/src/style.css b/frontend/src/style.css index 549c596..700135c 100644 --- a/frontend/src/style.css +++ b/frontend/src/style.css @@ -13,6 +13,23 @@ -moz-osx-font-smoothing: grayscale; } +#login-container { + max-width: 400px; + margin: 2rem auto; + padding: 2rem; +} + +#handle-input { + width: 100%; + padding: 0.5rem; + margin-bottom: 1rem; +} + +#login-error { + color: red; + margin-top: 1rem; +} + a { font-weight: 500; color: #646cff; diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts new file mode 100644 index 0000000..4420756 --- /dev/null +++ b/frontend/vite.config.ts @@ -0,0 +1,13 @@ +import { defineConfig } from 'vite' +import { resolve } from 'path' + +export default defineConfig({ + build: { + rollupOptions: { + input: { + main: resolve(__dirname, 'index.html'), + login: resolve(__dirname, 'login.html'), + }, + }, + }, +}) -- cgit v1.2.3