@youidian/sdk 3.3.7 → 3.4.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/client.cjs +400 -36
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +41 -5
- package/dist/client.d.ts +41 -5
- package/dist/client.js +399 -36
- package/dist/client.js.map +1 -1
- package/dist/feedback.cjs +682 -0
- package/dist/feedback.cjs.map +1 -0
- package/dist/feedback.d.cts +38 -0
- package/dist/feedback.d.ts +38 -0
- package/dist/feedback.js +656 -0
- package/dist/feedback.js.map +1 -0
- package/dist/index.cjs +1164 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +1161 -36
- package/dist/index.js.map +1 -1
- package/dist/{login-DerOcXcH.d.cts → login-Dqemys65.d.cts} +8 -4
- package/dist/{login-DerOcXcH.d.ts → login-Dqemys65.d.ts} +8 -4
- package/dist/login.cjs +320 -30
- package/dist/login.cjs.map +1 -1
- package/dist/login.d.cts +1 -1
- package/dist/login.d.ts +1 -1
- package/dist/login.js +320 -30
- package/dist/login.js.map +1 -1
- package/dist/server.cjs +108 -0
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +137 -1
- package/dist/server.d.ts +137 -1
- package/dist/server.js +108 -0
- package/dist/server.js.map +1 -1
- package/package.json +6 -1
|
@@ -21,8 +21,8 @@ declare class HostedFrameModal<TData extends HostedFrameMessage> {
|
|
|
21
21
|
close(): void;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
type LoginEventType = "LOGIN_READY" | "LOGIN_SUCCESS" | "LOGIN_CANCELLED" | "LOGIN_CLOSE" | "LOGIN_RESIZE" | "LOGIN_ERROR";
|
|
25
|
-
type LoginDisplayMode = "modal" | "popup";
|
|
24
|
+
type LoginEventType = "LOGIN_READY" | "LOGIN_SUCCESS" | "LOGIN_CANCELLED" | "LOGIN_CLOSE" | "LOGIN_RESIZE" | "LOGIN_REDIRECT_REQUIRED" | "LOGIN_ERROR";
|
|
25
|
+
type LoginDisplayMode = "auto" | "modal" | "popup" | "redirect";
|
|
26
26
|
type LoginFallbackRedirectMode = "auto" | "manual";
|
|
27
27
|
interface LoginResult {
|
|
28
28
|
avatar?: string | null;
|
|
@@ -43,6 +43,9 @@ interface LoginResult {
|
|
|
43
43
|
}
|
|
44
44
|
interface LoginEventData extends HostedFrameMessage, LoginResult {
|
|
45
45
|
type: LoginEventType;
|
|
46
|
+
attemptId?: string;
|
|
47
|
+
authUrl?: string;
|
|
48
|
+
channel?: string;
|
|
46
49
|
error?: string;
|
|
47
50
|
message?: string;
|
|
48
51
|
}
|
|
@@ -54,8 +57,8 @@ interface LoginUIOptions {
|
|
|
54
57
|
/** Optional same-origin URL used as the no-API OAuth callback landing page. */
|
|
55
58
|
callbackUrl?: string;
|
|
56
59
|
/**
|
|
57
|
-
* How to open the hosted login page. Defaults to "
|
|
58
|
-
*
|
|
60
|
+
* How to open the hosted login page. Defaults to "auto", which uses an
|
|
61
|
+
* iframe modal on desktop and redirects on mobile/embedded browsers.
|
|
59
62
|
*/
|
|
60
63
|
displayMode?: LoginDisplayMode;
|
|
61
64
|
/** Text for the fallback button shown when the iframe does not report readiness. */
|
|
@@ -142,6 +145,7 @@ declare class LoginUI extends HostedFrameModal<LoginEventData> {
|
|
|
142
145
|
private showIframeFallback;
|
|
143
146
|
private startIframeWatchdog;
|
|
144
147
|
private handleLoginEvent;
|
|
148
|
+
private openLoginRedirect;
|
|
145
149
|
private listenForLoginCallback;
|
|
146
150
|
close(): void;
|
|
147
151
|
private buildOpenContext;
|
|
@@ -21,8 +21,8 @@ declare class HostedFrameModal<TData extends HostedFrameMessage> {
|
|
|
21
21
|
close(): void;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
type LoginEventType = "LOGIN_READY" | "LOGIN_SUCCESS" | "LOGIN_CANCELLED" | "LOGIN_CLOSE" | "LOGIN_RESIZE" | "LOGIN_ERROR";
|
|
25
|
-
type LoginDisplayMode = "modal" | "popup";
|
|
24
|
+
type LoginEventType = "LOGIN_READY" | "LOGIN_SUCCESS" | "LOGIN_CANCELLED" | "LOGIN_CLOSE" | "LOGIN_RESIZE" | "LOGIN_REDIRECT_REQUIRED" | "LOGIN_ERROR";
|
|
25
|
+
type LoginDisplayMode = "auto" | "modal" | "popup" | "redirect";
|
|
26
26
|
type LoginFallbackRedirectMode = "auto" | "manual";
|
|
27
27
|
interface LoginResult {
|
|
28
28
|
avatar?: string | null;
|
|
@@ -43,6 +43,9 @@ interface LoginResult {
|
|
|
43
43
|
}
|
|
44
44
|
interface LoginEventData extends HostedFrameMessage, LoginResult {
|
|
45
45
|
type: LoginEventType;
|
|
46
|
+
attemptId?: string;
|
|
47
|
+
authUrl?: string;
|
|
48
|
+
channel?: string;
|
|
46
49
|
error?: string;
|
|
47
50
|
message?: string;
|
|
48
51
|
}
|
|
@@ -54,8 +57,8 @@ interface LoginUIOptions {
|
|
|
54
57
|
/** Optional same-origin URL used as the no-API OAuth callback landing page. */
|
|
55
58
|
callbackUrl?: string;
|
|
56
59
|
/**
|
|
57
|
-
* How to open the hosted login page. Defaults to "
|
|
58
|
-
*
|
|
60
|
+
* How to open the hosted login page. Defaults to "auto", which uses an
|
|
61
|
+
* iframe modal on desktop and redirects on mobile/embedded browsers.
|
|
59
62
|
*/
|
|
60
63
|
displayMode?: LoginDisplayMode;
|
|
61
64
|
/** Text for the fallback button shown when the iframe does not report readiness. */
|
|
@@ -142,6 +145,7 @@ declare class LoginUI extends HostedFrameModal<LoginEventData> {
|
|
|
142
145
|
private showIframeFallback;
|
|
143
146
|
private startIframeWatchdog;
|
|
144
147
|
private handleLoginEvent;
|
|
148
|
+
private openLoginRedirect;
|
|
145
149
|
private listenForLoginCallback;
|
|
146
150
|
close(): void;
|
|
147
151
|
private buildOpenContext;
|
package/dist/login.cjs
CHANGED
|
@@ -28,6 +28,91 @@ __export(login_exports, {
|
|
|
28
28
|
});
|
|
29
29
|
module.exports = __toCommonJS(login_exports);
|
|
30
30
|
|
|
31
|
+
// src/environment.ts
|
|
32
|
+
function normalizeText(value) {
|
|
33
|
+
return value || "";
|
|
34
|
+
}
|
|
35
|
+
function getRuntimeInput() {
|
|
36
|
+
if (typeof navigator === "undefined") {
|
|
37
|
+
return {};
|
|
38
|
+
}
|
|
39
|
+
const nav = navigator;
|
|
40
|
+
const coarsePointer = typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia("(pointer: coarse)").matches : void 0;
|
|
41
|
+
return {
|
|
42
|
+
coarsePointer,
|
|
43
|
+
maxTouchPoints: nav.maxTouchPoints || 0,
|
|
44
|
+
platform: nav.platform || "",
|
|
45
|
+
standalone: nav.standalone,
|
|
46
|
+
userAgent: nav.userAgent || "",
|
|
47
|
+
userAgentDataMobile: nav.userAgentData?.mobile
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function includesAny(value, patterns) {
|
|
51
|
+
return patterns.some((pattern) => pattern.test(value));
|
|
52
|
+
}
|
|
53
|
+
function detectLoginEnvironment(input = getRuntimeInput()) {
|
|
54
|
+
const userAgent = normalizeText(input.userAgent);
|
|
55
|
+
const platform = normalizeText(input.platform);
|
|
56
|
+
const rawMaxTouchPoints = input.maxTouchPoints ?? 0;
|
|
57
|
+
const maxTouchPoints = Number.isFinite(rawMaxTouchPoints) ? Math.max(0, rawMaxTouchPoints) : 0;
|
|
58
|
+
const isCoarsePointer = input.coarsePointer === true;
|
|
59
|
+
const isTouch = maxTouchPoints > 0 || isCoarsePointer;
|
|
60
|
+
const isWeChat = /micromessenger/i.test(userAgent);
|
|
61
|
+
const isAndroid = /\bandroid\b/i.test(userAgent);
|
|
62
|
+
const hasExplicitIOSDevice = /\b(iPad|iPhone|iPod)\b/i.test(userAgent);
|
|
63
|
+
const hasMacintoshUserAgent = /\bMacintosh\b/i.test(userAgent);
|
|
64
|
+
const hasMacPlatform = /^Mac/i.test(platform);
|
|
65
|
+
const isIPadOS = !hasExplicitIOSDevice && hasMacintoshUserAgent && hasMacPlatform && typeof input.standalone !== "undefined" && maxTouchPoints > 2;
|
|
66
|
+
const isIOS = hasExplicitIOSDevice || isIPadOS;
|
|
67
|
+
const isTabletByUa = includesAny(userAgent, [
|
|
68
|
+
/\biPad\b/i,
|
|
69
|
+
/\btablet\b/i,
|
|
70
|
+
/\bplaybook\b/i,
|
|
71
|
+
/\bsilk\b(?!.*\bmobile\b)/i,
|
|
72
|
+
/\bkindle\b/i,
|
|
73
|
+
/\bnexus 7\b/i,
|
|
74
|
+
/\bnexus 9\b/i,
|
|
75
|
+
/\bxoom\b/i,
|
|
76
|
+
/\bsm-t\d+/i,
|
|
77
|
+
/\bgt-p\d+/i,
|
|
78
|
+
/\bmi pad\b/i
|
|
79
|
+
]);
|
|
80
|
+
const isMobileByUa = includesAny(userAgent, [
|
|
81
|
+
/\bMobile\b/i,
|
|
82
|
+
/\biPhone\b/i,
|
|
83
|
+
/\biPod\b/i,
|
|
84
|
+
/\bWindows Phone\b/i,
|
|
85
|
+
/\bIEMobile\b/i,
|
|
86
|
+
/\bBlackBerry\b/i,
|
|
87
|
+
/\bBB10\b/i,
|
|
88
|
+
/\bOpera Mini\b/i,
|
|
89
|
+
/\bOpera Mobi\b/i,
|
|
90
|
+
/\bwebOS\b/i
|
|
91
|
+
]);
|
|
92
|
+
const isAndroidTablet = isAndroid && !/\bMobile\b/i.test(userAgent);
|
|
93
|
+
const isTablet = isIPadOS || isTabletByUa || isAndroidTablet;
|
|
94
|
+
const isMobile = input.userAgentDataMobile === true || isMobileByUa || isAndroid && !isTablet || isIOS && !isTablet;
|
|
95
|
+
const deviceType = isTablet ? "tablet" : isMobile ? "mobile" : userAgent || platform || isTouch ? "desktop" : "unknown";
|
|
96
|
+
const shouldUseRedirectLogin = deviceType === "mobile" || deviceType === "tablet" || isWeChat;
|
|
97
|
+
return {
|
|
98
|
+
deviceType,
|
|
99
|
+
isAndroid,
|
|
100
|
+
isCoarsePointer,
|
|
101
|
+
isDesktop: deviceType === "desktop",
|
|
102
|
+
isIOS,
|
|
103
|
+
isIPadOS,
|
|
104
|
+
isMobile,
|
|
105
|
+
isStandalone: input.standalone === true,
|
|
106
|
+
isTablet,
|
|
107
|
+
isTouch,
|
|
108
|
+
isWeChat,
|
|
109
|
+
maxTouchPoints,
|
|
110
|
+
platform,
|
|
111
|
+
shouldUseRedirectLogin,
|
|
112
|
+
userAgent
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
31
116
|
// src/hosted-modal.ts
|
|
32
117
|
var SDK_SUPPORTED_LOCALES = [
|
|
33
118
|
"en",
|
|
@@ -239,6 +324,15 @@ function getOrigin(value) {
|
|
|
239
324
|
return null;
|
|
240
325
|
}
|
|
241
326
|
}
|
|
327
|
+
function isValidLoginRedirectUrl(value) {
|
|
328
|
+
if (!value) return false;
|
|
329
|
+
try {
|
|
330
|
+
const url = new URL(value);
|
|
331
|
+
return url.protocol === "https:" || url.protocol === "http:";
|
|
332
|
+
} catch {
|
|
333
|
+
return false;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
242
336
|
function createLoginCallbackState() {
|
|
243
337
|
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
244
338
|
return crypto.randomUUID().replace(/-/g, "");
|
|
@@ -585,6 +679,24 @@ function applyLoginPanelStyle(panel) {
|
|
|
585
679
|
backdropFilter: "blur(16px)"
|
|
586
680
|
});
|
|
587
681
|
}
|
|
682
|
+
function applyLoginLoadingPanelStyle(panel) {
|
|
683
|
+
Object.assign(panel.style, {
|
|
684
|
+
position: "absolute",
|
|
685
|
+
inset: "0",
|
|
686
|
+
display: "flex",
|
|
687
|
+
alignItems: "center",
|
|
688
|
+
justifyContent: "center",
|
|
689
|
+
border: "0",
|
|
690
|
+
borderRadius: "28px",
|
|
691
|
+
background: "rgba(255,255,255,0.94)",
|
|
692
|
+
color: "#0f172a",
|
|
693
|
+
padding: "24px",
|
|
694
|
+
textAlign: "center",
|
|
695
|
+
zIndex: "1",
|
|
696
|
+
boxShadow: "none",
|
|
697
|
+
backdropFilter: "blur(16px)"
|
|
698
|
+
});
|
|
699
|
+
}
|
|
588
700
|
function createLoginPanelContent() {
|
|
589
701
|
const content = document.createElement("div");
|
|
590
702
|
Object.assign(content.style, {
|
|
@@ -609,6 +721,71 @@ function createLoginPanelContent() {
|
|
|
609
721
|
content.appendChild(badge);
|
|
610
722
|
return content;
|
|
611
723
|
}
|
|
724
|
+
function createBrandLoadingMark() {
|
|
725
|
+
const logo = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
726
|
+
logo.setAttribute("viewBox", "0 0 1024 1024");
|
|
727
|
+
logo.setAttribute("fill", "none");
|
|
728
|
+
logo.setAttribute("aria-hidden", "true");
|
|
729
|
+
Object.assign(logo.style, {
|
|
730
|
+
width: "112px",
|
|
731
|
+
height: "112px",
|
|
732
|
+
color: "#22c55e",
|
|
733
|
+
display: "block",
|
|
734
|
+
overflow: "visible"
|
|
735
|
+
});
|
|
736
|
+
const group = document.createElementNS("http://www.w3.org/2000/svg", "g");
|
|
737
|
+
group.setAttribute("fill", "currentColor");
|
|
738
|
+
const ring = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
739
|
+
ring.setAttribute(
|
|
740
|
+
"d",
|
|
741
|
+
"M704.298 679.54A264 264 0 1 1 704.298 309.46A49 49 0 0 1 634.4 378.149A166 166 0 1 0 634.4 610.851A49 49 0 0 1 704.298 679.54Z"
|
|
742
|
+
);
|
|
743
|
+
ring.setAttribute("class", "youidian-sdk-brand-loading__ring");
|
|
744
|
+
const dot = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
|
745
|
+
dot.setAttribute("class", "youidian-sdk-brand-loading__dot");
|
|
746
|
+
dot.setAttribute("cx", "714.5");
|
|
747
|
+
dot.setAttribute("cy", "490.5");
|
|
748
|
+
dot.setAttribute("r", "68");
|
|
749
|
+
group.appendChild(ring);
|
|
750
|
+
group.appendChild(dot);
|
|
751
|
+
logo.appendChild(group);
|
|
752
|
+
return logo;
|
|
753
|
+
}
|
|
754
|
+
function createBrandLoadingCopy() {
|
|
755
|
+
const brand = document.createElement("div");
|
|
756
|
+
brand.className = "youidian-sdk-brand-loading__copy";
|
|
757
|
+
Object.assign(brand.style, {
|
|
758
|
+
display: "flex",
|
|
759
|
+
flexDirection: "column",
|
|
760
|
+
alignItems: "flex-start",
|
|
761
|
+
justifyContent: "center",
|
|
762
|
+
lineHeight: "1"
|
|
763
|
+
});
|
|
764
|
+
const name = document.createElement("div");
|
|
765
|
+
name.className = "youidian-sdk-brand-loading__name";
|
|
766
|
+
name.textContent = "\u4F18\u6613\u70B9";
|
|
767
|
+
Object.assign(name.style, {
|
|
768
|
+
color: "#0f172a",
|
|
769
|
+
fontSize: "34px",
|
|
770
|
+
fontWeight: "900",
|
|
771
|
+
letterSpacing: "0",
|
|
772
|
+
lineHeight: "1"
|
|
773
|
+
});
|
|
774
|
+
const tagline = document.createElement("div");
|
|
775
|
+
tagline.className = "youidian-sdk-brand-loading__tagline";
|
|
776
|
+
tagline.textContent = "\u5F00\u53D1\u8005\u670D\u52A1\u4E2D\u53F0";
|
|
777
|
+
Object.assign(tagline.style, {
|
|
778
|
+
color: "#64748b",
|
|
779
|
+
fontSize: "16px",
|
|
780
|
+
fontWeight: "700",
|
|
781
|
+
letterSpacing: "0.24em",
|
|
782
|
+
lineHeight: "1",
|
|
783
|
+
marginTop: "6px"
|
|
784
|
+
});
|
|
785
|
+
brand.appendChild(name);
|
|
786
|
+
brand.appendChild(tagline);
|
|
787
|
+
return brand;
|
|
788
|
+
}
|
|
612
789
|
function createLoginPanelTitle(value) {
|
|
613
790
|
const title = document.createElement("div");
|
|
614
791
|
title.textContent = value;
|
|
@@ -638,32 +815,111 @@ function ensureLoginLoadingStyles() {
|
|
|
638
815
|
}
|
|
639
816
|
const style = document.createElement("style");
|
|
640
817
|
style.id = "youidian-login-loading-style";
|
|
641
|
-
style.textContent =
|
|
818
|
+
style.textContent = `
|
|
819
|
+
.youidian-sdk-brand-loading__ring,
|
|
820
|
+
.youidian-sdk-brand-loading__dot {
|
|
821
|
+
transform-box: fill-box;
|
|
822
|
+
transform-origin: center;
|
|
823
|
+
will-change: opacity, transform;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
.youidian-sdk-brand-loading__ring {
|
|
827
|
+
animation: youidian-sdk-brand-loading-ring 1400ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
.youidian-sdk-brand-loading__dot {
|
|
831
|
+
animation: youidian-sdk-brand-loading-dot 1400ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
.youidian-sdk-brand-loading__copy {
|
|
835
|
+
will-change: opacity, transform;
|
|
836
|
+
animation: youidian-sdk-brand-loading-copy 1600ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
.youidian-sdk-brand-loading__tagline {
|
|
840
|
+
will-change: opacity;
|
|
841
|
+
animation: youidian-sdk-brand-loading-tagline 1600ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
@keyframes youidian-sdk-brand-loading-ring {
|
|
845
|
+
0%,
|
|
846
|
+
100% {
|
|
847
|
+
opacity: 0.72;
|
|
848
|
+
transform: rotate(0deg) scale(0.98);
|
|
849
|
+
}
|
|
850
|
+
50% {
|
|
851
|
+
opacity: 1;
|
|
852
|
+
transform: rotate(8deg) scale(1.02);
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
@keyframes youidian-sdk-brand-loading-dot {
|
|
857
|
+
0%,
|
|
858
|
+
100% {
|
|
859
|
+
opacity: 0.55;
|
|
860
|
+
transform: scale(0.9);
|
|
861
|
+
}
|
|
862
|
+
50% {
|
|
863
|
+
opacity: 1;
|
|
864
|
+
transform: scale(1.08);
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
@keyframes youidian-sdk-brand-loading-copy {
|
|
869
|
+
0%,
|
|
870
|
+
100% {
|
|
871
|
+
opacity: 0.86;
|
|
872
|
+
transform: translateY(0);
|
|
873
|
+
}
|
|
874
|
+
50% {
|
|
875
|
+
opacity: 1;
|
|
876
|
+
transform: translateY(-1px);
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
@keyframes youidian-sdk-brand-loading-tagline {
|
|
881
|
+
0%,
|
|
882
|
+
100% {
|
|
883
|
+
opacity: 0.64;
|
|
884
|
+
}
|
|
885
|
+
50% {
|
|
886
|
+
opacity: 0.92;
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
@media (prefers-reduced-motion: reduce) {
|
|
891
|
+
.youidian-sdk-brand-loading__ring,
|
|
892
|
+
.youidian-sdk-brand-loading__dot,
|
|
893
|
+
.youidian-sdk-brand-loading__copy,
|
|
894
|
+
.youidian-sdk-brand-loading__tagline {
|
|
895
|
+
animation: none;
|
|
896
|
+
opacity: 1;
|
|
897
|
+
transform: none;
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
`;
|
|
642
901
|
document.head.appendChild(style);
|
|
643
902
|
}
|
|
644
|
-
function createLoginLoadingPanel(
|
|
903
|
+
function createLoginLoadingPanel() {
|
|
645
904
|
ensureLoginLoadingStyles();
|
|
646
905
|
const panel = document.createElement("div");
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
margin: "0 auto 18px",
|
|
657
|
-
animation: "youidian-login-spin 780ms linear infinite"
|
|
906
|
+
applyLoginLoadingPanelStyle(panel);
|
|
907
|
+
panel.setAttribute("role", "status");
|
|
908
|
+
panel.setAttribute("aria-label", "\u4F18\u6613\u70B9\u5F00\u53D1\u8005\u670D\u52A1\u4E2D\u53F0");
|
|
909
|
+
const content = document.createElement("div");
|
|
910
|
+
Object.assign(content.style, {
|
|
911
|
+
display: "flex",
|
|
912
|
+
alignItems: "center",
|
|
913
|
+
justifyContent: "center",
|
|
914
|
+
gap: "12px"
|
|
658
915
|
});
|
|
659
|
-
content.appendChild(
|
|
660
|
-
content.appendChild(
|
|
661
|
-
content.appendChild(createLoginPanelDescription(options.description));
|
|
916
|
+
content.appendChild(createBrandLoadingMark());
|
|
917
|
+
content.appendChild(createBrandLoadingCopy());
|
|
662
918
|
panel.appendChild(content);
|
|
663
919
|
return panel;
|
|
664
920
|
}
|
|
665
|
-
function createLoginRedirectingPanel(
|
|
666
|
-
return createLoginLoadingPanel(
|
|
921
|
+
function createLoginRedirectingPanel(_options) {
|
|
922
|
+
return createLoginLoadingPanel();
|
|
667
923
|
}
|
|
668
924
|
function createLoginFallbackPanel(options) {
|
|
669
925
|
const panel = document.createElement("div");
|
|
@@ -763,14 +1019,11 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
763
1019
|
this.iframeFallbackPanel = null;
|
|
764
1020
|
this.iframeLoadingPanel = null;
|
|
765
1021
|
}
|
|
766
|
-
showIframeLoading(container
|
|
1022
|
+
showIframeLoading(container) {
|
|
767
1023
|
if (this.iframeLoadingPanel || this.iframeReady) {
|
|
768
1024
|
return;
|
|
769
1025
|
}
|
|
770
|
-
const panel = createLoginLoadingPanel(
|
|
771
|
-
description: options?.loadingDescription || "Please wait while the secure login page opens.",
|
|
772
|
-
title: options?.loadingTitle || "Opening login page"
|
|
773
|
-
});
|
|
1026
|
+
const panel = createLoginLoadingPanel();
|
|
774
1027
|
this.iframeLoadingPanel = panel;
|
|
775
1028
|
container.appendChild(panel);
|
|
776
1029
|
}
|
|
@@ -858,6 +1111,20 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
858
1111
|
break;
|
|
859
1112
|
case "LOGIN_RESIZE":
|
|
860
1113
|
break;
|
|
1114
|
+
case "LOGIN_REDIRECT_REQUIRED":
|
|
1115
|
+
if (!isValidLoginRedirectUrl(data.authUrl)) {
|
|
1116
|
+
logLoginWarn("Login redirect requested with invalid authUrl");
|
|
1117
|
+
options?.onError?.("Login redirect URL is invalid", data);
|
|
1118
|
+
break;
|
|
1119
|
+
}
|
|
1120
|
+
logLoginInfo("Login redirect requested by hosted page", {
|
|
1121
|
+
attemptId: data.attemptId || null,
|
|
1122
|
+
channel: data.channel || null,
|
|
1123
|
+
authUrl: data.authUrl
|
|
1124
|
+
});
|
|
1125
|
+
this.close();
|
|
1126
|
+
window.location.assign(data.authUrl);
|
|
1127
|
+
break;
|
|
861
1128
|
case "LOGIN_ERROR":
|
|
862
1129
|
if (this.completed) {
|
|
863
1130
|
break;
|
|
@@ -881,6 +1148,25 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
881
1148
|
break;
|
|
882
1149
|
}
|
|
883
1150
|
}
|
|
1151
|
+
openLoginRedirect(params, options) {
|
|
1152
|
+
if (typeof window === "undefined") return;
|
|
1153
|
+
const { callbackState, finalUrl, launchPayload } = this.buildOpenContext(
|
|
1154
|
+
params,
|
|
1155
|
+
options
|
|
1156
|
+
);
|
|
1157
|
+
logLoginInfo("Redirecting to hosted login page", {
|
|
1158
|
+
appId: params.appId,
|
|
1159
|
+
callbackState,
|
|
1160
|
+
callbackUrl: launchPayload.callbackUrl || null,
|
|
1161
|
+
hasCallbackUrl: Boolean(launchPayload.callbackUrl),
|
|
1162
|
+
loginUrl: finalUrl,
|
|
1163
|
+
autoClose: options?.autoClose ?? true,
|
|
1164
|
+
displayMode: "redirect",
|
|
1165
|
+
pageUrl: window.location.href,
|
|
1166
|
+
parentOrigin: launchPayload.origin || null
|
|
1167
|
+
});
|
|
1168
|
+
window.location.assign(finalUrl);
|
|
1169
|
+
}
|
|
884
1170
|
listenForLoginCallback(callbackState, options) {
|
|
885
1171
|
try {
|
|
886
1172
|
this.callbackChannel = new BroadcastChannel(
|
|
@@ -957,21 +1243,17 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
957
1243
|
options?.onCancel?.();
|
|
958
1244
|
options?.onClose?.();
|
|
959
1245
|
},
|
|
960
|
-
onMessage: (data,
|
|
1246
|
+
onMessage: (data, _container, event) => {
|
|
961
1247
|
const isIframeEvent = event.source === this.iframe?.contentWindow;
|
|
962
1248
|
if (isIframeEvent && (data.type === "LOGIN_READY" || data.type === "LOGIN_RESIZE") || data.type === "LOGIN_SUCCESS" || data.type === "LOGIN_ERROR") {
|
|
963
1249
|
this.markIframeReady();
|
|
964
1250
|
}
|
|
965
|
-
if (data.type === "LOGIN_RESIZE" && data.height) {
|
|
966
|
-
const maxHeight = window.innerHeight * 0.94;
|
|
967
|
-
container.style.height = `${Math.min(data.height, maxHeight)}px`;
|
|
968
|
-
}
|
|
969
1251
|
this.handleLoginEvent(data, options);
|
|
970
1252
|
},
|
|
971
1253
|
width: "min(520px, 100%)"
|
|
972
1254
|
});
|
|
973
1255
|
if (hostedFrame) {
|
|
974
|
-
this.showIframeLoading(hostedFrame.container
|
|
1256
|
+
this.showIframeLoading(hostedFrame.container);
|
|
975
1257
|
this.startIframeWatchdog({
|
|
976
1258
|
container: hostedFrame.container,
|
|
977
1259
|
finalUrl,
|
|
@@ -1075,11 +1357,19 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
1075
1357
|
}
|
|
1076
1358
|
openLogin(params, options) {
|
|
1077
1359
|
if (typeof window === "undefined") return;
|
|
1078
|
-
const displayMode = options?.displayMode ?? "
|
|
1360
|
+
const displayMode = options?.displayMode ?? "auto";
|
|
1361
|
+
if (displayMode === "redirect") {
|
|
1362
|
+
this.openLoginRedirect(params, options);
|
|
1363
|
+
return;
|
|
1364
|
+
}
|
|
1079
1365
|
if (displayMode === "popup") {
|
|
1080
1366
|
this.openLoginPopup(params, options);
|
|
1081
1367
|
return;
|
|
1082
1368
|
}
|
|
1369
|
+
if (displayMode === "auto" && detectLoginEnvironment().shouldUseRedirectLogin) {
|
|
1370
|
+
this.openLoginRedirect(params, options);
|
|
1371
|
+
return;
|
|
1372
|
+
}
|
|
1083
1373
|
this.openLoginModal(params, options);
|
|
1084
1374
|
}
|
|
1085
1375
|
};
|