@authon/js 0.3.5 → 0.4.0

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.d.cts CHANGED
@@ -110,6 +110,13 @@ declare class Authon {
110
110
  updateMemberRole: (orgId: string, memberId: string, role: string) => Promise<OrganizationMember>;
111
111
  leave: (orgId: string) => Promise<void>;
112
112
  };
113
+ /** Testing utilities — only available when initialized with a pk_test_ key */
114
+ get testing(): {
115
+ signIn(params: {
116
+ email: string;
117
+ nickname?: string;
118
+ }): Promise<AuthonUser>;
119
+ } | undefined;
113
120
  destroy(): void;
114
121
  private loadTurnstileScript;
115
122
  private emit;
package/dist/index.d.ts CHANGED
@@ -110,6 +110,13 @@ declare class Authon {
110
110
  updateMemberRole: (orgId: string, memberId: string, role: string) => Promise<OrganizationMember>;
111
111
  leave: (orgId: string) => Promise<void>;
112
112
  };
113
+ /** Testing utilities — only available when initialized with a pk_test_ key */
114
+ get testing(): {
115
+ signIn(params: {
116
+ email: string;
117
+ nickname?: string;
118
+ }): Promise<AuthonUser>;
119
+ } | undefined;
113
120
  destroy(): void;
114
121
  private loadTurnstileScript;
115
122
  private emit;
package/dist/index.js CHANGED
@@ -100,6 +100,7 @@ var ModalRenderer = class {
100
100
  shadowRoot = null;
101
101
  hostElement = null;
102
102
  containerElement = null;
103
+ containerId = null;
103
104
  mode;
104
105
  theme;
105
106
  branding;
@@ -142,9 +143,20 @@ var ModalRenderer = class {
142
143
  this.onPasskeyClick = options.onPasskeyClick || (() => {
143
144
  });
144
145
  if (options.mode === "embedded" && options.containerId) {
145
- this.containerElement = document.getElementById(options.containerId);
146
+ this.containerId = options.containerId;
146
147
  }
147
148
  }
149
+ resolveContainerElement() {
150
+ if (this.mode !== "embedded" || !this.containerId) return null;
151
+ const next = document.getElementById(this.containerId);
152
+ if (this.containerElement !== next) {
153
+ this.hostElement?.remove();
154
+ this.hostElement = null;
155
+ this.shadowRoot = null;
156
+ }
157
+ this.containerElement = next;
158
+ return next;
159
+ }
148
160
  setProviders(providers) {
149
161
  this.enabledProviders = providers;
150
162
  }
@@ -152,6 +164,11 @@ var ModalRenderer = class {
152
164
  this.branding = { ...DEFAULT_BRANDING, ...branding };
153
165
  }
154
166
  open(view = "signIn") {
167
+ this.resolveContainerElement();
168
+ if (this.hostElement && !this.hostElement.isConnected) {
169
+ this.hostElement = null;
170
+ this.shadowRoot = null;
171
+ }
155
172
  if (this.shadowRoot && this.hostElement) {
156
173
  this.hideOverlay();
157
174
  this.switchView(view);
@@ -181,8 +198,9 @@ var ModalRenderer = class {
181
198
  this.hostElement = null;
182
199
  this.shadowRoot = null;
183
200
  }
184
- if (this.containerElement) {
185
- this.containerElement.innerHTML = "";
201
+ const liveContainer = this.resolveContainerElement();
202
+ if (liveContainer) {
203
+ liveContainer.replaceChildren();
186
204
  }
187
205
  this.currentOverlay = "none";
188
206
  }
@@ -348,8 +366,14 @@ var ModalRenderer = class {
348
366
  this.hostElement = host;
349
367
  if (this.mode === "popup") {
350
368
  document.body.appendChild(host);
351
- } else if (this.containerElement) {
352
- this.containerElement.appendChild(host);
369
+ } else {
370
+ const container = this.resolveContainerElement();
371
+ if (!container) {
372
+ this.hostElement = null;
373
+ throw new Error(`Authon container "#${this.containerId}" not found`);
374
+ }
375
+ container.replaceChildren();
376
+ container.appendChild(host);
353
377
  }
354
378
  this.shadowRoot = host.attachShadow({ mode: "open" });
355
379
  this.shadowRoot.innerHTML = this.buildShell(view);
@@ -1107,9 +1131,42 @@ var SessionManager = class {
1107
1131
  refreshTimer = null;
1108
1132
  apiUrl;
1109
1133
  publishableKey;
1134
+ storageKey;
1110
1135
  constructor(publishableKey, apiUrl) {
1111
1136
  this.publishableKey = publishableKey;
1112
1137
  this.apiUrl = apiUrl;
1138
+ this.storageKey = `authon_session_${publishableKey.slice(0, 16)}`;
1139
+ this.restoreFromStorage();
1140
+ }
1141
+ restoreFromStorage() {
1142
+ if (typeof window === "undefined") return;
1143
+ try {
1144
+ const stored = localStorage.getItem(this.storageKey);
1145
+ if (!stored) return;
1146
+ const data = JSON.parse(stored);
1147
+ if (data.accessToken && data.refreshToken && data.user) {
1148
+ this.accessToken = data.accessToken;
1149
+ this.refreshToken = data.refreshToken;
1150
+ this.user = data.user;
1151
+ this.scheduleRefresh(5);
1152
+ }
1153
+ } catch {
1154
+ }
1155
+ }
1156
+ persistToStorage() {
1157
+ if (typeof window === "undefined") return;
1158
+ try {
1159
+ if (this.accessToken && this.refreshToken && this.user) {
1160
+ localStorage.setItem(this.storageKey, JSON.stringify({
1161
+ accessToken: this.accessToken,
1162
+ refreshToken: this.refreshToken,
1163
+ user: this.user
1164
+ }));
1165
+ } else {
1166
+ localStorage.removeItem(this.storageKey);
1167
+ }
1168
+ } catch {
1169
+ }
1113
1170
  }
1114
1171
  getToken() {
1115
1172
  return this.accessToken;
@@ -1121,6 +1178,7 @@ var SessionManager = class {
1121
1178
  this.accessToken = tokens.accessToken;
1122
1179
  this.refreshToken = tokens.refreshToken;
1123
1180
  this.user = tokens.user;
1181
+ this.persistToStorage();
1124
1182
  if (tokens.expiresIn && tokens.expiresIn > 0) {
1125
1183
  this.scheduleRefresh(tokens.expiresIn);
1126
1184
  }
@@ -1132,6 +1190,7 @@ var SessionManager = class {
1132
1190
  this.accessToken = null;
1133
1191
  this.refreshToken = null;
1134
1192
  this.user = null;
1193
+ this.persistToStorage();
1135
1194
  if (this.refreshTimer) {
1136
1195
  clearTimeout(this.refreshTimer);
1137
1196
  this.refreshTimer = null;
@@ -1927,6 +1986,18 @@ var Authon = class {
1927
1986
  await this.apiPostAuth(`/v1/auth/organizations/${orgId}/leave`, void 0, token);
1928
1987
  }
1929
1988
  };
1989
+ /** Testing utilities — only available when initialized with a pk_test_ key */
1990
+ get testing() {
1991
+ if (!this.publishableKey.startsWith("pk_test_")) return void 0;
1992
+ return {
1993
+ signIn: async (params) => {
1994
+ const res = await this.apiPost("/v1/auth/testing/token", params);
1995
+ this.session.setSession(res);
1996
+ this.emit("signedIn", res.user);
1997
+ return res.user;
1998
+ }
1999
+ };
2000
+ }
1930
2001
  destroy() {
1931
2002
  this.modal?.close();
1932
2003
  this.session.destroy();