From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server-vie001.gnuweeb.org X-Spam-Level: X-Spam-Status: No, score=-1.2 required=5.0 tests=ALL_TRUSTED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,URIBL_DBL_BLOCKED_OPENDNS, URIBL_ZEN_BLOCKED_OPENDNS autolearn=ham autolearn_force=no version=3.4.6 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gnuweeb.org; s=default; t=1741462051; bh=eKijn+2bJkIQhEbygvHikXrIuLopzFjg6/4OWcYvN2U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Message-ID:Date:From: Reply-To:Subject:To:Cc:In-Reply-To:References:Resent-Date: Resent-From:Resent-To:Resent-Cc:User-Agent:Content-Type: Content-Transfer-Encoding; b=Jr7nEgSIipUkYo0wCcAZ1eRw75XC2H3tes67GkitYVb3xnS/JcmRr6jvtuskG0jiv opYMPBU3mmQyDZdPmnAYAGJI6I4sYESSC7lGG8mgc6P7zJVO+LaDfrVq0a71eDtY0k osUh2+50bUG7nSPgwEqPvScN5++V2Nz6QcfKvaC8t3v7KzOvY+AoZXMb0BhmNLoZIw yiHMnjo3J+KA7+7WEKBUAjEFgvDshYg/T/PDl2Elr0YoA9EScdAdW7Q8bpoTn1l8bh w2qqAplSeBNe1ojr9F1oKuEpi/K8hk5YAbVWy6dloVpRquV0KZib30YFidATsn3fi3 WnNl+5G9IbBdA== Received: from localhost.localdomain (unknown [101.128.125.112]) by server-vie001.gnuweeb.org (Postfix) with ESMTPSA id 4120620B4925; Sat, 8 Mar 2025 19:27:30 +0000 (UTC) From: Muhammad Rizki To: Ammar Faizi Cc: Muhammad Rizki , Alviro Iskandar Setiawan , GNU/Weeb Mailing List Subject: [PATCH v2 12/12] fix(auth): fix auth guard when credentials is invalid Date: Sun, 9 Mar 2025 02:26:54 +0700 Message-ID: <20250308192656.97-13-kiizuha@gnuweeb.org> X-Mailer: git-send-email 2.45.2.windows.1 In-Reply-To: <20250308192656.97-1-kiizuha@gnuweeb.org> References: <20250308192656.97-1-kiizuha@gnuweeb.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: This commit fixes auth guard to prevent invalid credentials to call API, it will redirect user to the login page if credentials is invalid. Signed-off-by: Muhammad Rizki --- src/lib/hooks/auth.svelte.ts | 26 +++++++++++++++++++++----- src/lib/hooks/http.svelte.ts | 4 +++- src/routes/(protected)/+layout.svelte | 9 +++++++++ src/routes/(protected)/+layout.ts | 9 ++++++++- src/routes/+page.ts | 2 ++ 5 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/lib/hooks/auth.svelte.ts b/src/lib/hooks/auth.svelte.ts index 7bd2d3b..aa4beda 100644 --- a/src/lib/hooks/auth.svelte.ts +++ b/src/lib/hooks/auth.svelte.ts @@ -5,6 +5,17 @@ let data = $state({ token_exp_at: 0 }); +const getUserFromLocalStorage = () => { + const user = localStorage.getItem("gwm_uinfo"); + if (!user) return undefined; + + try { + return JSON.parse(user) as User; + } catch { + return undefined; + } +}; + export function useAuth() { return { get token() { @@ -24,8 +35,12 @@ export function useAuth() { }, refresh() { - const user = localStorage.getItem("gwm_uinfo"); - data.user_info = JSON.parse(user!) as User; + const token = localStorage.getItem("gwm_token"); + const token_exp_at = Number(localStorage.getItem("gwm_token_exp_at")); + + data.user_info = getUserFromLocalStorage(); + data.token = token!; + data.token_exp_at = token_exp_at; }, save({ user_info, token, token_exp_at }: LoginResponse) { @@ -42,15 +57,16 @@ export function useAuth() { }, isValid() { + const user = getUserFromLocalStorage(); const token = localStorage.getItem("gwm_token"); - const user = localStorage.getItem("gwm_uinfo"); + const expLs = localStorage.getItem("gwm_token_exp_at"); - if (!token || !user) { + if (!token || !user || !expLs) { this.clear(); return false; } - const exp = Number(localStorage.getItem("gwm_token_exp_at")); + const exp = Number(expLs); const unix = Math.round(new Date().getTime() / 1000); if (unix >= exp) { diff --git a/src/lib/hooks/http.svelte.ts b/src/lib/hooks/http.svelte.ts index d3445d9..f30687d 100644 --- a/src/lib/hooks/http.svelte.ts +++ b/src/lib/hooks/http.svelte.ts @@ -1,3 +1,4 @@ +import { goto } from "$app/navigation"; import { PUBLIC_BASE_URL } from "$env/static/public"; import * as typing from "$typings"; import axios from "axios"; @@ -53,10 +54,11 @@ client.interceptors.response.use( const response = err.response as AxiosResponse>; const status = response ? response.status : null; - if (status === 403 && response?.data) { + if (status !== 200) { localStorage.removeItem("gwm_token"); localStorage.removeItem("gwm_token_exp_at"); localStorage.removeItem("gwm_uinfo"); + goto("/"); } return response; diff --git a/src/routes/(protected)/+layout.svelte b/src/routes/(protected)/+layout.svelte index e88b3fb..f5998a7 100644 --- a/src/routes/(protected)/+layout.svelte +++ b/src/routes/(protected)/+layout.svelte @@ -3,8 +3,17 @@ import AppSidebar from "$components/customs/app-sidebar.svelte"; import Header from "$components/customs/header.svelte"; import Separator from "$components/ui/separator/separator.svelte"; + import { useAuth } from "$lib/hooks/auth.svelte"; + import { goto, onNavigate } from "$app/navigation"; let { children } = $props(); + + const auth = useAuth(); + + onNavigate(() => { + if (auth.isValid()) return; + goto("/"); + }); diff --git a/src/routes/(protected)/+layout.ts b/src/routes/(protected)/+layout.ts index 06ff2db..951766f 100644 --- a/src/routes/(protected)/+layout.ts +++ b/src/routes/(protected)/+layout.ts @@ -9,13 +9,20 @@ export const load: LayoutLoad = async () => { if (!auth.isValid()) { localStorage.setItem("gwm_invalid_creds", String(1)); + auth.clear(); return redirect(307, "/"); } - const { data } = await http<{ user_info: typing.User }>({ + const { status, data } = await http<{ user_info: typing.User }>({ params: { action: "get_user_info" } }); + if (status !== 200) { + localStorage.setItem("gwm_invalid_creds", String(1)); + auth.clear(); + return redirect(307, "/"); + } + auth.save({ token: data.res?.renew_token?.token, token_exp_at: data.res?.renew_token?.token_exp_at, diff --git a/src/routes/+page.ts b/src/routes/+page.ts index 8cbe162..604e967 100644 --- a/src/routes/+page.ts +++ b/src/routes/+page.ts @@ -11,6 +11,8 @@ export const load: PageLoad = async () => { if (auth.isValid()) return redirect(307, "/home"); + auth.refresh(); + const form = await superValidate(zod(loginSchema)); return { form, isInvalidCreds }; }; -- Muhammad Rizki