diff --git a/functions/_middleware.ts b/functions/_middleware.ts
index 75042fa..b8ed629 100644
--- a/functions/_middleware.ts
+++ b/functions/_middleware.ts
@@ -98,6 +98,74 @@ async function refreshAuth(context: RequestContext) {
 
   delete context.data.sid;
 
+  const jwtPayload = context.request.headers
+    .get("authorization")
+    ?.replace("Bearer ", "")
+    .split(".")
+    .at(1);
+
+  if (jwtPayload) {
+    let jwtData: { [k: string]: any };
+
+    try {
+      jwtData = JSON.parse(
+        atob(jwtPayload.replaceAll("-", "+").replaceAll("_", "/")),
+      );
+    } catch {
+      return jsonError("JWT is malformed", 400);
+    }
+
+    jwtData.email = userData.email;
+    jwtData.exp = Math.floor(Date.now() / 1000) + userData.expires_in;
+    jwtData.iat = Math.floor(Date.now() / 1000);
+    jwtData.name = userData.username;
+    jwtData.permissions = userData.permissions;
+    jwtData.picture =
+      userData.avatar ?? "https://carcrushers.cc/files/logo192.png";
+
+    const key = await crypto.subtle.importKey(
+      "raw",
+      // @ts-expect-error
+      Uint8Array.from(
+        atob(
+          context.env.JWT_SIGNING_KEY.replaceAll("-", "+").replaceAll("_", "/"),
+        ),
+        (m) => m.codePointAt(0),
+      ),
+      { hash: "SHA-256", name: "HMAC" },
+      false,
+      ["sign"],
+    );
+
+    const jwtBase = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.${btoa(
+      JSON.stringify(jwtData),
+    )
+      .replaceAll("+", "-")
+      .replaceAll("/", "_")
+      .replaceAll("=", "")}`;
+
+    const signature = btoa(
+      String.fromCodePoint(
+        ...new Uint8Array(
+          await crypto.subtle.sign(
+            "HMAC",
+            key,
+            new TextEncoder().encode(jwtBase),
+          ),
+        ),
+      ),
+    )
+      .replaceAll("+", "-")
+      .replace("/", "_")
+      .replaceAll("=", "");
+
+    const response = await context.next();
+
+    response.headers.set("refreshed-token", `${jwtBase}.${signature}`);
+
+    return response;
+  }
+
   return await context.next();
 }