@lovable.dev/cloud-auth-js 1.0.1 → 1.1.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.cjs CHANGED
@@ -29,6 +29,7 @@ var EXPECTED_MESSAGE_TYPE = "authorization_response";
29
29
  var DEFAULT_OAUTH_BROKER_URL = "/~oauth/initiate";
30
30
  var DEFAULT_SUPPORTED_OAUTH_ORIGINS = ["https://oauth.lovable.app", "https://lovable.dev"];
31
31
  var DEFAULT_MOBILE_DEEP_LINK_REDIRECT_URI = "lovable://oauth-callback";
32
+ var DEFAULT_DESKTOP_LOCALHOST_REDIRECT_URI = "http://127.0.0.1/iframe-oauth/callback";
32
33
  var POPUP_CHECK_INTERVAL_MS = 500;
33
34
  var IFRAME_FALLBACK_TIMEOUT_MS = 12e4;
34
35
  function startWebMessageListener(supportedOrigins) {
@@ -87,6 +88,14 @@ function processOAuthResponse(data, expectedState) {
87
88
  error: null
88
89
  };
89
90
  }
91
+ function isDevice() {
92
+ const ua = navigator.userAgent;
93
+ if (/iPhone|iPad|iPod|Android/i.test(ua))
94
+ return true;
95
+ if (/Macintosh/i.test(ua) && navigator.maxTouchPoints > 1)
96
+ return true;
97
+ return false;
98
+ }
90
99
  function generateState() {
91
100
  if (typeof crypto !== "undefined" && crypto.getRandomValues) {
92
101
  return [...crypto.getRandomValues(new Uint8Array(16))].map((b) => b.toString(16).padStart(2, "0")).join("");
@@ -104,10 +113,15 @@ function createAuth(config = {}) {
104
113
  isInIframe = true;
105
114
  }
106
115
  const ua = navigator.userAgent;
107
- const isMobile = /iPhone|iPad|iPod|Android/i.test(ua);
108
116
  const isMobileApp = /LovableApp\//.test(ua);
117
+ const isDesktopApp = !isMobileApp && /lovable/i.test(ua);
109
118
  const state = generateState();
110
- const redirectUri = isMobileApp && isInIframe ? DEFAULT_MOBILE_DEEP_LINK_REDIRECT_URI : opts.redirect_uri ?? window.location.origin;
119
+ let redirectUri = opts.redirect_uri ?? window.location.origin;
120
+ if (isMobileApp && isInIframe) {
121
+ redirectUri = DEFAULT_MOBILE_DEEP_LINK_REDIRECT_URI;
122
+ } else if (isDesktopApp && isInIframe) {
123
+ redirectUri = DEFAULT_DESKTOP_LOCALHOST_REDIRECT_URI;
124
+ }
111
125
  const params = new URLSearchParams({
112
126
  ...opts.extraParams,
113
127
  provider,
@@ -118,19 +132,20 @@ function createAuth(config = {}) {
118
132
  window.location.href = `${oauthBrokerUrl}?${params.toString()}`;
119
133
  return { error: null, redirected: true };
120
134
  }
121
- if (!isMobileApp) {
135
+ if (!isMobileApp && !isDesktopApp) {
122
136
  params.set("response_mode", "web_message");
123
137
  }
124
138
  const url = `${oauthBrokerUrl}?${params.toString()}`;
125
- const { messagePromise, cleanup } = startWebMessageListener(supportedOAuthOrigins);
139
+ const effectiveOrigins = isDesktopApp ? [...supportedOAuthOrigins, window.location.origin] : supportedOAuthOrigins;
140
+ const { messagePromise, cleanup } = startWebMessageListener(effectiveOrigins);
126
141
  let popup;
127
- if (isMobile) {
142
+ if (isDevice()) {
128
143
  popup = window.open(url, "_blank");
129
144
  } else {
130
145
  const { width, height, left, top } = getPopupDimensions(isInIframe);
131
146
  popup = window.open(url, "oauth", `width=${width},height=${height},left=${left},top=${top}`);
132
147
  }
133
- if (!popup && isMobileApp) {
148
+ if (!popup && (isMobileApp || isDesktopApp)) {
134
149
  let webViewTimeoutId;
135
150
  const webViewTimeoutPromise = new Promise((_, reject) => {
136
151
  webViewTimeoutId = setTimeout(() => {
@@ -179,7 +194,46 @@ function createAuth(config = {}) {
179
194
  };
180
195
  }
181
196
 
197
+ // package.json
198
+ var package_default = {
199
+ name: "@lovable.dev/cloud-auth-js",
200
+ version: "1.1.1",
201
+ description: "Lovable Cloud Auth JS",
202
+ main: "./dist/index.cjs",
203
+ module: "./dist/index.js",
204
+ types: "./dist/index.d.ts",
205
+ type: "module",
206
+ files: [
207
+ "dist"
208
+ ],
209
+ scripts: {
210
+ build: "tsup src/index.ts --format cjs,esm --dts --outDir dist",
211
+ dev: "tsup src/index.ts --format cjs,esm --dts --watch",
212
+ test: "vitest run",
213
+ typecheck: "tsgo --noEmit",
214
+ prepublishOnly: "npm run clean && npm run build",
215
+ clean: "rimraf dist"
216
+ },
217
+ keywords: [
218
+ "lovable",
219
+ "oauth",
220
+ "authentication"
221
+ ],
222
+ license: "MIT",
223
+ devDependencies: {
224
+ "@types/node": "^22",
225
+ jsdom: "^26",
226
+ rimraf: "^5.0.0",
227
+ tsup: "^7.2.0",
228
+ typescript: "^5",
229
+ vitest: "^4.1.0"
230
+ }
231
+ };
232
+
182
233
  // src/index.ts
234
+ if (typeof window !== "undefined") {
235
+ window.__lovable_cloud_auth_js_version = package_default.version;
236
+ }
183
237
  function createLovableAuth(config = {}) {
184
238
  return createAuth(config);
185
239
  }
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ var EXPECTED_MESSAGE_TYPE = "authorization_response";
3
3
  var DEFAULT_OAUTH_BROKER_URL = "/~oauth/initiate";
4
4
  var DEFAULT_SUPPORTED_OAUTH_ORIGINS = ["https://oauth.lovable.app", "https://lovable.dev"];
5
5
  var DEFAULT_MOBILE_DEEP_LINK_REDIRECT_URI = "lovable://oauth-callback";
6
+ var DEFAULT_DESKTOP_LOCALHOST_REDIRECT_URI = "http://127.0.0.1/iframe-oauth/callback";
6
7
  var POPUP_CHECK_INTERVAL_MS = 500;
7
8
  var IFRAME_FALLBACK_TIMEOUT_MS = 12e4;
8
9
  function startWebMessageListener(supportedOrigins) {
@@ -61,6 +62,14 @@ function processOAuthResponse(data, expectedState) {
61
62
  error: null
62
63
  };
63
64
  }
65
+ function isDevice() {
66
+ const ua = navigator.userAgent;
67
+ if (/iPhone|iPad|iPod|Android/i.test(ua))
68
+ return true;
69
+ if (/Macintosh/i.test(ua) && navigator.maxTouchPoints > 1)
70
+ return true;
71
+ return false;
72
+ }
64
73
  function generateState() {
65
74
  if (typeof crypto !== "undefined" && crypto.getRandomValues) {
66
75
  return [...crypto.getRandomValues(new Uint8Array(16))].map((b) => b.toString(16).padStart(2, "0")).join("");
@@ -78,10 +87,15 @@ function createAuth(config = {}) {
78
87
  isInIframe = true;
79
88
  }
80
89
  const ua = navigator.userAgent;
81
- const isMobile = /iPhone|iPad|iPod|Android/i.test(ua);
82
90
  const isMobileApp = /LovableApp\//.test(ua);
91
+ const isDesktopApp = !isMobileApp && /lovable/i.test(ua);
83
92
  const state = generateState();
84
- const redirectUri = isMobileApp && isInIframe ? DEFAULT_MOBILE_DEEP_LINK_REDIRECT_URI : opts.redirect_uri ?? window.location.origin;
93
+ let redirectUri = opts.redirect_uri ?? window.location.origin;
94
+ if (isMobileApp && isInIframe) {
95
+ redirectUri = DEFAULT_MOBILE_DEEP_LINK_REDIRECT_URI;
96
+ } else if (isDesktopApp && isInIframe) {
97
+ redirectUri = DEFAULT_DESKTOP_LOCALHOST_REDIRECT_URI;
98
+ }
85
99
  const params = new URLSearchParams({
86
100
  ...opts.extraParams,
87
101
  provider,
@@ -92,19 +106,20 @@ function createAuth(config = {}) {
92
106
  window.location.href = `${oauthBrokerUrl}?${params.toString()}`;
93
107
  return { error: null, redirected: true };
94
108
  }
95
- if (!isMobileApp) {
109
+ if (!isMobileApp && !isDesktopApp) {
96
110
  params.set("response_mode", "web_message");
97
111
  }
98
112
  const url = `${oauthBrokerUrl}?${params.toString()}`;
99
- const { messagePromise, cleanup } = startWebMessageListener(supportedOAuthOrigins);
113
+ const effectiveOrigins = isDesktopApp ? [...supportedOAuthOrigins, window.location.origin] : supportedOAuthOrigins;
114
+ const { messagePromise, cleanup } = startWebMessageListener(effectiveOrigins);
100
115
  let popup;
101
- if (isMobile) {
116
+ if (isDevice()) {
102
117
  popup = window.open(url, "_blank");
103
118
  } else {
104
119
  const { width, height, left, top } = getPopupDimensions(isInIframe);
105
120
  popup = window.open(url, "oauth", `width=${width},height=${height},left=${left},top=${top}`);
106
121
  }
107
- if (!popup && isMobileApp) {
122
+ if (!popup && (isMobileApp || isDesktopApp)) {
108
123
  let webViewTimeoutId;
109
124
  const webViewTimeoutPromise = new Promise((_, reject) => {
110
125
  webViewTimeoutId = setTimeout(() => {
@@ -153,7 +168,46 @@ function createAuth(config = {}) {
153
168
  };
154
169
  }
155
170
 
171
+ // package.json
172
+ var package_default = {
173
+ name: "@lovable.dev/cloud-auth-js",
174
+ version: "1.1.1",
175
+ description: "Lovable Cloud Auth JS",
176
+ main: "./dist/index.cjs",
177
+ module: "./dist/index.js",
178
+ types: "./dist/index.d.ts",
179
+ type: "module",
180
+ files: [
181
+ "dist"
182
+ ],
183
+ scripts: {
184
+ build: "tsup src/index.ts --format cjs,esm --dts --outDir dist",
185
+ dev: "tsup src/index.ts --format cjs,esm --dts --watch",
186
+ test: "vitest run",
187
+ typecheck: "tsgo --noEmit",
188
+ prepublishOnly: "npm run clean && npm run build",
189
+ clean: "rimraf dist"
190
+ },
191
+ keywords: [
192
+ "lovable",
193
+ "oauth",
194
+ "authentication"
195
+ ],
196
+ license: "MIT",
197
+ devDependencies: {
198
+ "@types/node": "^22",
199
+ jsdom: "^26",
200
+ rimraf: "^5.0.0",
201
+ tsup: "^7.2.0",
202
+ typescript: "^5",
203
+ vitest: "^4.1.0"
204
+ }
205
+ };
206
+
156
207
  // src/index.ts
208
+ if (typeof window !== "undefined") {
209
+ window.__lovable_cloud_auth_js_version = package_default.version;
210
+ }
157
211
  function createLovableAuth(config = {}) {
158
212
  return createAuth(config);
159
213
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lovable.dev/cloud-auth-js",
3
- "version": "1.0.1",
3
+ "version": "1.1.1",
4
4
  "description": "Lovable Cloud Auth JS",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",