@frank-auth/react
Version:
Flexible and customizable React UI components for Frank Authentication
232 lines (231 loc) • 5.75 kB
JavaScript
import { useState as m, useCallback as p, useEffect as w, useMemo as o } from "react";
import { useAuth as z } from "./use-auth.js";
import { useConfig as B } from "../provider/config-provider.js";
function g() {
const { session: e, sdk: n, createSession: r, reload: i, userType: u } = z(), { apiUrl: f, publishableKey: d } = B(), [t, A] = m([]), [k, a] = m(!1), [D, S] = m(null), c = p((s) => {
const h = {
code: s.code || "UNKNOWN_ERROR",
message: s.message || "An unknown error occurred",
details: s.details,
field: s.field
};
throw S(h), h;
}, []), v = p(async () => {
try {
a(!0), S(null);
const s = await n.session.listSessions({ fields: [] });
A(s.data);
} catch (s) {
console.error("Failed to load sessions:", s), S({
code: "SESSIONS_LOAD_FAILED",
message: "Failed to load sessions"
});
} finally {
a(!1);
}
}, [n.session]);
w(() => {
v();
}, [v]);
const I = p(async (s) => r(s), [r]), T = p(async (s) => {
try {
a(!0), S(null), n.session.activeSession = s, await i(), await v();
} catch (h) {
c(h);
} finally {
a(!1);
}
}, [n.session, i, v, c]), U = p(async () => {
try {
a(!0), S(null);
const s = await n.session.refreshSession();
return await i(), s;
} catch (s) {
return c(s), null;
} finally {
a(!1);
}
}, [n.session, i, c]), M = p(async (s) => {
try {
a(!0), S(null), await n.session.revokeSession(s), s === e?.id ? await i() : await v();
} catch (h) {
c(h);
} finally {
a(!1);
}
}, [n.session, e?.id, i, v, c]), C = p(async (s = !1) => {
try {
a(!0), S(null), await n.session.revokeAllSessions({
exceptCurrent: s
}), s ? await v() : await i();
} catch (h) {
c(h);
} finally {
a(!1);
}
}, [n.session, i, v, c]), L = p(async () => {
try {
a(!0), S(null), await i();
} catch (s) {
c(s);
} finally {
a(!1);
}
}, [n.session, i, c]), x = o(() => e?.id || null, [e]), b = o(() => e?.accessToken || null, [e]), l = o(
() => e?.expiresAt ? new Date(e.expiresAt) : null,
[e]
), N = o(
() => e?.lastActiveAt ? new Date(e.lastActiveAt) : null,
[e]
), O = o(() => !!e && !e.expired, [e]), E = o(() => l ? l.getTime() <= Date.now() : !1, [l]), F = o(() => {
if (!l) return !1;
const s = Date.now() + 5 * 60 * 1e3;
return l.getTime() <= s && !E;
}, [l, E]), R = o(() => {
if (!l) return null;
const s = l.getTime() - Date.now();
return Math.max(0, Math.floor(s / 6e4));
}, [l]), y = o(() => e?.deviceInfo ? {
userAgent: e.deviceInfo.userAgent || "",
browser: e.deviceInfo.browser || "Unknown",
os: e.deviceInfo.os || "Unknown",
device: e.deviceInfo.device || "Unknown",
ipAddress: e.deviceInfo.ipAddress || "",
location: e.deviceInfo.location
} : null, [e]), _ = o(() => !e || !y ? !1 : typeof navigator < "u" && y.userAgent === navigator.userAgent, [e, y]), K = o(
() => e?.trustedDevice || !1,
[e]
), W = o(() => t.length > 1, [t]), j = o(() => t.length, [t]), q = o(
() => t.filter((s) => s.id !== x),
[t, x]
);
return {
// Session state
session: e,
sessions: t,
isLoaded: !!e,
isLoading: k,
error: D,
// Session management
createSession: I,
setActiveSession: T,
refreshSession: U,
revokeSession: M,
revokeAllSessions: C,
endSession: L,
// Session information
sessionId: x,
sessionToken: b,
expiresAt: l,
lastActiveAt: N,
// Session status
isActive: O,
isExpired: E,
isExpiring: F,
timeUntilExpiry: R,
// Device information
deviceInfo: y,
// Security features
isCurrentDevice: _,
isTrustedDevice: K,
// Multi-session support
hasMultipleSessions: W,
sessionCount: j,
otherSessions: q
};
}
function P() {
const {
isActive: e,
isExpired: n,
isExpiring: r,
timeUntilExpiry: i,
expiresAt: u,
refreshSession: f
} = g();
return {
isActive: e,
isExpired: n,
isExpiring: r,
timeUntilExpiry: i,
expiresAt: u,
refreshSession: f,
status: n ? "expired" : r ? "expiring" : e ? "active" : "inactive"
};
}
function Q() {
const {
sessions: e,
sessionCount: n,
otherSessions: r,
hasMultipleSessions: i,
revokeSession: u,
revokeAllSessions: f,
setActiveSession: d,
isLoading: t,
error: A
} = g();
return {
sessions: e,
sessionCount: n,
otherSessions: r,
hasMultipleSessions: i,
revokeSession: u,
revokeAllSessions: f,
setActiveSession: d,
isLoading: t,
error: A,
revokeAllOthers: () => f(!0)
};
}
function V() {
const {
deviceInfo: e,
isCurrentDevice: n,
isTrustedDevice: r,
sessionId: i,
lastActiveAt: u
} = g();
return {
deviceInfo: e,
isCurrentDevice: n,
isTrustedDevice: r,
sessionId: i,
lastActiveAt: u,
isSecure: r && n
};
}
function X(e = {}) {
const {
autoRefresh: n = !1,
refreshThreshold: r = 5,
onExpiry: i,
onExpiring: u
} = e, {
isExpired: f,
isExpiring: d,
timeUntilExpiry: t,
refreshSession: A
} = g();
return w(() => {
n && d && t && t <= r && A().catch(console.error);
}, [n, d, t, r, A]), w(() => {
f && i?.();
}, [f, i]), w(() => {
d && u?.();
}, [d, u]), {
isExpired: f,
isExpiring: d,
timeUntilExpiry: t,
refreshSession: A,
autoRefresh: n
};
}
export {
Q as useMultiSession,
g as useSession,
X as useSessionExpiry,
V as useSessionSecurity,
P as useSessionStatus
};
//# sourceMappingURL=use-session.js.map