@authon/js 0.1.7 → 0.1.9
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.js +99 -19
- package/dist/index.mjs +99 -19
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -131,6 +131,25 @@ var ModalRenderer = class {
|
|
|
131
131
|
this.containerElement.innerHTML = "";
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
|
+
showLoading() {
|
|
135
|
+
if (!this.shadowRoot) return;
|
|
136
|
+
this.hideLoading();
|
|
137
|
+
const overlay = document.createElement("div");
|
|
138
|
+
overlay.id = "authon-loading-overlay";
|
|
139
|
+
overlay.innerHTML = `
|
|
140
|
+
<div class="loading-spinner">
|
|
141
|
+
<div class="loading-ring"></div>
|
|
142
|
+
<div class="loading-ring"></div>
|
|
143
|
+
<div class="loading-ring"></div>
|
|
144
|
+
</div>
|
|
145
|
+
<div class="loading-text">Signing in<span class="loading-dots"><span></span><span></span><span></span></span></div>
|
|
146
|
+
`;
|
|
147
|
+
this.shadowRoot.querySelector(".modal-container")?.appendChild(overlay);
|
|
148
|
+
}
|
|
149
|
+
hideLoading() {
|
|
150
|
+
if (!this.shadowRoot) return;
|
|
151
|
+
this.shadowRoot.getElementById("authon-loading-overlay")?.remove();
|
|
152
|
+
}
|
|
134
153
|
render(view) {
|
|
135
154
|
const host = document.createElement("div");
|
|
136
155
|
host.setAttribute("data-authon-modal", "");
|
|
@@ -234,6 +253,7 @@ var ModalRenderer = class {
|
|
|
234
253
|
border-radius: var(--authon-radius);
|
|
235
254
|
padding: 32px;
|
|
236
255
|
width: 400px; max-width: 100%;
|
|
256
|
+
position: ${this.mode === "popup" ? "fixed" : "relative"};
|
|
237
257
|
${this.mode === "popup" ? `box-shadow: 0 25px 50px -12px rgba(0,0,0,${dark ? "0.5" : "0.25"}); animation: slideIn 0.3s ease;` : ""}
|
|
238
258
|
}
|
|
239
259
|
.logo { display: block; margin: 0 auto 16px; max-height: 48px; }
|
|
@@ -288,6 +308,39 @@ var ModalRenderer = class {
|
|
|
288
308
|
font-size: 11px; color: var(--authon-dim);
|
|
289
309
|
}
|
|
290
310
|
.secured-brand { font-weight: 600; color: var(--authon-muted); }
|
|
311
|
+
/* Loading overlay */
|
|
312
|
+
#authon-loading-overlay {
|
|
313
|
+
position: absolute; inset: 0; z-index: 10;
|
|
314
|
+
background: ${dark ? "rgba(15,23,42,0.92)" : "rgba(255,255,255,0.92)"};
|
|
315
|
+
backdrop-filter: blur(2px);
|
|
316
|
+
border-radius: var(--authon-radius);
|
|
317
|
+
display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 20px;
|
|
318
|
+
animation: fadeIn 0.15s ease;
|
|
319
|
+
}
|
|
320
|
+
.loading-spinner { position: relative; width: 48px; height: 48px; }
|
|
321
|
+
.loading-ring {
|
|
322
|
+
position: absolute; inset: 0;
|
|
323
|
+
border: 2.5px solid transparent; border-top-color: var(--authon-primary-start);
|
|
324
|
+
border-radius: 50%; animation: spin 1s cubic-bezier(.55,.15,.45,.85) infinite;
|
|
325
|
+
}
|
|
326
|
+
.loading-ring:nth-child(2) {
|
|
327
|
+
inset: 5px; border-top-color: transparent; border-right-color: var(--authon-primary-end);
|
|
328
|
+
animation-duration: 1.2s; animation-direction: reverse; opacity: .7;
|
|
329
|
+
}
|
|
330
|
+
.loading-ring:nth-child(3) {
|
|
331
|
+
inset: 10px; border-top-color: transparent; border-bottom-color: var(--authon-primary-start);
|
|
332
|
+
animation-duration: .8s; opacity: .4;
|
|
333
|
+
}
|
|
334
|
+
.loading-text { font-size: 14px; font-weight: 500; color: var(--authon-muted); }
|
|
335
|
+
.loading-dots { display: inline-flex; gap: 2px; margin-left: 2px; }
|
|
336
|
+
.loading-dots span {
|
|
337
|
+
width: 3px; height: 3px; border-radius: 50%;
|
|
338
|
+
background: var(--authon-muted); animation: blink 1.4s infinite both;
|
|
339
|
+
}
|
|
340
|
+
.loading-dots span:nth-child(2) { animation-delay: .2s; }
|
|
341
|
+
.loading-dots span:nth-child(3) { animation-delay: .4s; }
|
|
342
|
+
@keyframes spin { to { transform: rotate(360deg); } }
|
|
343
|
+
@keyframes blink { 0%,80%,100% { opacity: .2; } 40% { opacity: 1; } }
|
|
291
344
|
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
|
|
292
345
|
@keyframes slideIn { from { opacity: 0; transform: translate(-50%, -48%); } to { opacity: 1; transform: translate(-50%, -50%); } }
|
|
293
346
|
${b.customCss || ""}
|
|
@@ -542,6 +595,7 @@ var Authon = class {
|
|
|
542
595
|
const { url } = await this.apiGet(
|
|
543
596
|
`/v1/auth/oauth/${provider}/url?redirectUri=${encodeURIComponent(redirectUri)}`
|
|
544
597
|
);
|
|
598
|
+
this.modal?.showLoading();
|
|
545
599
|
const width = 500;
|
|
546
600
|
const height = 700;
|
|
547
601
|
const left = window.screenX + (window.outerWidth - width) / 2;
|
|
@@ -551,30 +605,56 @@ var Authon = class {
|
|
|
551
605
|
"authon-oauth",
|
|
552
606
|
`width=${width},height=${height},left=${left},top=${top},toolbar=no,menubar=no`
|
|
553
607
|
);
|
|
608
|
+
let callbackReceived = false;
|
|
609
|
+
let cleaned = false;
|
|
610
|
+
const cleanup = () => {
|
|
611
|
+
if (cleaned) return;
|
|
612
|
+
cleaned = true;
|
|
613
|
+
window.removeEventListener("message", handler);
|
|
614
|
+
window.removeEventListener("focus", focusHandler);
|
|
615
|
+
if (maxTimer) clearTimeout(maxTimer);
|
|
616
|
+
};
|
|
617
|
+
const focusHandler = () => {
|
|
618
|
+
if (callbackReceived || cleaned) return;
|
|
619
|
+
setTimeout(() => {
|
|
620
|
+
if (callbackReceived || cleaned) return;
|
|
621
|
+
cleanup();
|
|
622
|
+
this.modal?.hideLoading();
|
|
623
|
+
}, 1500);
|
|
624
|
+
};
|
|
625
|
+
window.addEventListener("focus", focusHandler);
|
|
626
|
+
const maxTimer = setTimeout(() => {
|
|
627
|
+
if (callbackReceived || cleaned) return;
|
|
628
|
+
cleanup();
|
|
629
|
+
this.modal?.hideLoading();
|
|
630
|
+
}, 18e4);
|
|
631
|
+
if (!popup) {
|
|
632
|
+
cleanup();
|
|
633
|
+
this.modal?.hideLoading();
|
|
634
|
+
this.emit("error", new Error("Popup was blocked by the browser"));
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
554
637
|
const handler = async (e) => {
|
|
555
|
-
if (e.data?.type
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
this.emit("signedIn", tokens.user);
|
|
571
|
-
} catch (err) {
|
|
572
|
-
this.emit("error", err instanceof Error ? err : new Error(String(err)));
|
|
573
|
-
}
|
|
638
|
+
if (e.data?.type !== "authon-oauth-callback") return;
|
|
639
|
+
callbackReceived = true;
|
|
640
|
+
cleanup();
|
|
641
|
+
try {
|
|
642
|
+
const tokens = await this.apiPost("/v1/auth/oauth/callback", {
|
|
643
|
+
code: e.data.code,
|
|
644
|
+
state: e.data.state,
|
|
645
|
+
provider
|
|
646
|
+
});
|
|
647
|
+
this.session.setSession(tokens);
|
|
648
|
+
this.modal?.close();
|
|
649
|
+
this.emit("signedIn", tokens.user);
|
|
650
|
+
} catch (err) {
|
|
651
|
+
this.modal?.hideLoading();
|
|
652
|
+
this.emit("error", err instanceof Error ? err : new Error(String(err)));
|
|
574
653
|
}
|
|
575
654
|
};
|
|
576
655
|
window.addEventListener("message", handler);
|
|
577
656
|
} catch (err) {
|
|
657
|
+
this.modal?.hideLoading();
|
|
578
658
|
this.emit("error", err instanceof Error ? err : new Error(String(err)));
|
|
579
659
|
}
|
|
580
660
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -104,6 +104,25 @@ var ModalRenderer = class {
|
|
|
104
104
|
this.containerElement.innerHTML = "";
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
|
+
showLoading() {
|
|
108
|
+
if (!this.shadowRoot) return;
|
|
109
|
+
this.hideLoading();
|
|
110
|
+
const overlay = document.createElement("div");
|
|
111
|
+
overlay.id = "authon-loading-overlay";
|
|
112
|
+
overlay.innerHTML = `
|
|
113
|
+
<div class="loading-spinner">
|
|
114
|
+
<div class="loading-ring"></div>
|
|
115
|
+
<div class="loading-ring"></div>
|
|
116
|
+
<div class="loading-ring"></div>
|
|
117
|
+
</div>
|
|
118
|
+
<div class="loading-text">Signing in<span class="loading-dots"><span></span><span></span><span></span></span></div>
|
|
119
|
+
`;
|
|
120
|
+
this.shadowRoot.querySelector(".modal-container")?.appendChild(overlay);
|
|
121
|
+
}
|
|
122
|
+
hideLoading() {
|
|
123
|
+
if (!this.shadowRoot) return;
|
|
124
|
+
this.shadowRoot.getElementById("authon-loading-overlay")?.remove();
|
|
125
|
+
}
|
|
107
126
|
render(view) {
|
|
108
127
|
const host = document.createElement("div");
|
|
109
128
|
host.setAttribute("data-authon-modal", "");
|
|
@@ -207,6 +226,7 @@ var ModalRenderer = class {
|
|
|
207
226
|
border-radius: var(--authon-radius);
|
|
208
227
|
padding: 32px;
|
|
209
228
|
width: 400px; max-width: 100%;
|
|
229
|
+
position: ${this.mode === "popup" ? "fixed" : "relative"};
|
|
210
230
|
${this.mode === "popup" ? `box-shadow: 0 25px 50px -12px rgba(0,0,0,${dark ? "0.5" : "0.25"}); animation: slideIn 0.3s ease;` : ""}
|
|
211
231
|
}
|
|
212
232
|
.logo { display: block; margin: 0 auto 16px; max-height: 48px; }
|
|
@@ -261,6 +281,39 @@ var ModalRenderer = class {
|
|
|
261
281
|
font-size: 11px; color: var(--authon-dim);
|
|
262
282
|
}
|
|
263
283
|
.secured-brand { font-weight: 600; color: var(--authon-muted); }
|
|
284
|
+
/* Loading overlay */
|
|
285
|
+
#authon-loading-overlay {
|
|
286
|
+
position: absolute; inset: 0; z-index: 10;
|
|
287
|
+
background: ${dark ? "rgba(15,23,42,0.92)" : "rgba(255,255,255,0.92)"};
|
|
288
|
+
backdrop-filter: blur(2px);
|
|
289
|
+
border-radius: var(--authon-radius);
|
|
290
|
+
display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 20px;
|
|
291
|
+
animation: fadeIn 0.15s ease;
|
|
292
|
+
}
|
|
293
|
+
.loading-spinner { position: relative; width: 48px; height: 48px; }
|
|
294
|
+
.loading-ring {
|
|
295
|
+
position: absolute; inset: 0;
|
|
296
|
+
border: 2.5px solid transparent; border-top-color: var(--authon-primary-start);
|
|
297
|
+
border-radius: 50%; animation: spin 1s cubic-bezier(.55,.15,.45,.85) infinite;
|
|
298
|
+
}
|
|
299
|
+
.loading-ring:nth-child(2) {
|
|
300
|
+
inset: 5px; border-top-color: transparent; border-right-color: var(--authon-primary-end);
|
|
301
|
+
animation-duration: 1.2s; animation-direction: reverse; opacity: .7;
|
|
302
|
+
}
|
|
303
|
+
.loading-ring:nth-child(3) {
|
|
304
|
+
inset: 10px; border-top-color: transparent; border-bottom-color: var(--authon-primary-start);
|
|
305
|
+
animation-duration: .8s; opacity: .4;
|
|
306
|
+
}
|
|
307
|
+
.loading-text { font-size: 14px; font-weight: 500; color: var(--authon-muted); }
|
|
308
|
+
.loading-dots { display: inline-flex; gap: 2px; margin-left: 2px; }
|
|
309
|
+
.loading-dots span {
|
|
310
|
+
width: 3px; height: 3px; border-radius: 50%;
|
|
311
|
+
background: var(--authon-muted); animation: blink 1.4s infinite both;
|
|
312
|
+
}
|
|
313
|
+
.loading-dots span:nth-child(2) { animation-delay: .2s; }
|
|
314
|
+
.loading-dots span:nth-child(3) { animation-delay: .4s; }
|
|
315
|
+
@keyframes spin { to { transform: rotate(360deg); } }
|
|
316
|
+
@keyframes blink { 0%,80%,100% { opacity: .2; } 40% { opacity: 1; } }
|
|
264
317
|
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
|
|
265
318
|
@keyframes slideIn { from { opacity: 0; transform: translate(-50%, -48%); } to { opacity: 1; transform: translate(-50%, -50%); } }
|
|
266
319
|
${b.customCss || ""}
|
|
@@ -515,6 +568,7 @@ var Authon = class {
|
|
|
515
568
|
const { url } = await this.apiGet(
|
|
516
569
|
`/v1/auth/oauth/${provider}/url?redirectUri=${encodeURIComponent(redirectUri)}`
|
|
517
570
|
);
|
|
571
|
+
this.modal?.showLoading();
|
|
518
572
|
const width = 500;
|
|
519
573
|
const height = 700;
|
|
520
574
|
const left = window.screenX + (window.outerWidth - width) / 2;
|
|
@@ -524,30 +578,56 @@ var Authon = class {
|
|
|
524
578
|
"authon-oauth",
|
|
525
579
|
`width=${width},height=${height},left=${left},top=${top},toolbar=no,menubar=no`
|
|
526
580
|
);
|
|
581
|
+
let callbackReceived = false;
|
|
582
|
+
let cleaned = false;
|
|
583
|
+
const cleanup = () => {
|
|
584
|
+
if (cleaned) return;
|
|
585
|
+
cleaned = true;
|
|
586
|
+
window.removeEventListener("message", handler);
|
|
587
|
+
window.removeEventListener("focus", focusHandler);
|
|
588
|
+
if (maxTimer) clearTimeout(maxTimer);
|
|
589
|
+
};
|
|
590
|
+
const focusHandler = () => {
|
|
591
|
+
if (callbackReceived || cleaned) return;
|
|
592
|
+
setTimeout(() => {
|
|
593
|
+
if (callbackReceived || cleaned) return;
|
|
594
|
+
cleanup();
|
|
595
|
+
this.modal?.hideLoading();
|
|
596
|
+
}, 1500);
|
|
597
|
+
};
|
|
598
|
+
window.addEventListener("focus", focusHandler);
|
|
599
|
+
const maxTimer = setTimeout(() => {
|
|
600
|
+
if (callbackReceived || cleaned) return;
|
|
601
|
+
cleanup();
|
|
602
|
+
this.modal?.hideLoading();
|
|
603
|
+
}, 18e4);
|
|
604
|
+
if (!popup) {
|
|
605
|
+
cleanup();
|
|
606
|
+
this.modal?.hideLoading();
|
|
607
|
+
this.emit("error", new Error("Popup was blocked by the browser"));
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
527
610
|
const handler = async (e) => {
|
|
528
|
-
if (e.data?.type
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
this.emit("signedIn", tokens.user);
|
|
544
|
-
} catch (err) {
|
|
545
|
-
this.emit("error", err instanceof Error ? err : new Error(String(err)));
|
|
546
|
-
}
|
|
611
|
+
if (e.data?.type !== "authon-oauth-callback") return;
|
|
612
|
+
callbackReceived = true;
|
|
613
|
+
cleanup();
|
|
614
|
+
try {
|
|
615
|
+
const tokens = await this.apiPost("/v1/auth/oauth/callback", {
|
|
616
|
+
code: e.data.code,
|
|
617
|
+
state: e.data.state,
|
|
618
|
+
provider
|
|
619
|
+
});
|
|
620
|
+
this.session.setSession(tokens);
|
|
621
|
+
this.modal?.close();
|
|
622
|
+
this.emit("signedIn", tokens.user);
|
|
623
|
+
} catch (err) {
|
|
624
|
+
this.modal?.hideLoading();
|
|
625
|
+
this.emit("error", err instanceof Error ? err : new Error(String(err)));
|
|
547
626
|
}
|
|
548
627
|
};
|
|
549
628
|
window.addEventListener("message", handler);
|
|
550
629
|
} catch (err) {
|
|
630
|
+
this.modal?.hideLoading();
|
|
551
631
|
this.emit("error", err instanceof Error ? err : new Error(String(err)));
|
|
552
632
|
}
|
|
553
633
|
}
|