From: Muhammad Rizki <[email protected]>
To: Ammar Faizi <[email protected]>
Cc: Muhammad Rizki <[email protected]>,
Alviro Iskandar Setiawan <[email protected]>,
GNU/Weeb Mailing List <[email protected]>
Subject: [PATCH v2 12/12] fix(auth): fix auth guard when credentials is invalid
Date: Sun, 9 Mar 2025 02:26:54 +0700 [thread overview]
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>
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 <[email protected]>
---
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<LoginResponse>({
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<typing.ResponseAPI<typing.RenewTokenResponse>>;
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("/");
+ });
</script>
<Sidebar.Provider class="light">
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
next prev parent reply other threads:[~2025-03-08 19:27 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-08 19:26 [PATCH v2 00/12] Fix Auth Guard, Move SEO Muhammad Rizki
2025-03-08 19:26 ` [PATCH v2 01/12] fix(svelte): use relative false Muhammad Rizki
2025-03-08 19:26 ` [PATCH v2 02/12] fix(avatar): change avatarImg state to use from auth.user.photo state Muhammad Rizki
2025-03-08 19:26 ` [PATCH v2 03/12] chore(profile): add toUpperCase() on getShortName() Muhammad Rizki
2025-03-08 19:26 ` [PATCH v2 04/12] fix(profile): make social fields default to empty string Muhammad Rizki
2025-03-08 19:26 ` [PATCH v2 05/12] chore(toaster): change toast message position and use richColors Muhammad Rizki
2025-03-08 19:26 ` [PATCH v2 06/12] chore(profile): reset password value on success Muhammad Rizki
2025-03-08 19:26 ` [PATCH v2 07/12] fix(profile-avatar): add delete avatar method Muhammad Rizki
2025-03-08 19:26 ` [PATCH v2 08/12] chore(profile): add space for password confirmation form Muhammad Rizki
2025-03-08 19:26 ` [PATCH v2 09/12] feat(ui): add dropdown-menu and update bits-ui version Muhammad Rizki
2025-03-08 19:26 ` [PATCH v2 10/12] chore(sidebar-menu): change sidebar menu look Muhammad Rizki
2025-03-08 19:26 ` [PATCH v2 11/12] chore(seo): move seo from layout to /home page Muhammad Rizki
2025-03-08 19:26 ` Muhammad Rizki [this message]
2025-03-08 19:38 ` [PATCH v2 00/12] Fix Auth Guard, Move SEO Ammar Faizi
2025-03-08 19:51 ` Alviro Iskandar Setiawan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox