@fluid-app/rep-sdk 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -45,6 +45,45 @@ var HTTP_METHODS = {
45
45
  DELETE: "DELETE"
46
46
  };
47
47
 
48
+ // src/auth/auth-redirect.ts
49
+ var DEFAULT_AUTH_URL = "https://auth.fluid.app";
50
+ var AUTH_REDIRECT_TOKEN_KEY = "jwt";
51
+ var REDIRECT_TIMESTAMP_KEY = "__fluid_auth_redirect_ts";
52
+ var REDIRECT_COOLDOWN_S = 10;
53
+ function isRedirectLoop() {
54
+ try {
55
+ const ts = sessionStorage.getItem(REDIRECT_TIMESTAMP_KEY);
56
+ if (!ts) return false;
57
+ const elapsed = (Date.now() - Number(ts)) / 1e3;
58
+ return elapsed < REDIRECT_COOLDOWN_S;
59
+ } catch {
60
+ return false;
61
+ }
62
+ }
63
+ function markRedirect() {
64
+ try {
65
+ sessionStorage.setItem(REDIRECT_TIMESTAMP_KEY, String(Date.now()));
66
+ } catch {
67
+ }
68
+ }
69
+ function createDefaultAuthRedirect(authUrl) {
70
+ return () => {
71
+ if (isRedirectLoop()) {
72
+ console.warn(
73
+ "[FluidAuth] Auth redirect suppressed \u2014 possible redirect loop. Check that your auth server returns a token accepted by the API."
74
+ );
75
+ return;
76
+ }
77
+ markRedirect();
78
+ const base = authUrl ?? DEFAULT_AUTH_URL;
79
+ const currentUrl = encodeURIComponent(window.location.href);
80
+ window.location.href = `${base}/?redirect_url=${currentUrl}`;
81
+ };
82
+ }
83
+ function resolveAuthFailureHandler(onAuthFailure, authUrl) {
84
+ return onAuthFailure ?? createDefaultAuthRedirect(authUrl);
85
+ }
86
+
48
87
  // src/client/fluid-client.ts
49
88
  var ApiError = class _ApiError extends Error {
50
89
  status;
@@ -88,6 +127,7 @@ function extractErrorMessage(data, fallback) {
88
127
  }
89
128
  function createFluidClient(config) {
90
129
  const { baseUrl, getAuthToken, onAuthError, defaultHeaders = {} } = config;
130
+ const effectiveOnAuthError = onAuthError ?? createDefaultAuthRedirect();
91
131
  async function buildHeaders(customHeaders) {
92
132
  const headers = {
93
133
  "Content-Type": "application/json",
@@ -173,8 +213,8 @@ function createFluidClient(config) {
173
213
  null
174
214
  );
175
215
  }
176
- if (response.status === 401 && onAuthError) {
177
- onAuthError();
216
+ if (response.status === 401) {
217
+ effectiveOnAuthError();
178
218
  }
179
219
  if (!response.ok) {
180
220
  try {
@@ -776,6 +816,7 @@ function FluidAuthProvider({
776
816
  const [error, setError] = react.useState(null);
777
817
  react.useEffect(() => {
778
818
  const initializeAuth = async () => {
819
+ const handleAuthFailure = resolveAuthFailureHandler(config?.onAuthFailure, config?.authUrl);
779
820
  try {
780
821
  if (isDevBypassActive(config?.devBypass)) {
781
822
  const envToken = undefined.VITE_DEV_TOKEN;
@@ -803,7 +844,11 @@ function FluidAuthProvider({
803
844
  }
804
845
  const tokenKey = config?.tokenKey ?? "fluidUserToken";
805
846
  let candidateToken = extractTokenFromUrl(tokenKey);
847
+ if (!candidateToken && tokenKey !== AUTH_REDIRECT_TOKEN_KEY) {
848
+ candidateToken = extractTokenFromUrl(AUTH_REDIRECT_TOKEN_KEY);
849
+ }
806
850
  cleanTokenFromUrl(tokenKey);
851
+ cleanTokenFromUrl(AUTH_REDIRECT_TOKEN_KEY);
807
852
  if (!candidateToken) {
808
853
  candidateToken = getStoredToken(config);
809
854
  }
@@ -816,7 +861,7 @@ function FluidAuthProvider({
816
861
  setToken(null);
817
862
  setUser(null);
818
863
  setError(new Error("JWT signature verification failed"));
819
- config?.onAuthFailure?.();
864
+ handleAuthFailure();
820
865
  return;
821
866
  }
822
867
  if (isTokenExpired(candidateToken, config?.gracePeriodMs)) {
@@ -824,7 +869,7 @@ function FluidAuthProvider({
824
869
  setToken(null);
825
870
  setUser(null);
826
871
  setError(new Error("Token has expired"));
827
- config?.onAuthFailure?.();
872
+ handleAuthFailure();
828
873
  return;
829
874
  }
830
875
  } else {
@@ -839,7 +884,7 @@ function FluidAuthProvider({
839
884
  setToken(null);
840
885
  setUser(null);
841
886
  setError(new Error(validation.error ?? "Invalid token"));
842
- config?.onAuthFailure?.();
887
+ handleAuthFailure();
843
888
  return;
844
889
  }
845
890
  }
@@ -851,14 +896,14 @@ function FluidAuthProvider({
851
896
  setToken(null);
852
897
  setUser(null);
853
898
  setError(new Error("No authentication token found"));
854
- config?.onAuthFailure?.();
899
+ handleAuthFailure();
855
900
  }
856
901
  } catch (err) {
857
902
  const error2 = err instanceof Error ? err : new Error("Authentication error");
858
903
  setError(error2);
859
904
  setToken(null);
860
905
  setUser(null);
861
- config?.onAuthFailure?.();
906
+ handleAuthFailure();
862
907
  } finally {
863
908
  setIsLoading(false);
864
909
  }
@@ -2353,6 +2398,7 @@ exports.BUILT_IN_THEMES = export_BUILT_IN_THEMES;
2353
2398
  exports.CORE_COLOR_KEYS = export_CORE_COLOR_KEYS;
2354
2399
  exports.CORE_PAGE_IDS = CORE_PAGE_IDS;
2355
2400
  exports.CURRENT_REP_QUERY_KEY = CURRENT_REP_QUERY_KEY;
2401
+ exports.DEFAULT_AUTH_URL = DEFAULT_AUTH_URL;
2356
2402
  exports.DEFAULT_CORE_COLORS = export_DEFAULT_CORE_COLORS;
2357
2403
  exports.FluidAuthProvider = FluidAuthProvider;
2358
2404
  exports.FluidProvider = FluidProvider;
@@ -2370,6 +2416,7 @@ exports.catppuccinMocha = export_catppuccinMocha;
2370
2416
  exports.clampChroma = export_clampChroma;
2371
2417
  exports.cleanTokenFromUrl = cleanTokenFromUrl;
2372
2418
  exports.clearTokens = clearTokens;
2419
+ exports.createDefaultAuthRedirect = createDefaultAuthRedirect;
2373
2420
  exports.createFluidClient = createFluidClient;
2374
2421
  exports.decodeToken = decodeToken;
2375
2422
  exports.defaultTheme = export_defaultTheme;