feat(sso): accept base-issued iframe login
CI / build (push) Has been skipped
CI / deploy (push) Successful in 1m44s

Handle Base SSO tokens on initial requests so Stackq can bootstrap PocketBase auth and redirect into the app without a separate login.
This commit is contained in:
eewing
2026-02-19 09:36:08 -06:00
parent e3ec0219b7
commit c6b30100bd
3 changed files with 39 additions and 0 deletions
Vendored
BIN
View File
Binary file not shown.
+15
View File
@@ -0,0 +1,15 @@
.DS_Store
Thumbs.db
node_modules
/.svelte-kit
/build
/.output
.env
.env.*
!.env.example
!.env.test
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
+24
View File
@@ -3,6 +3,7 @@ import PocketBase from "pocketbase";
import type { Handle } from "@sveltejs/kit";
const POCKETBASE_URL = "https://pocketbase.ccllc.pro";
const BASE_SSO_URL = process.env.BASE_SSO_URL ?? "https://base.ccllc.pro";
const LOGIN_PATH = "/login";
const LOGOUT_PATH = "/logout";
@@ -15,6 +16,29 @@ function isPublicRoute(pathname: string): boolean {
}
export const handle: Handle = async ({ event, resolve }) => {
// SSO: if opened from Base with ?sso=token, exchange for session and redirect
const ssoParam = event.url.searchParams.get("sso");
if (ssoParam) {
try {
const res = await fetch(
`${BASE_SSO_URL}/api/sso/exchange?token=${encodeURIComponent(ssoParam)}`
);
if (res.ok) {
const auth = await res.json();
const cookieVal = encodeURIComponent(
JSON.stringify({ token: auth.token, model: auth.model })
);
const setCookie = `pb_auth=${cookieVal}; Path=/; SameSite=Lax; Max-Age=604800`;
return new Response(null, {
status: 302,
headers: { Location: event.url.pathname, "Set-Cookie": setCookie },
});
}
} catch {
// fall through to normal auth
}
}
event.locals.pb = new PocketBase(POCKETBASE_URL);
event.locals.pb.authStore.loadFromCookie(event.request.headers.get("cookie") || "");