@rhinestone/1auth 0.5.0 → 0.6.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.mjs CHANGED
@@ -26,7 +26,6 @@ var POPUP_WIDTH = 450;
26
26
  var POPUP_HEIGHT = 600;
27
27
  var DEFAULT_EMBED_WIDTH = "400px";
28
28
  var DEFAULT_EMBED_HEIGHT = "500px";
29
- var MODAL_WIDTH = 340;
30
29
  var DEFAULT_PROVIDER_URL = "https://passkey.1auth.box";
31
30
  var OneAuthClient = class {
32
31
  constructor(config) {
@@ -555,7 +554,7 @@ var OneAuthClient = class {
555
554
  if (event.origin !== dialogOrigin) return;
556
555
  if (event.data?.type === "PASSKEY_READY") {
557
556
  iframe.contentWindow?.postMessage(
558
- { type: "PASSKEY_INIT", ...initPayload },
557
+ { type: "PASSKEY_INIT", ...initPayload, fullViewport: true },
559
558
  dialogOrigin
560
559
  );
561
560
  }
@@ -894,7 +893,7 @@ var OneAuthClient = class {
894
893
  if (event.origin !== dialogOrigin) return;
895
894
  if (event.data?.type === "PASSKEY_READY") {
896
895
  iframe.contentWindow?.postMessage(
897
- { type: "PASSKEY_INIT", ...batchInitPayload },
896
+ { type: "PASSKEY_INIT", ...batchInitPayload, fullViewport: true },
898
897
  dialogOrigin
899
898
  );
900
899
  }
@@ -1227,7 +1226,7 @@ var OneAuthClient = class {
1227
1226
  ready: true,
1228
1227
  sendInit: (initMessage) => {
1229
1228
  iframe.contentWindow?.postMessage(
1230
- { type: "PASSKEY_INIT", ...initMessage },
1229
+ { type: "PASSKEY_INIT", ...initMessage, fullViewport: true },
1231
1230
  dialogOrigin
1232
1231
  );
1233
1232
  }
@@ -1961,7 +1960,8 @@ var OneAuthClient = class {
1961
1960
  teardown();
1962
1961
  iframe.contentWindow?.postMessage({
1963
1962
  type: "PASSKEY_INIT",
1964
- ...initMessage
1963
+ ...initMessage,
1964
+ fullViewport: true
1965
1965
  }, dialogOrigin);
1966
1966
  resolve(true);
1967
1967
  } else if (event.data?.type === "PASSKEY_CLOSE") {
@@ -1984,121 +1984,175 @@ var OneAuthClient = class {
1984
1984
  });
1985
1985
  }
1986
1986
  /**
1987
- * Create a modal dialog with an iframe inside.
1987
+ * Create a modal dialog with a full-viewport iframe inside.
1988
+ * All visual chrome (backdrop, positioning, animations) is rendered
1989
+ * by the passkey app inside the iframe — the SDK just provides
1990
+ * a transparent full-screen container.
1988
1991
  */
1989
1992
  createModalDialog(url) {
1990
1993
  const dialogUrl = this.getDialogUrl();
1991
1994
  const hostUrl = new URL(dialogUrl);
1995
+ const urlParams = new URL(url, window.location.href).searchParams;
1996
+ const themeMode = urlParams.get("theme") || "light";
1997
+ const accentColor = urlParams.get("accent") || "#0090ff";
1998
+ const isDark = themeMode === "dark" || themeMode !== "light" && window.matchMedia("(prefers-color-scheme: dark)").matches;
1999
+ const bgPrimary = isDark ? "#191919" : "#fcfcfc";
2000
+ const bgSecondary = isDark ? "#222222" : "#f9f9f9";
2001
+ const borderColor = isDark ? "#2a2a2a" : "#e0e0e0";
2002
+ const textPrimary = isDark ? "#eeeeee" : "#202020";
2003
+ const textSecondary = isDark ? "#7b7b7b" : "#838383";
2004
+ const bgSurface = isDark ? "#222222" : "#f0f0f0";
2005
+ const ah = accentColor.replace("#", "");
2006
+ const accentRgb = `${parseInt(ah.slice(0, 2), 16)},${parseInt(ah.slice(2, 4), 16)},${parseInt(ah.slice(4, 6), 16)}`;
2007
+ const accentTint = isDark ? `rgba(${accentRgb},0.15)` : `rgba(${accentRgb},0.1)`;
2008
+ const hostname = window.location.hostname;
1992
2009
  const dialog = document.createElement("dialog");
1993
2010
  dialog.dataset.passkey = "";
2011
+ dialog.style.opacity = "1";
2012
+ dialog.style.background = "transparent";
1994
2013
  document.body.appendChild(dialog);
1995
2014
  const style = document.createElement("style");
1996
2015
  style.textContent = `
1997
2016
  dialog[data-passkey] {
1998
- padding: 0;
1999
- border: none;
2000
- background: transparent;
2017
+ position: fixed;
2018
+ top: 0;
2019
+ left: 0;
2020
+ width: 100vw;
2021
+ height: 100vh;
2022
+ height: 100dvh;
2001
2023
  max-width: none;
2002
2024
  max-height: none;
2003
2025
  margin: 0;
2004
- position: fixed;
2005
- top: 50px;
2006
- left: 50%;
2007
- transform: translateX(-50%);
2026
+ padding: 0;
2027
+ border: none;
2028
+ background: transparent;
2029
+ color-scheme: normal;
2008
2030
  outline: none;
2031
+ overflow: hidden;
2032
+ pointer-events: auto;
2009
2033
  }
2010
-
2011
2034
  dialog[data-passkey]::backdrop {
2012
- background-color: rgba(0, 0, 0, 0.4);
2013
- backdrop-filter: blur(8px);
2014
- -webkit-backdrop-filter: blur(8px);
2035
+ background: transparent !important;
2015
2036
  }
2016
-
2017
2037
  dialog[data-passkey] iframe {
2038
+ position: fixed;
2039
+ top: 0;
2040
+ left: 0;
2041
+ width: 100%;
2042
+ height: 100%;
2043
+ border: 0;
2018
2044
  background-color: transparent;
2019
- border-radius: 14px;
2020
- border: none;
2021
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.08);
2022
- transition: height 0.15s ease-out;
2023
- max-height: calc(100vh - 100px);
2024
- max-height: calc(100dvh - 100px);
2045
+ color-scheme: normal;
2046
+ pointer-events: auto;
2047
+ backdrop-filter: blur(8px);
2048
+ -webkit-backdrop-filter: blur(8px);
2025
2049
  }
2026
-
2027
- @media (min-width: 769px) {
2028
- dialog[data-passkey] iframe {
2029
- animation: passkey_zoomIn 0.2s cubic-bezier(0.32, 0.72, 0, 1);
2030
- }
2050
+ dialog[data-passkey] [data-passkey-overlay] {
2051
+ position: fixed;
2052
+ top: 0;
2053
+ left: 0;
2054
+ width: 100%;
2055
+ height: 100%;
2056
+ display: flex;
2057
+ align-items: flex-start;
2058
+ justify-content: center;
2059
+ padding-top: 50px;
2060
+ background: rgba(0, 0, 0, 0.4);
2061
+ backdrop-filter: blur(8px);
2062
+ -webkit-backdrop-filter: blur(8px);
2063
+ z-index: 1;
2064
+ animation: _1auth-backdrop-in 0.2s ease-out;
2031
2065
  }
2032
-
2033
2066
  @media (max-width: 768px) {
2034
- dialog[data-passkey] {
2035
- width: 100vw !important;
2036
- height: auto !important;
2037
- max-height: 90vh !important;
2038
- max-height: 90dvh !important;
2039
- top: auto !important;
2040
- bottom: 0 !important;
2041
- left: 0 !important;
2042
- right: 0 !important;
2043
- transform: none !important;
2044
- margin: 0 !important;
2045
- }
2046
-
2047
- dialog[data-passkey] iframe {
2048
- animation: passkey_slideFromBottom 0.3s cubic-bezier(0.32, 0.72, 0, 1);
2049
- border-bottom-left-radius: 0 !important;
2050
- border-bottom-right-radius: 0 !important;
2051
- width: 100% !important;
2052
- max-height: 90vh !important;
2053
- max-height: 90dvh !important;
2054
- box-shadow: 0 -4px 32px rgba(0, 0, 0, 0.15) !important;
2067
+ dialog[data-passkey] [data-passkey-overlay] {
2068
+ align-items: flex-end;
2069
+ padding-top: 0;
2055
2070
  }
2056
2071
  }
2057
-
2058
- @keyframes passkey_zoomIn {
2059
- from {
2060
- opacity: 0;
2061
- transform: scale(0.96) translateY(8px);
2062
- }
2063
- to {
2064
- opacity: 1;
2065
- transform: scale(1) translateY(0);
2072
+ dialog[data-passkey] [data-passkey-card] {
2073
+ width: 340px;
2074
+ overflow: hidden;
2075
+ border-radius: 14px;
2076
+ box-shadow: 0 8px 32px rgba(0,0,0,0.12), 0 2px 8px rgba(0,0,0,0.08);
2077
+ animation: _1auth-card-in 0.2s cubic-bezier(0.32, 0.72, 0, 1);
2078
+ max-height: calc(100dvh - 100px);
2079
+ }
2080
+ @media (max-width: 768px) {
2081
+ dialog[data-passkey] [data-passkey-card] {
2082
+ width: 100%;
2083
+ border-bottom-left-radius: 0;
2084
+ border-bottom-right-radius: 0;
2085
+ animation: _1auth-card-slide 0.3s cubic-bezier(0.32, 0.72, 0, 1);
2066
2086
  }
2067
2087
  }
2068
-
2069
- @keyframes passkey_slideFromBottom {
2088
+ @keyframes _1auth-backdrop-in {
2089
+ from { opacity: 0; } to { opacity: 1; }
2090
+ }
2091
+ @keyframes _1auth-card-in {
2092
+ from { opacity: 0; transform: scale(0.96) translateY(8px); }
2093
+ to { opacity: 1; transform: scale(1) translateY(0); }
2094
+ }
2095
+ @keyframes _1auth-card-slide {
2070
2096
  from { transform: translate3d(0, 100%, 0); }
2071
2097
  to { transform: translate3d(0, 0, 0); }
2072
2098
  }
2073
-
2074
- @keyframes passkey_shake {
2075
- 0%, 100% { transform: translateX(0); }
2076
- 20% { transform: translateX(-4px); }
2077
- 40% { transform: translateX(4px); }
2078
- 60% { transform: translateX(-4px); }
2079
- 80% { transform: translateX(4px); }
2099
+ @keyframes _1auth-spin {
2100
+ from { transform: rotate(0deg); }
2101
+ to { transform: rotate(360deg); }
2080
2102
  }
2081
2103
  `;
2082
2104
  dialog.appendChild(style);
2105
+ const overlay = document.createElement("div");
2106
+ overlay.dataset.passkeyOverlay = "";
2107
+ const _sp = '<path d="M10 0.5C8.02219 0.5 6.08879 1.08649 4.4443 2.1853C2.79981 3.28412 1.51809 4.8459 0.761209 6.67316C0.00433288 8.50043 -0.1937 10.5111 0.192152 12.4509C0.578004 14.3907 1.53041 16.1725 2.92894 17.5711C4.32746 18.9696 6.10929 19.922 8.0491 20.3078C9.98891 20.6937 11.9996 20.4957 13.8268 19.7388C15.6541 18.9819 17.2159 17.7002 18.3147 16.0557C19.4135 14.4112 20 12.4778 20 10.5C20 7.84783 18.9464 5.3043 17.0711 3.42893C15.1957 1.55357 12.6522 0.5 10 0.5ZM10 17.7727C8.56159 17.7727 7.15549 17.3462 5.95949 16.547C4.7635 15.7479 3.83134 14.6121 3.28088 13.2831C2.73042 11.9542 2.5864 10.4919 2.86702 9.08116C3.14764 7.67039 3.8403 6.37451 4.85741 5.3574C5.87452 4.3403 7.17039 3.64764 8.58116 3.36702C9.99193 3.0864 11.4542 3.23042 12.7832 3.78088C14.1121 4.33133 15.2479 5.26349 16.0471 6.45949C16.8462 7.65548 17.2727 9.06159 17.2727 10.5C17.2727 12.4288 16.5065 14.2787 15.1426 15.6426C13.7787 17.0065 11.9288 17.7727 10 17.7727Z" fill="currentColor" opacity="0.3"/><path d="M10 3.22767C11.7423 3.22846 13.4276 3.8412 14.7556 4.95667C16.0837 6.07214 16.9681 7.61784 17.2512 9.31825C17.3012 9.64364 17.4662 9.94096 17.7169 10.1573C17.9677 10.3737 18.2878 10.4951 18.6205 10.5C18.8211 10.5001 19.0193 10.457 19.2012 10.3735C19.3832 10.2901 19.5445 10.1684 19.674 10.017C19.8036 9.86549 19.8981 9.68789 19.9511 9.49656C20.004 9.30523 20.0141 9.10478 19.9807 8.90918C19.5986 6.56305 18.3843 4.42821 16.5554 2.88726C14.7265 1.34631 12.4025 0.5 10 0.5C7.59751 0.5 5.27354 1.34631 3.44461 2.88726C1.61569 4.42821 0.401366 6.56305 0.0192815 8.90918C-0.0141442 9.10478 -0.00402016 9.30523 0.0489472 9.49656C0.101914 9.68789 0.196449 9.86549 0.325956 10.017C0.455463 10.1684 0.616823 10.2901 0.798778 10.3735C0.980732 10.457 1.1789 10.5001 1.37945 10.5C1.71216 10.4951 2.03235 10.3737 2.28307 10.1573C2.5338 9.94096 2.69883 9.64364 2.74882 9.31825C3.03193 7.61784 3.91633 6.07214 5.24436 4.95667C6.57239 3.8412 8.25775 3.22846 10 3.22767Z" fill="currentColor"/>';
2108
+ overlay.innerHTML = `<div data-passkey-card style="background:${bgPrimary};border:1px solid ${borderColor};font-family:ui-sans-serif,system-ui,sans-serif,'Apple Color Emoji','Segoe UI Emoji'"><div style="height:36px;display:flex;align-items:center;justify-content:space-between;padding:0 12px;background:${bgSecondary};border-bottom:1px solid ${borderColor}"><div style="display:flex;align-items:center;gap:8px"><div style="display:flex;width:20px;height:20px;align-items:center;justify-content:center;border-radius:4px;background:${bgSurface}"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="${textPrimary}" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12V7H5a2 2 0 0 1 0-4h14v4"/><path d="M3 5v14a2 2 0 0 0 2 2h16v-5"/><path d="M18 12a2 2 0 0 0 0 4h4v-4Z"/></svg></div><span style="font-size:13px;font-weight:500;color:${textPrimary};max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${hostname}</span><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="${textSecondary}" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/><path d="m9 12 2 2 4-4"/></svg></div><div style="display:flex;align-items:center;gap:4px"><div style="display:flex;width:24px;height:24px;align-items:center;justify-content:center;border-radius:6px;color:${textSecondary}"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></svg></div><button data-passkey-close style="display:flex;width:24px;height:24px;align-items:center;justify-content:center;border-radius:6px;color:${textSecondary};border:none;background:none;cursor:pointer;padding:0"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg></button></div></div><div style="padding:12px"><div style="display:flex;align-items:center;gap:8px"><div style="display:flex;width:32px;height:32px;min-width:32px;align-items:center;justify-content:center;border-radius:50%;background:${accentTint};padding:6px"><svg style="width:100%;height:100%;animation:_1auth-spin 0.8s linear infinite;color:${accentColor}" fill="none" viewBox="0 0 20 21" xmlns="http://www.w3.org/2000/svg">${_sp}</svg></div><div style="font-weight:500;font-size:18px;color:${textPrimary}">Loading...</div></div><div style="margin-top:8px"><div style="font-size:15px;line-height:20px;color:${textPrimary}">This will only take a few moments.</div><div style="font-size:15px;line-height:20px;color:${textSecondary}">Please do not close the window.</div></div></div></div>`;
2109
+ overlay.addEventListener("click", (e) => {
2110
+ if (e.target === overlay) cleanup();
2111
+ });
2112
+ const overlayCloseBtn = overlay.querySelector("[data-passkey-close]");
2113
+ if (overlayCloseBtn) overlayCloseBtn.addEventListener("click", () => cleanup());
2114
+ dialog.appendChild(overlay);
2083
2115
  const iframe = document.createElement("iframe");
2084
2116
  iframe.setAttribute(
2085
2117
  "allow",
2086
- "publickey-credentials-get *; publickey-credentials-create *; clipboard-write; identity-credentials-get"
2118
+ [
2119
+ `publickey-credentials-get ${hostUrl.origin}`,
2120
+ `publickey-credentials-create ${hostUrl.origin}`,
2121
+ "clipboard-write",
2122
+ "identity-credentials-get"
2123
+ ].join("; ")
2087
2124
  );
2088
2125
  iframe.setAttribute("aria-label", "Passkey Authentication");
2089
2126
  iframe.setAttribute("tabindex", "0");
2127
+ iframe.setAttribute(
2128
+ "sandbox",
2129
+ "allow-forms allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox"
2130
+ );
2090
2131
  iframe.setAttribute("src", url);
2091
2132
  iframe.setAttribute("title", "Passkey");
2092
- iframe.style.border = "none";
2093
- iframe.style.height = "400px";
2094
- iframe.style.width = `${MODAL_WIDTH}px`;
2133
+ iframe.style.opacity = "0";
2095
2134
  dialog.appendChild(iframe);
2135
+ const inertObserver = new MutationObserver((mutations) => {
2136
+ for (const mutation of mutations) {
2137
+ if (mutation.attributeName === "inert") {
2138
+ dialog.removeAttribute("inert");
2139
+ }
2140
+ }
2141
+ });
2142
+ inertObserver.observe(dialog, { attributes: true });
2143
+ let overlayHidden = false;
2144
+ const hideOverlay = () => {
2145
+ if (overlayHidden) return;
2146
+ overlayHidden = true;
2147
+ overlay.style.display = "none";
2148
+ iframe.style.opacity = "1";
2149
+ };
2096
2150
  const handleMessage = (event) => {
2097
2151
  if (event.origin !== hostUrl.origin) return;
2098
- if (event.data?.type === "PASSKEY_RESIZE") {
2099
- const maxHeight = window.innerHeight - 100;
2100
- iframe.style.height = `${Math.min(event.data.height, maxHeight)}px`;
2101
- } else if (event.data?.type === "PASSKEY_DISCONNECT") {
2152
+ if (event.data?.type === "PASSKEY_RENDERED") {
2153
+ hideOverlay();
2154
+ }
2155
+ if (event.data?.type === "PASSKEY_DISCONNECT") {
2102
2156
  localStorage.removeItem("1auth-user");
2103
2157
  }
2104
2158
  };
@@ -2109,19 +2163,22 @@ var OneAuthClient = class {
2109
2163
  }
2110
2164
  };
2111
2165
  document.addEventListener("keydown", handleEscape);
2112
- dialog.addEventListener("click", (event) => {
2113
- if (event.target === dialog) {
2114
- cleanup();
2115
- }
2116
- });
2117
2166
  dialog.showModal();
2118
2167
  let cleanedUp = false;
2119
2168
  const cleanup = () => {
2120
2169
  if (cleanedUp) return;
2121
2170
  cleanedUp = true;
2171
+ inertObserver.disconnect();
2122
2172
  window.removeEventListener("message", handleMessage);
2123
2173
  document.removeEventListener("keydown", handleEscape);
2124
2174
  dialog.close();
2175
+ if (dialog.parentNode) {
2176
+ for (const sibling of Array.from(dialog.parentNode.children)) {
2177
+ if (sibling !== dialog && sibling instanceof HTMLElement && sibling.hasAttribute("inert")) {
2178
+ sibling.removeAttribute("inert");
2179
+ }
2180
+ }
2181
+ }
2125
2182
  dialog.remove();
2126
2183
  };
2127
2184
  return { dialog, iframe, cleanup };
@@ -2137,7 +2194,8 @@ var OneAuthClient = class {
2137
2194
  dialogReady = true;
2138
2195
  iframe.contentWindow?.postMessage({
2139
2196
  type: "PASSKEY_INIT",
2140
- mode: "iframe"
2197
+ mode: "iframe",
2198
+ fullViewport: true
2141
2199
  }, dialogOrigin);
2142
2200
  return;
2143
2201
  }