@lovable.dev/cloud-auth-js 1.2.1 → 1.2.4
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.cjs +30 -2
- package/dist/index.js +30 -2
- package/package.json +2 -2
- package/styles.css +4 -15
package/dist/index.cjs
CHANGED
|
@@ -7,11 +7,26 @@ const DEFAULT_MOBILE_DEEP_LINK_REDIRECT_URI = "lovable://oauth-callback";
|
|
|
7
7
|
const DEFAULT_DESKTOP_LOCALHOST_REDIRECT_URI = "http://127.0.0.1/iframe-oauth/callback";
|
|
8
8
|
const POPUP_CHECK_INTERVAL_MS = 500;
|
|
9
9
|
const IFRAME_FALLBACK_TIMEOUT_MS = 12e4;
|
|
10
|
+
const POPUP_RESULT_TIMEOUT_MS = 3e5;
|
|
10
11
|
const MOBILE_APP_SCHEME_UA_TOKEN = /LovableAppScheme\/([a-z0-9.+-]+)/i;
|
|
11
12
|
function mobileDeepLinkRedirectUri(ua) {
|
|
12
13
|
const scheme = MOBILE_APP_SCHEME_UA_TOKEN.exec(ua)?.[1];
|
|
13
14
|
return scheme ? `${scheme}://oauth-callback` : DEFAULT_MOBILE_DEEP_LINK_REDIRECT_URI;
|
|
14
15
|
}
|
|
16
|
+
function sameOriginRedirectUri(redirectUri) {
|
|
17
|
+
const pageOrigin = window.location.origin;
|
|
18
|
+
if (pageOrigin === "null") return redirectUri;
|
|
19
|
+
let parsed;
|
|
20
|
+
try {
|
|
21
|
+
parsed = new URL(redirectUri, window.location.href);
|
|
22
|
+
} catch {
|
|
23
|
+
return redirectUri;
|
|
24
|
+
}
|
|
25
|
+
if (parsed.origin === pageOrigin) return redirectUri;
|
|
26
|
+
const rewritten = `${pageOrigin}${parsed.pathname}${parsed.search}${parsed.hash}`;
|
|
27
|
+
console.warn(`[cloud-auth-js] redirect_uri origin ${parsed.origin} differs from the page origin ${pageOrigin}; using ${rewritten} so the popup result can reach this window`);
|
|
28
|
+
return rewritten;
|
|
29
|
+
}
|
|
15
30
|
function startWebMessageListener(supportedOrigins) {
|
|
16
31
|
let resolvePromise;
|
|
17
32
|
const promise = new Promise((resolve) => {
|
|
@@ -86,6 +101,8 @@ function createAuth(config = {}) {
|
|
|
86
101
|
let redirectUri = opts.redirect_uri ?? window.location.origin;
|
|
87
102
|
if (isMobileApp && isInIframe) redirectUri = mobileDeepLinkRedirectUri(ua);
|
|
88
103
|
else if (isDesktopApp && isInIframe) redirectUri = DEFAULT_DESKTOP_LOCALHOST_REDIRECT_URI;
|
|
104
|
+
const useWebMessage = isInIframe && !isMobileApp && !isDesktopApp;
|
|
105
|
+
if (useWebMessage) redirectUri = sameOriginRedirectUri(redirectUri);
|
|
89
106
|
const params = new URLSearchParams({
|
|
90
107
|
...opts.extraParams,
|
|
91
108
|
provider,
|
|
@@ -99,7 +116,7 @@ function createAuth(config = {}) {
|
|
|
99
116
|
redirected: true
|
|
100
117
|
};
|
|
101
118
|
}
|
|
102
|
-
if (
|
|
119
|
+
if (useWebMessage) params.set("response_mode", "web_message");
|
|
103
120
|
const url = `${oauthBrokerUrl}?${params.toString()}`;
|
|
104
121
|
const { messagePromise, cleanup } = startWebMessageListener(isDesktopApp ? [...supportedOAuthOrigins, window.location.origin] : supportedOAuthOrigins);
|
|
105
122
|
let popup;
|
|
@@ -137,11 +154,22 @@ function createAuth(config = {}) {
|
|
|
137
154
|
}
|
|
138
155
|
}, POPUP_CHECK_INTERVAL_MS);
|
|
139
156
|
});
|
|
157
|
+
let resultTimeoutId;
|
|
158
|
+
const resultTimeoutPromise = new Promise((_, reject) => {
|
|
159
|
+
resultTimeoutId = setTimeout(() => {
|
|
160
|
+
reject(/* @__PURE__ */ new Error("Sign-in timed out waiting for the sign-in window. If it is still open, finish there, or open the app in a new browser tab to sign in."));
|
|
161
|
+
}, POPUP_RESULT_TIMEOUT_MS);
|
|
162
|
+
});
|
|
140
163
|
try {
|
|
141
|
-
return processOAuthResponse(await Promise.race([
|
|
164
|
+
return processOAuthResponse(await Promise.race([
|
|
165
|
+
messagePromise,
|
|
166
|
+
popupClosedPromise,
|
|
167
|
+
resultTimeoutPromise
|
|
168
|
+
]), state);
|
|
142
169
|
} catch (error) {
|
|
143
170
|
return { error: error instanceof Error ? error : new Error(String(error)) };
|
|
144
171
|
} finally {
|
|
172
|
+
clearTimeout(resultTimeoutId);
|
|
145
173
|
clearInterval(popupCheckInterval);
|
|
146
174
|
cleanup();
|
|
147
175
|
popup?.close();
|
package/dist/index.js
CHANGED
|
@@ -6,11 +6,26 @@ const DEFAULT_MOBILE_DEEP_LINK_REDIRECT_URI = "lovable://oauth-callback";
|
|
|
6
6
|
const DEFAULT_DESKTOP_LOCALHOST_REDIRECT_URI = "http://127.0.0.1/iframe-oauth/callback";
|
|
7
7
|
const POPUP_CHECK_INTERVAL_MS = 500;
|
|
8
8
|
const IFRAME_FALLBACK_TIMEOUT_MS = 12e4;
|
|
9
|
+
const POPUP_RESULT_TIMEOUT_MS = 3e5;
|
|
9
10
|
const MOBILE_APP_SCHEME_UA_TOKEN = /LovableAppScheme\/([a-z0-9.+-]+)/i;
|
|
10
11
|
function mobileDeepLinkRedirectUri(ua) {
|
|
11
12
|
const scheme = MOBILE_APP_SCHEME_UA_TOKEN.exec(ua)?.[1];
|
|
12
13
|
return scheme ? `${scheme}://oauth-callback` : DEFAULT_MOBILE_DEEP_LINK_REDIRECT_URI;
|
|
13
14
|
}
|
|
15
|
+
function sameOriginRedirectUri(redirectUri) {
|
|
16
|
+
const pageOrigin = window.location.origin;
|
|
17
|
+
if (pageOrigin === "null") return redirectUri;
|
|
18
|
+
let parsed;
|
|
19
|
+
try {
|
|
20
|
+
parsed = new URL(redirectUri, window.location.href);
|
|
21
|
+
} catch {
|
|
22
|
+
return redirectUri;
|
|
23
|
+
}
|
|
24
|
+
if (parsed.origin === pageOrigin) return redirectUri;
|
|
25
|
+
const rewritten = `${pageOrigin}${parsed.pathname}${parsed.search}${parsed.hash}`;
|
|
26
|
+
console.warn(`[cloud-auth-js] redirect_uri origin ${parsed.origin} differs from the page origin ${pageOrigin}; using ${rewritten} so the popup result can reach this window`);
|
|
27
|
+
return rewritten;
|
|
28
|
+
}
|
|
14
29
|
function startWebMessageListener(supportedOrigins) {
|
|
15
30
|
let resolvePromise;
|
|
16
31
|
const promise = new Promise((resolve) => {
|
|
@@ -85,6 +100,8 @@ function createAuth(config = {}) {
|
|
|
85
100
|
let redirectUri = opts.redirect_uri ?? window.location.origin;
|
|
86
101
|
if (isMobileApp && isInIframe) redirectUri = mobileDeepLinkRedirectUri(ua);
|
|
87
102
|
else if (isDesktopApp && isInIframe) redirectUri = DEFAULT_DESKTOP_LOCALHOST_REDIRECT_URI;
|
|
103
|
+
const useWebMessage = isInIframe && !isMobileApp && !isDesktopApp;
|
|
104
|
+
if (useWebMessage) redirectUri = sameOriginRedirectUri(redirectUri);
|
|
88
105
|
const params = new URLSearchParams({
|
|
89
106
|
...opts.extraParams,
|
|
90
107
|
provider,
|
|
@@ -98,7 +115,7 @@ function createAuth(config = {}) {
|
|
|
98
115
|
redirected: true
|
|
99
116
|
};
|
|
100
117
|
}
|
|
101
|
-
if (
|
|
118
|
+
if (useWebMessage) params.set("response_mode", "web_message");
|
|
102
119
|
const url = `${oauthBrokerUrl}?${params.toString()}`;
|
|
103
120
|
const { messagePromise, cleanup } = startWebMessageListener(isDesktopApp ? [...supportedOAuthOrigins, window.location.origin] : supportedOAuthOrigins);
|
|
104
121
|
let popup;
|
|
@@ -136,11 +153,22 @@ function createAuth(config = {}) {
|
|
|
136
153
|
}
|
|
137
154
|
}, POPUP_CHECK_INTERVAL_MS);
|
|
138
155
|
});
|
|
156
|
+
let resultTimeoutId;
|
|
157
|
+
const resultTimeoutPromise = new Promise((_, reject) => {
|
|
158
|
+
resultTimeoutId = setTimeout(() => {
|
|
159
|
+
reject(/* @__PURE__ */ new Error("Sign-in timed out waiting for the sign-in window. If it is still open, finish there, or open the app in a new browser tab to sign in."));
|
|
160
|
+
}, POPUP_RESULT_TIMEOUT_MS);
|
|
161
|
+
});
|
|
139
162
|
try {
|
|
140
|
-
return processOAuthResponse(await Promise.race([
|
|
163
|
+
return processOAuthResponse(await Promise.race([
|
|
164
|
+
messagePromise,
|
|
165
|
+
popupClosedPromise,
|
|
166
|
+
resultTimeoutPromise
|
|
167
|
+
]), state);
|
|
141
168
|
} catch (error) {
|
|
142
169
|
return { error: error instanceof Error ? error : new Error(String(error)) };
|
|
143
170
|
} finally {
|
|
171
|
+
clearTimeout(resultTimeoutId);
|
|
144
172
|
clearInterval(popupCheckInterval);
|
|
145
173
|
cleanup();
|
|
146
174
|
popup?.close();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lovable.dev/cloud-auth-js",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.4",
|
|
4
4
|
"description": "Lovable legacy OAuth broker JS",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"check:package": "tmp=$(mktemp -d) && pnpm pack --out \"$tmp/pkg.tgz\" && tar -xzf \"$tmp/pkg.tgz\" -C \"$tmp\" && publint \"$tmp/package\" --strict && attw \"$tmp/pkg.tgz\"",
|
|
56
56
|
"dev": "tsdown --watch",
|
|
57
57
|
"test": "vitest run",
|
|
58
|
-
"typecheck": "
|
|
58
|
+
"typecheck": "tsc --noEmit",
|
|
59
59
|
"clean": "rimraf dist"
|
|
60
60
|
}
|
|
61
61
|
}
|
package/styles.css
CHANGED
|
@@ -1,28 +1,18 @@
|
|
|
1
|
-
/* Camera Plain subset for "Continue", "Sign in", and "Sign up with Lovable". */
|
|
2
|
-
@font-face {
|
|
3
|
-
font-family: "Lovable Camera";
|
|
4
|
-
src: url("data:font/woff2;base64,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")
|
|
5
|
-
format("woff2");
|
|
6
|
-
font-weight: 400;
|
|
7
|
-
font-style: normal;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
1
|
.lovable-auth-button {
|
|
11
|
-
position: relative;
|
|
12
2
|
display: inline-flex;
|
|
13
3
|
min-width: 220px;
|
|
14
4
|
min-height: 44px;
|
|
15
5
|
align-items: center;
|
|
16
6
|
justify-content: center;
|
|
7
|
+
gap: 8px;
|
|
17
8
|
box-sizing: border-box;
|
|
18
|
-
padding: 10px
|
|
9
|
+
padding: 10px 16px;
|
|
19
10
|
border: 1px solid #c5cad3;
|
|
20
11
|
border-radius: 8px;
|
|
21
12
|
appearance: none;
|
|
22
13
|
background: #ffffff;
|
|
23
14
|
color: #000000;
|
|
24
|
-
font-family:
|
|
25
|
-
font-synthesis: none;
|
|
15
|
+
font-family: inherit;
|
|
26
16
|
font-size: 16px;
|
|
27
17
|
font-weight: 400;
|
|
28
18
|
line-height: 22px;
|
|
@@ -31,8 +21,7 @@
|
|
|
31
21
|
}
|
|
32
22
|
|
|
33
23
|
.lovable-auth-button::before {
|
|
34
|
-
|
|
35
|
-
inset-inline-start: 16px;
|
|
24
|
+
flex: none;
|
|
36
25
|
width: 16px;
|
|
37
26
|
height: 17px;
|
|
38
27
|
background: url("./assets/lovable-mark.svg") center / contain no-repeat;
|