dexie-cloud-addon 4.3.4 → 4.3.6
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/TODO-SOCIALAUTH.md +1 -1
- package/dist/modern/authentication/handleOAuthCallback.d.ts +0 -4
- package/dist/modern/default-ui/OptionButton.d.ts +0 -4
- package/dist/modern/dexie-cloud-addon.js +69 -119
- package/dist/modern/dexie-cloud-addon.js.map +1 -1
- package/dist/modern/dexie-cloud-addon.min.js +1 -1
- package/dist/modern/dexie-cloud-addon.min.js.map +1 -1
- package/dist/modern/service-worker.js +69 -119
- package/dist/modern/service-worker.js.map +1 -1
- package/dist/modern/service-worker.min.js +1 -1
- package/dist/modern/service-worker.min.js.map +1 -1
- package/dist/modern/types/DXCUserInteraction.d.ts +1 -3
- package/dist/umd/dexie-cloud-addon.js +70 -120
- package/dist/umd/dexie-cloud-addon.js.map +1 -1
- package/dist/umd/dexie-cloud-addon.min.js +1 -1
- package/dist/umd/dexie-cloud-addon.min.js.map +1 -1
- package/dist/umd/service-worker.js +70 -120
- package/dist/umd/service-worker.js.map +1 -1
- package/dist/umd/service-worker.min.js +1 -1
- package/dist/umd/service-worker.min.js.map +1 -1
- package/package.json +1 -1
package/TODO-SOCIALAUTH.md
CHANGED
|
@@ -9,7 +9,7 @@ This feature adds support for OAuth 2.0 social login providers (Google, GitHub,
|
|
|
9
9
|
### Related Files
|
|
10
10
|
|
|
11
11
|
- **Detailed flow diagram**: [oauth_flow.md](oauth_flow.md) - Sequence diagrams and detailed protocol description
|
|
12
|
-
- **Server implementation**:
|
|
12
|
+
- **Server implementation**: See `dexie-cloud-server` repository
|
|
13
13
|
- `src/api/oauth/registerOAuthEndpoints.ts` - OAuth endpoints
|
|
14
14
|
- `src/api/oauth/oauth-helpers.ts` - Provider exchange logic
|
|
15
15
|
- `src/api/registerTokenEndpoint.ts` - Token endpoint (authorization_code grant)
|
|
@@ -26,10 +26,6 @@ export declare function parseOAuthCallback(url?: string): OAuthCallbackParams |
|
|
|
26
26
|
* @returns true if valid, false otherwise
|
|
27
27
|
*/
|
|
28
28
|
export declare function validateOAuthState(receivedState: string): boolean;
|
|
29
|
-
/**
|
|
30
|
-
* Gets the OAuth provider from sessionStorage (for redirect flows).
|
|
31
|
-
*/
|
|
32
|
-
export declare function getStoredOAuthProvider(): string | null;
|
|
33
29
|
/**
|
|
34
30
|
* Cleans up the dxc-auth query parameter from the URL.
|
|
35
31
|
* Call this after successfully handling the callback to clean up the browser URL.
|
|
@@ -8,10 +8,6 @@ export interface OptionButtonProps {
|
|
|
8
8
|
* Generic button component for selectable options.
|
|
9
9
|
* Displays the option's icon and display name.
|
|
10
10
|
*
|
|
11
|
-
* The icon can be:
|
|
12
|
-
* - Inline SVG (iconSvg) - rendered directly with dangerouslySetInnerHTML
|
|
13
|
-
* - Image URL (iconUrl) - rendered as an img tag
|
|
14
|
-
*
|
|
15
11
|
* Style is determined by the styleHint property for branding purposes.
|
|
16
12
|
*/
|
|
17
13
|
export declare function OptionButton({ option, onClick }: OptionButtonProps): h.JSX.Element;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* ==========================================================================
|
|
10
10
|
*
|
|
11
|
-
* Version 4.3.
|
|
11
|
+
* Version 4.3.6, Wed Jan 28 2026
|
|
12
12
|
*
|
|
13
13
|
* https://dexie.org
|
|
14
14
|
*
|
|
@@ -761,73 +761,19 @@ class TokenErrorResponseError extends Error {
|
|
|
761
761
|
}
|
|
762
762
|
}
|
|
763
763
|
|
|
764
|
-
/**
|
|
765
|
-
const
|
|
766
|
-
/** Default SVG icons for built-in OAuth providers */
|
|
767
|
-
const ProviderIcons = {
|
|
768
|
-
google: `<svg viewBox="0 0 24 24" width="20" height="20"><path fill="#4285F4" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"/><path fill="#34A853" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"/><path fill="#FBBC05" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"/><path fill="#EA4335" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"/></svg>`,
|
|
769
|
-
github: `<svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/></svg>`,
|
|
770
|
-
microsoft: `<svg viewBox="0 0 24 24" width="20" height="20"><rect fill="#F25022" x="1" y="1" width="10" height="10"/><rect fill="#00A4EF" x="1" y="13" width="10" height="10"/><rect fill="#7FBA00" x="13" y="1" width="10" height="10"/><rect fill="#FFB900" x="13" y="13" width="10" height="10"/></svg>`,
|
|
771
|
-
apple: `<svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor"><path d="M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.81-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M13 3.5c.73-.83 1.94-1.46 2.94-1.5.13 1.17-.34 2.35-1.04 3.19-.69.85-1.83 1.51-2.95 1.42-.15-1.15.41-2.35 1.05-3.11z"/></svg>`,
|
|
772
|
-
};
|
|
773
|
-
/** Email/envelope icon for OTP option */
|
|
774
|
-
const EmailIcon = `<svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="M22 6L12 13 2 6"/></svg>`;
|
|
775
|
-
/**
|
|
776
|
-
* Fetches SVG content from a URL and caches it.
|
|
777
|
-
* Returns the SVG string or null if fetch fails.
|
|
778
|
-
*/
|
|
779
|
-
function fetchSvgIcon(url) {
|
|
780
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
781
|
-
if (svgCache[url]) {
|
|
782
|
-
return svgCache[url];
|
|
783
|
-
}
|
|
784
|
-
try {
|
|
785
|
-
const res = yield fetch(url);
|
|
786
|
-
if (res.ok) {
|
|
787
|
-
const svg = yield res.text();
|
|
788
|
-
// Validate it looks like SVG
|
|
789
|
-
if (svg.includes('<svg')) {
|
|
790
|
-
svgCache[url] = svg;
|
|
791
|
-
return svg;
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
catch (_a) {
|
|
796
|
-
// Silently fail - will show no icon
|
|
797
|
-
}
|
|
798
|
-
return null;
|
|
799
|
-
});
|
|
800
|
-
}
|
|
764
|
+
/** Email/envelope icon data URL for OTP option */
|
|
765
|
+
const EmailIcon = `data:image/svg+xml;base64,${btoa('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="#666666" stroke-width="2"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="M22 6L12 13 2 6"/></svg>')}`;
|
|
801
766
|
/**
|
|
802
767
|
* Converts an OAuthProviderInfo to a generic DXCOption.
|
|
803
|
-
* Fetches SVG icons from URLs if needed.
|
|
804
768
|
*/
|
|
805
769
|
function providerToOption(provider) {
|
|
806
|
-
return
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
// If provider has iconUrl pointing to SVG, fetch and inline it
|
|
814
|
-
else if ((_a = provider.iconUrl) === null || _a === void 0 ? void 0 : _a.toLowerCase().endsWith('.svg')) {
|
|
815
|
-
const fetched = yield fetchSvgIcon(provider.iconUrl);
|
|
816
|
-
if (fetched) {
|
|
817
|
-
iconSvg = fetched;
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
return {
|
|
821
|
-
name: 'provider',
|
|
822
|
-
value: provider.name,
|
|
823
|
-
displayName: `Continue with ${provider.displayName}`,
|
|
824
|
-
iconSvg,
|
|
825
|
-
// If iconUrl is not SVG, pass it through for img tag rendering
|
|
826
|
-
iconUrl: (!iconSvg && provider.iconUrl) ? provider.iconUrl : undefined,
|
|
827
|
-
// Use provider type as style hint for branding
|
|
828
|
-
styleHint: provider.type,
|
|
829
|
-
};
|
|
830
|
-
});
|
|
770
|
+
return {
|
|
771
|
+
name: 'provider',
|
|
772
|
+
value: provider.name,
|
|
773
|
+
displayName: `Continue with ${provider.displayName}`,
|
|
774
|
+
iconUrl: provider.iconUrl,
|
|
775
|
+
styleHint: provider.type,
|
|
776
|
+
};
|
|
831
777
|
}
|
|
832
778
|
function interactWithUser(userInteraction, req) {
|
|
833
779
|
return new Promise((resolve, reject) => {
|
|
@@ -978,8 +924,8 @@ function confirmLogout(userInteraction, currentUserId, numUnsyncedChanges) {
|
|
|
978
924
|
*/
|
|
979
925
|
function promptForProvider(userInteraction_1, providers_1, otpEnabled_1) {
|
|
980
926
|
return __awaiter(this, arguments, void 0, function* (userInteraction, providers, otpEnabled, title = 'Choose login method', alerts = []) {
|
|
981
|
-
// Convert providers to generic options
|
|
982
|
-
const providerOptions =
|
|
927
|
+
// Convert providers to generic options
|
|
928
|
+
const providerOptions = providers.map(providerToOption);
|
|
983
929
|
// Build the options array
|
|
984
930
|
const options = [...providerOptions];
|
|
985
931
|
// Add OTP option if enabled
|
|
@@ -988,7 +934,7 @@ function promptForProvider(userInteraction_1, providers_1, otpEnabled_1) {
|
|
|
988
934
|
name: 'otp',
|
|
989
935
|
value: 'email',
|
|
990
936
|
displayName: 'Continue with email',
|
|
991
|
-
|
|
937
|
+
iconUrl: EmailIcon,
|
|
992
938
|
styleHint: 'otp',
|
|
993
939
|
});
|
|
994
940
|
}
|
|
@@ -1416,10 +1362,12 @@ function exchangeOAuthCode(options) {
|
|
|
1416
1362
|
mode: 'cors',
|
|
1417
1363
|
});
|
|
1418
1364
|
if (!res.ok) {
|
|
1365
|
+
// Read body once as text to avoid stream consumption issues
|
|
1366
|
+
const bodyText = yield res.text().catch(() => res.statusText);
|
|
1419
1367
|
if (res.status === 400 || res.status === 401) {
|
|
1420
|
-
// Try to parse error response
|
|
1368
|
+
// Try to parse error response as JSON
|
|
1421
1369
|
try {
|
|
1422
|
-
const errorResponse =
|
|
1370
|
+
const errorResponse = JSON.parse(bodyText);
|
|
1423
1371
|
if (errorResponse.type === 'error') {
|
|
1424
1372
|
// Check for specific error codes
|
|
1425
1373
|
if (errorResponse.messageCode === 'INVALID_OTP') {
|
|
@@ -1436,8 +1384,7 @@ function exchangeOAuthCode(options) {
|
|
|
1436
1384
|
// Fall through to generic error
|
|
1437
1385
|
}
|
|
1438
1386
|
}
|
|
1439
|
-
|
|
1440
|
-
throw new OAuthError('provider_error', undefined, `Token exchange failed: ${res.status} ${errorText}`);
|
|
1387
|
+
throw new OAuthError('provider_error', undefined, `Token exchange failed: ${res.status} ${bodyText}`);
|
|
1441
1388
|
}
|
|
1442
1389
|
const response = yield res.json();
|
|
1443
1390
|
if (response.type === 'error') {
|
|
@@ -1543,9 +1490,8 @@ function buildOAuthLoginUrl(options) {
|
|
|
1543
1490
|
* ```
|
|
1544
1491
|
*/
|
|
1545
1492
|
function startOAuthRedirect(options) {
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
sessionStorage.setItem('dexie-cloud-oauth-provider', options.provider);
|
|
1493
|
+
if (typeof window === 'undefined') {
|
|
1494
|
+
throw new Error('OAuth redirect requires a browser environment');
|
|
1549
1495
|
}
|
|
1550
1496
|
const loginUrl = buildOAuthLoginUrl(options);
|
|
1551
1497
|
window.location.href = loginUrl;
|
|
@@ -1597,6 +1543,25 @@ function otpFetchTokenCallback(db) {
|
|
|
1597
1543
|
public_key,
|
|
1598
1544
|
};
|
|
1599
1545
|
}
|
|
1546
|
+
else if ((hints === null || hints === void 0 ? void 0 : hints.grant_type) === 'otp' || (hints === null || hints === void 0 ? void 0 : hints.email)) {
|
|
1547
|
+
// User explicitly requested OTP flow - skip provider selection
|
|
1548
|
+
const email = (hints === null || hints === void 0 ? void 0 : hints.email) || (yield promptForEmail(userInteraction, 'Enter email address'));
|
|
1549
|
+
if (/@demo.local$/.test(email)) {
|
|
1550
|
+
tokenRequest = {
|
|
1551
|
+
demo_user: email,
|
|
1552
|
+
grant_type: 'demo',
|
|
1553
|
+
scopes: ['ACCESS_DB'],
|
|
1554
|
+
public_key
|
|
1555
|
+
};
|
|
1556
|
+
}
|
|
1557
|
+
else {
|
|
1558
|
+
tokenRequest = {
|
|
1559
|
+
email,
|
|
1560
|
+
grant_type: 'otp',
|
|
1561
|
+
scopes: ['ACCESS_DB'],
|
|
1562
|
+
};
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1600
1565
|
else {
|
|
1601
1566
|
// Check for available auth providers (OAuth + OTP)
|
|
1602
1567
|
const socialAuthEnabled = ((_c = db.cloud.options) === null || _c === void 0 ? void 0 : _c.socialAuth) !== false;
|
|
@@ -1632,7 +1597,8 @@ function otpFetchTokenCallback(db) {
|
|
|
1632
1597
|
const res1 = yield fetch(`${url}/token`, {
|
|
1633
1598
|
body: JSON.stringify(tokenRequest),
|
|
1634
1599
|
method: 'post',
|
|
1635
|
-
headers: { 'Content-Type': 'application/json'
|
|
1600
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1601
|
+
mode: 'cors',
|
|
1636
1602
|
});
|
|
1637
1603
|
if (res1.status !== 200) {
|
|
1638
1604
|
const errMsg = yield res1.text();
|
|
@@ -1702,7 +1668,11 @@ function initiateOAuthRedirect(db, provider) {
|
|
|
1702
1668
|
if (!url)
|
|
1703
1669
|
throw new Error(`No database URL given.`);
|
|
1704
1670
|
const redirectUri = ((_b = db.cloud.options) === null || _b === void 0 ? void 0 : _b.oauthRedirectUri) ||
|
|
1705
|
-
(typeof
|
|
1671
|
+
(typeof location !== 'undefined' ? location.href : undefined);
|
|
1672
|
+
// CodeRabbit suggested to fail fast here, but the only situation where
|
|
1673
|
+
// redirectUri would be undefined is in non-browser environments, and
|
|
1674
|
+
// in those environments OAuth redirect does not make sense anyway
|
|
1675
|
+
// and will fail fast in startOAuthRedirect().
|
|
1706
1676
|
// Start OAuth redirect flow - page navigates away
|
|
1707
1677
|
startOAuthRedirect({
|
|
1708
1678
|
databaseUrl: url,
|
|
@@ -5817,13 +5787,13 @@ const Styles = {
|
|
|
5817
5787
|
color: "#3c4043"
|
|
5818
5788
|
},
|
|
5819
5789
|
ProviderGitHub: {
|
|
5820
|
-
backgroundColor: "#
|
|
5821
|
-
border: "1px solid #
|
|
5822
|
-
color: "#
|
|
5790
|
+
backgroundColor: "#ffffff",
|
|
5791
|
+
border: "1px solid #dadce0",
|
|
5792
|
+
color: "#181717"
|
|
5823
5793
|
},
|
|
5824
5794
|
ProviderMicrosoft: {
|
|
5825
5795
|
backgroundColor: "#ffffff",
|
|
5826
|
-
border: "1px solid #
|
|
5796
|
+
border: "1px solid #dadce0",
|
|
5827
5797
|
color: "#5e5e5e"
|
|
5828
5798
|
},
|
|
5829
5799
|
ProviderApple: {
|
|
@@ -5832,9 +5802,9 @@ const Styles = {
|
|
|
5832
5802
|
color: "#ffffff"
|
|
5833
5803
|
},
|
|
5834
5804
|
ProviderCustom: {
|
|
5835
|
-
backgroundColor: "#
|
|
5836
|
-
border: "1px solid #
|
|
5837
|
-
color: "#
|
|
5805
|
+
backgroundColor: "#ffffff",
|
|
5806
|
+
border: "1px solid #dadce0",
|
|
5807
|
+
color: "#181717"
|
|
5838
5808
|
},
|
|
5839
5809
|
// Divider styles
|
|
5840
5810
|
Divider: {
|
|
@@ -5925,39 +5895,13 @@ function getOptionStyle(styleHint) {
|
|
|
5925
5895
|
* Generic button component for selectable options.
|
|
5926
5896
|
* Displays the option's icon and display name.
|
|
5927
5897
|
*
|
|
5928
|
-
* The icon can be:
|
|
5929
|
-
* - Inline SVG (iconSvg) - rendered directly with dangerouslySetInnerHTML
|
|
5930
|
-
* - Image URL (iconUrl) - rendered as an img tag
|
|
5931
|
-
*
|
|
5932
5898
|
* Style is determined by the styleHint property for branding purposes.
|
|
5933
5899
|
*/
|
|
5934
5900
|
function OptionButton({ option, onClick }) {
|
|
5935
|
-
const { displayName, iconUrl,
|
|
5901
|
+
const { displayName, iconUrl, styleHint } = option;
|
|
5936
5902
|
const style = getOptionStyle(styleHint);
|
|
5937
|
-
// Get the text color from the button style for SVG fill processing
|
|
5938
|
-
const textColor = style.color || '#000000';
|
|
5939
|
-
// Process SVG to replace currentColor with actual text color
|
|
5940
|
-
const processedSvg = iconSvg
|
|
5941
|
-
? iconSvg
|
|
5942
|
-
.replace(/fill="currentColor"/gi, `fill="${textColor}"`)
|
|
5943
|
-
.replace(/fill='currentColor'/gi, `fill='${textColor}'`)
|
|
5944
|
-
.replace(/stroke="currentColor"/gi, `stroke="${textColor}"`)
|
|
5945
|
-
.replace(/stroke='currentColor'/gi, `stroke='${textColor}'`)
|
|
5946
|
-
: null;
|
|
5947
|
-
// Render the appropriate icon
|
|
5948
|
-
const renderIcon = () => {
|
|
5949
|
-
// Inline SVG
|
|
5950
|
-
if (processedSvg) {
|
|
5951
|
-
return (_$1("span", { style: Styles.ProviderButtonIcon, "aria-hidden": "true", dangerouslySetInnerHTML: { __html: processedSvg } }));
|
|
5952
|
-
}
|
|
5953
|
-
// Image URL
|
|
5954
|
-
if (iconUrl) {
|
|
5955
|
-
return (_$1("img", { src: iconUrl, alt: "", style: Styles.ProviderButtonIcon, "aria-hidden": "true" }));
|
|
5956
|
-
}
|
|
5957
|
-
return null;
|
|
5958
|
-
};
|
|
5959
5903
|
return (_$1("button", { type: "button", style: style, onClick: onClick, class: `dxc-option-btn${styleHint ? ` dxc-option-${styleHint}` : ''}`, "aria-label": displayName },
|
|
5960
|
-
|
|
5904
|
+
iconUrl && (_$1("img", { src: iconUrl, alt: "", style: Styles.ProviderButtonIcon, "aria-hidden": "true" })),
|
|
5961
5905
|
_$1("span", { style: Styles.ProviderButtonText }, displayName)));
|
|
5962
5906
|
}
|
|
5963
5907
|
/**
|
|
@@ -6915,7 +6859,7 @@ function dexieCloud(dexie) {
|
|
|
6915
6859
|
const syncComplete = new Subject();
|
|
6916
6860
|
dexie.cloud = {
|
|
6917
6861
|
// @ts-ignore
|
|
6918
|
-
version: "4.3.
|
|
6862
|
+
version: "4.3.6",
|
|
6919
6863
|
options: Object.assign({}, DEFAULT_OPTIONS),
|
|
6920
6864
|
schema: null,
|
|
6921
6865
|
get currentUserId() {
|
|
@@ -7185,12 +7129,18 @@ function dexieCloud(dexie) {
|
|
|
7185
7129
|
pendingOAuthError = null; // Clear pending error
|
|
7186
7130
|
console.debug('[dexie-cloud] Showing OAuth error:', error.message);
|
|
7187
7131
|
// Show alert to user about the OAuth error
|
|
7188
|
-
|
|
7189
|
-
|
|
7190
|
-
|
|
7191
|
-
|
|
7192
|
-
|
|
7193
|
-
|
|
7132
|
+
// Guard so UI errors don't abort initialization
|
|
7133
|
+
try {
|
|
7134
|
+
yield alertUser(db.cloud.userInteraction, 'Authentication Error', {
|
|
7135
|
+
type: 'error',
|
|
7136
|
+
messageCode: 'GENERIC_ERROR',
|
|
7137
|
+
message: error.message,
|
|
7138
|
+
messageParams: { provider: error.provider || 'unknown' }
|
|
7139
|
+
});
|
|
7140
|
+
}
|
|
7141
|
+
catch (uiError) {
|
|
7142
|
+
console.error('[dexie-cloud] Failed to show OAuth error alert:', uiError);
|
|
7143
|
+
}
|
|
7194
7144
|
}
|
|
7195
7145
|
// Process pending OAuth callback if present (from dxc-auth redirect)
|
|
7196
7146
|
if (pendingOAuthCode && !db.cloud.isServiceWorkerDB) {
|
|
@@ -7294,7 +7244,7 @@ function dexieCloud(dexie) {
|
|
|
7294
7244
|
}
|
|
7295
7245
|
}
|
|
7296
7246
|
// @ts-ignore
|
|
7297
|
-
dexieCloud.version = "4.3.
|
|
7247
|
+
dexieCloud.version = "4.3.6";
|
|
7298
7248
|
Dexie.Cloud = dexieCloud;
|
|
7299
7249
|
|
|
7300
7250
|
export { dexieCloud as default, defineYDocTrigger, dexieCloud, getTiedObjectId, getTiedRealmId, resolveText };
|