confirmed SSR support with Remix

This commit is contained in:
dswbx
2024-11-25 19:59:46 +01:00
parent 1c94777317
commit eea76ebc28
15 changed files with 144 additions and 44 deletions

View File

@@ -1,6 +1,7 @@
import { AuthApi } from "auth/api/AuthApi";
import { DataApi } from "data/api/DataApi";
import { decode } from "hono/jwt";
import { omit } from "lodash-es";
import { MediaApi } from "media/api/MediaApi";
import { SystemApi } from "modules/SystemApi";
@@ -14,15 +15,18 @@ declare global {
export type ApiOptions = {
host: string;
user?: object;
token?: string;
storage?: "localStorage" | "manual";
headers?: Headers;
key?: string;
localStorage?: boolean;
};
export class Api {
private token?: string;
private user?: object;
private verified = false;
private token_transport: "header" | "cookie" | "none" = "header";
public system!: SystemApi;
public data!: DataApi;
@@ -30,7 +34,12 @@ export class Api {
public media!: MediaApi;
constructor(private readonly options: ApiOptions) {
if (options.token) {
if (options.user) {
this.user = options.user;
this.token_transport = "none";
this.verified = true;
} else if (options.token) {
this.token_transport = "header";
this.updateToken(options.token);
} else {
this.extractToken();
@@ -39,33 +48,44 @@ export class Api {
this.buildApis();
}
get tokenStorage() {
return this.options.storage ?? "manual";
}
get tokenKey() {
return this.options.key ?? "auth";
}
private extractToken() {
if (this.tokenStorage === "localStorage") {
if (this.options.headers) {
// try cookies
const cookieToken = getCookieValue(this.options.headers.get("cookie"), "auth");
if (cookieToken) {
this.updateToken(cookieToken);
this.token_transport = "cookie";
this.verified = true;
return;
}
// try authorization header
const headerToken = this.options.headers.get("authorization")?.replace("Bearer ", "");
if (headerToken) {
this.token_transport = "header";
this.updateToken(headerToken);
return;
}
} else if (this.options.localStorage) {
const token = localStorage.getItem(this.tokenKey);
if (token) {
this.token = token;
this.user = decode(token).payload as any;
}
} else {
if (typeof window !== "undefined" && "__BKND__" in window) {
this.user = window.__BKND__.user;
this.verified = true;
this.token_transport = "header";
this.updateToken(token);
}
}
//console.warn("Couldn't extract token");
}
updateToken(token?: string, rebuild?: boolean) {
this.token = token;
this.user = token ? (decode(token).payload as any) : undefined;
this.user = token ? omit(decode(token).payload as any, ["iat", "iss", "exp"]) : undefined;
if (this.tokenStorage === "localStorage") {
if (this.options.localStorage) {
const key = this.tokenKey;
if (token) {
@@ -94,7 +114,9 @@ export class Api {
private buildApis() {
const baseParams = {
host: this.options.host,
token: this.token
token: this.token,
headers: this.options.headers,
token_transport: this.token_transport
};
this.system = new SystemApi(baseParams);
@@ -106,3 +128,15 @@ export class Api {
this.media = new MediaApi(baseParams);
}
}
function getCookieValue(cookies: string | null, name: string) {
if (!cookies) return null;
for (const cookie of cookies.split("; ")) {
const [key, value] = cookie.split("=");
if (key === name && value) {
return decodeURIComponent(value);
}
}
return null;
}