const s = (e) => {
  try {
    const t = e.split(".");
    if (t.length !== 3) return null;
    const n = JSON.parse(atob(t[0])), r = JSON.parse(atob(t[1])), i = t[2];
    return { header: n, payload: r, signature: i };
  } catch {
    return null;
  }
}, f = (e) => {
  const t = s(e);
  if (!t) return !0;
  const n = Math.floor(Date.now() / 1e3);
  return t.payload.exp < n;
}, p = (e) => {
  const t = s(e);
  return t ? new Date(t.payload.exp * 1e3) : null;
}, h = (e) => {
  const t = s(e);
  if (!t) return 0;
  const n = Math.floor(Date.now() / 1e3);
  return Math.max(0, t.payload.exp - n);
}, g = (e) => {
  const t = /* @__PURE__ */ new Date(), n = new Date(e.expiresAt);
  return e.isActive && n > t;
}, l = (e) => {
  const t = /* @__PURE__ */ new Date(), n = new Date(e.expiresAt);
  return Math.max(0, n.getTime() - t.getTime());
}, w = (e) => {
  const t = l(e);
  if (t === 0) return "Expired";
  const n = Math.floor(t / (1e3 * 60 * 60)), r = Math.floor(t % (1e3 * 60 * 60) / (1e3 * 60));
  return n > 0 ? `${n}h ${r}m` : `${r}m`;
}, d = (e) => e.fullName ? e.fullName : e.firstName && e.lastName ? `${e.firstName} ${e.lastName}` : e.firstName ? e.firstName : e.username ? e.username : e.emailAddress ? e.emailAddress : "Unknown User", y = (e) => d(e).split(" ").map((n) => n.charAt(0).toUpperCase()).slice(0, 2).join(""), A = (e) => e.emailVerified && (e.phoneNumber ? e.phoneVerified : !0), P = (e) => {
  const t = [];
  return e.emailVerified || t.push("email"), e.phoneNumber && !e.phoneVerified && t.push("phone"), {
    isVerified: t.length === 0,
    emailVerified: e.emailVerified,
    phoneVerified: e.phoneVerified,
    missingVerifications: t
  };
}, b = (e, t) => e.organizations ? e.organizations.some((n) => n.id === t) : !1, S = (e, t) => e.organizations && e.organizations.find((r) => r.id === t)?.userRole || null, v = (e, t) => e.organizations ? e.organizations.find((r) => r.id === t)?.userPermissions || [] : [], o = (e, t, n) => e.permissions ? e.permissions.some((r) => r.permissionName !== t ? !1 : n ? r.contextType === "organization" && r.contextId === n : r.contextType === "system") : !1, a = (e, t, n) => e.roles ? e.roles.some((r) => r.roleName !== t ? !1 : n ? r.contextType === "organization" && r.contextId === n : r.contextType === "system") : !1, c = (e, t) => t.ownerId === e.id, x = (e, t) => c(e, t) || a(e, "admin", t.id) || o(e, "organization:manage", t.id), k = (e, t) => c(e, t) || a(e, "admin", t.id) || o(e, "members:invite", t.id), U = (e) => {
  const t = {
    passkey: 1,
    oauth: 2,
    email: 3,
    phone: 4,
    username: 5,
    mfa: 6,
    magic_link: 7
  };
  return e.sort((n, r) => t[n] - t[r]);
}, C = (e, t) => t.includes(e), M = (e) => ({
  email: "Email",
  phone: "Phone",
  username: "Username",
  oauth: "Social Login",
  passkey: "Passkey",
  magic_link: "Magic Link",
  mfa: "Multi-Factor Authentication"
})[e] || e, N = (e) => {
  const t = [];
  let n = 0;
  return e.length >= 8 ? n += 1 : t.push("Password must be at least 8 characters long"), /[a-z]/.test(e) ? n += 1 : t.push("Include lowercase letters"), /[A-Z]/.test(e) ? n += 1 : t.push("Include uppercase letters"), /\d/.test(e) ? n += 1 : t.push("Include numbers"), /[^A-Za-z0-9]/.test(e) ? n += 1 : t.push("Include special characters"), e.length >= 12 && (n += 1), /(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/.test(e) && (n += 1), {
    score: Math.min(n, 5),
    feedback: t,
    isValid: n >= 4
  };
}, T = (e) => ["Very Weak", "Weak", "Fair", "Good", "Strong"][Math.min(e, 4)] || "Very Weak", V = (e) => [
  "password",
  "123456",
  "123456789",
  "qwerty",
  "abc123",
  "password123",
  "admin",
  "letmein",
  "welcome",
  "monkey",
  "1234567890",
  "dragon",
  "master",
  "login",
  "welcome123"
].includes(e.toLowerCase()), O = (e) => e.replace(/(.{4})/g, "$1-").replace(/-$/, ""), I = (e) => /^\d{6}$/.test(e), z = (e) => /^\d{4,8}$/.test(e), D = (e) => /^[A-Z0-9]{8}$/.test(e.replace(/-/g, "")), E = () => {
  const e = navigator.userAgent;
  let t = "unknown";
  /Mobile|Android|iPhone|iPad/.test(e) ? t = /iPad/.test(e) ? "tablet" : "mobile" : /Windows|Mac|Linux/.test(e) && (t = "desktop");
  let n;
  e.includes("Chrome") ? n = "Chrome" : e.includes("Firefox") ? n = "Firefox" : e.includes("Safari") ? n = "Safari" : e.includes("Edge") && (n = "Edge");
  let r;
  return e.includes("Windows") ? r = "Windows" : e.includes("Mac") ? r = "macOS" : e.includes("Linux") ? r = "Linux" : e.includes("Android") ? r = "Android" : e.includes("iOS") && (r = "iOS"), {
    deviceType: t,
    browser: n,
    operatingSystem: r,
    userAgent: e
  };
}, $ = () => !!(window.PublicKeyCredential && window.PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable && window.PublicKeyCredential.isConditionalMediationAvailable), L = async () => {
  if (!window.PublicKeyCredential)
    return {
      supported: !1,
      conditionalUI: !1,
      platformAuthenticator: !1
    };
  const [e, t] = await Promise.all([
    window.PublicKeyCredential.isConditionalMediationAvailable?.() || Promise.resolve(!1),
    window.PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable?.() || Promise.resolve(!1)
  ]);
  return {
    supported: !0,
    conditionalUI: e,
    platformAuthenticator: t
  };
}, R = (e, t) => {
  const n = new URL(e);
  for (const [r, i] of Object.entries(t))
    i !== void 0 && n.searchParams.set(r, i);
  return n.toString();
}, W = (e) => {
  const t = new URL(e);
  return {
    code: t.searchParams.get("code") || void 0,
    state: t.searchParams.get("state") || void 0,
    error: t.searchParams.get("error") || void 0,
    error_description: t.searchParams.get("error_description") || void 0
  };
}, K = () => {
  const e = new Uint8Array(32);
  return crypto.getRandomValues(e), Array.from(e, (t) => t.toString(16).padStart(2, "0")).join("");
}, u = () => window.isSecureContext, j = () => {
  if (!u())
    throw new Error("This operation requires a secure context (HTTPS)");
}, q = (e, t) => {
  try {
    const n = new URL(e);
    return t.some((r) => n.hostname === r || n.hostname.endsWith(`.${r}`)) ? e : null;
  } catch {
    return null;
  }
}, m = (e, t = {}) => new CustomEvent(`frank-auth:${e}`, {
  detail: {
    timestamp: (/* @__PURE__ */ new Date()).toISOString(),
    ...t
  }
}), F = (e, t = {}) => {
  const n = m(e, t);
  window.dispatchEvent(n);
};
export {
  R as buildRedirectUrl,
  b as canUserAccessOrganization,
  k as canUserInviteMembers,
  x as canUserManageOrganization,
  m as createAuthEvent,
  s as decodeJWT,
  F as dispatchAuthEvent,
  O as formatBackupCode,
  w as formatSessionDuration,
  K as generateRandomState,
  M as getAuthMethodDisplayName,
  E as getDeviceInfo,
  L as getPasskeySupport,
  T as getPasswordStrengthLabel,
  U as getRequiredAuthMethods,
  l as getSessionTimeRemaining,
  p as getTokenExpiration,
  h as getTokenTimeToExpiry,
  d as getUserDisplayName,
  y as getUserInitials,
  v as getUserPermissionsInOrganization,
  S as getUserRoleInOrganization,
  P as getUserVerificationStatus,
  o as hasPermission,
  a as hasRole,
  C as isAuthMethodAvailable,
  V as isCommonPassword,
  $ as isPasskeySupported,
  u as isSecureContext,
  g as isSessionActive,
  f as isTokenExpired,
  c as isUserOrganizationOwner,
  A as isUserVerified,
  W as parseAuthCallback,
  j as requireSecureContext,
  q as sanitizeRedirectUrl,
  D as validateBackupCode,
  N as validatePasswordStrength,
  z as validateSMSCode,
  I as validateTOTPCode
};
//# sourceMappingURL=auth.js.map
