dexie-cloud-addon 4.2.5 → 4.3.2
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 +274 -0
- package/dist/modern/DexieCloudAPI.d.ts +4 -0
- package/dist/modern/DexieCloudOptions.d.ts +17 -0
- package/dist/modern/authentication/exchangeOAuthCode.d.ts +23 -0
- package/dist/modern/authentication/fetchAuthProviders.d.ts +14 -0
- package/dist/modern/authentication/handleOAuthCallback.d.ts +63 -0
- package/dist/modern/authentication/interactWithUser.d.ts +22 -0
- package/dist/modern/authentication/oauthLogin.d.ts +38 -0
- package/dist/modern/default-ui/AuthProviderButton.d.ts +21 -0
- package/dist/modern/default-ui/LoginDialog.d.ts +30 -2
- package/dist/modern/default-ui/OptionButton.d.ts +21 -0
- package/dist/modern/default-ui/ProviderSelectionDialog.d.ts +7 -0
- package/dist/modern/default-ui/SelectDialog.d.ts +10 -0
- package/dist/modern/dexie-cloud-addon.js +686 -13
- 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.gz +0 -0
- package/dist/modern/dexie-cloud-addon.min.js.map +1 -1
- package/dist/modern/errors/OAuthError.d.ts +10 -0
- package/dist/modern/service-worker.js +686 -13
- 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 +32 -1
- package/dist/umd/DISABLE_SERVICEWORKER_STRATEGY.d.ts +1 -0
- package/dist/umd/DXCWebSocketStatus.d.ts +1 -0
- package/dist/umd/DexieCloudAPI.d.ts +75 -0
- package/dist/umd/DexieCloudOptions.d.ts +27 -0
- package/dist/umd/DexieCloudSyncOptions.d.ts +4 -0
- package/dist/umd/DexieCloudTable.d.ts +18 -0
- package/dist/umd/InvalidLicenseError.d.ts +5 -0
- package/dist/umd/Invite.d.ts +8 -0
- package/dist/umd/PermissionChecker.d.ts +15 -0
- package/dist/umd/TSON.d.ts +17 -0
- package/dist/umd/WSObservable.d.ts +72 -0
- package/dist/umd/associate.d.ts +1 -0
- package/dist/umd/authentication/AuthPersistedContext.d.ts +9 -0
- package/dist/umd/authentication/TokenErrorResponseError.d.ts +10 -0
- package/dist/umd/authentication/TokenExpiredError.d.ts +3 -0
- package/dist/umd/authentication/UNAUTHORIZED_USER.d.ts +2 -0
- package/dist/umd/authentication/authenticate.d.ts +13 -0
- package/dist/umd/authentication/currentUserObservable.d.ts +1 -0
- package/dist/umd/authentication/interactWithUser.d.ts +21 -0
- package/dist/umd/authentication/login.d.ts +3 -0
- package/dist/umd/authentication/logout.d.ts +5 -0
- package/dist/umd/authentication/otpFetchTokenCallback.d.ts +3 -0
- package/dist/umd/authentication/setCurrentUser.d.ts +14 -0
- package/dist/umd/authentication/waitUntil.d.ts +3 -0
- package/dist/umd/computeSyncState.d.ts +4 -0
- package/dist/umd/createSharedValueObservable.d.ts +3 -0
- package/dist/umd/currentUserEmitter.d.ts +3 -0
- package/dist/umd/db/DexieCloudDB.d.ts +61 -0
- package/dist/umd/db/entities/BaseRevisionMapEntry.d.ts +5 -0
- package/dist/umd/db/entities/EntityCommon.d.ts +5 -0
- package/dist/umd/db/entities/GuardedJob.d.ts +5 -0
- package/dist/umd/db/entities/Member.d.ts +19 -0
- package/dist/umd/db/entities/PersistedSyncState.d.ts +22 -0
- package/dist/umd/db/entities/Realm.d.ts +14 -0
- package/dist/umd/db/entities/Role.d.ts +11 -0
- package/dist/umd/db/entities/UserLogin.d.ts +23 -0
- package/dist/umd/default-ui/Dialog.d.ts +5 -0
- package/dist/umd/default-ui/LoginDialog.d.ts +3 -0
- package/dist/umd/default-ui/Styles.d.ts +3 -0
- package/dist/umd/default-ui/index.d.ts +24 -0
- package/dist/umd/define-ydoc-trigger.d.ts +3 -0
- package/dist/umd/dexie-cloud-addon.d.ts +3 -0
- package/dist/umd/dexie-cloud-addon.js +687 -14
- package/dist/umd/dexie-cloud-addon.js.gz +0 -0
- 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.gz +0 -0
- package/dist/umd/dexie-cloud-addon.min.js.map +1 -1
- package/dist/umd/dexie-cloud-client.d.ts +23 -0
- package/dist/umd/errors/HttpError.d.ts +5 -0
- package/dist/umd/extend-dexie-interface.d.ts +23 -0
- package/dist/umd/getGlobalRolesObservable.d.ts +5 -0
- package/dist/umd/getInternalAccessControlObservable.d.ts +12 -0
- package/dist/umd/getInvitesObservable.d.ts +23 -0
- package/dist/umd/getPermissionsLookupObservable.d.ts +16 -0
- package/dist/umd/getTiedRealmId.d.ts +2 -0
- package/dist/umd/helpers/BroadcastedAndLocalEvent.d.ts +8 -0
- package/dist/umd/helpers/CancelToken.d.ts +4 -0
- package/dist/umd/helpers/IS_SERVICE_WORKER.d.ts +1 -0
- package/dist/umd/helpers/SWBroadcastChannel.d.ts +12 -0
- package/dist/umd/helpers/allSettled.d.ts +1 -0
- package/dist/umd/helpers/bulkUpdate.d.ts +4 -0
- package/dist/umd/helpers/computeRealmSetHash.d.ts +2 -0
- package/dist/umd/helpers/date-constants.d.ts +5 -0
- package/dist/umd/helpers/flatten.d.ts +1 -0
- package/dist/umd/helpers/getMutationTable.d.ts +1 -0
- package/dist/umd/helpers/getSyncableTables.d.ts +4 -0
- package/dist/umd/helpers/getTableFromMutationTable.d.ts +1 -0
- package/dist/umd/helpers/makeArray.d.ts +1 -0
- package/dist/umd/helpers/randomString.d.ts +1 -0
- package/dist/umd/helpers/resolveText.d.ts +16 -0
- package/dist/umd/helpers/throwVersionIncrementNeeded.d.ts +1 -0
- package/dist/umd/helpers/visibilityState.d.ts +1 -0
- package/dist/umd/isEagerSyncDisabled.d.ts +2 -0
- package/dist/umd/isFirefox.d.ts +1 -0
- package/dist/umd/isSafari.d.ts +2 -0
- package/dist/umd/mapValueObservable.d.ts +5 -0
- package/dist/umd/mergePermissions.d.ts +2 -0
- package/dist/umd/middleware-helpers/guardedTable.d.ts +11 -0
- package/dist/umd/middleware-helpers/idGenerationHelpers.d.ts +18 -0
- package/dist/umd/middlewares/createIdGenerationMiddleware.d.ts +3 -0
- package/dist/umd/middlewares/createImplicitPropSetterMiddleware.d.ts +3 -0
- package/dist/umd/middlewares/createMutationTrackingMiddleware.d.ts +17 -0
- package/dist/umd/middlewares/outstandingTransaction.d.ts +4 -0
- package/dist/umd/overrideParseStoresSpec.d.ts +4 -0
- package/dist/umd/performInitialSync.d.ts +4 -0
- package/dist/umd/permissions.d.ts +9 -0
- package/dist/umd/prodLog.d.ts +9 -0
- package/dist/umd/service-worker.d.ts +1 -0
- package/dist/umd/service-worker.js +687 -14
- 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/dist/umd/sync/DEXIE_CLOUD_SYNCER_ID.d.ts +1 -0
- package/dist/umd/sync/LocalSyncWorker.d.ts +7 -0
- package/dist/umd/sync/SyncRequiredError.d.ts +3 -0
- package/dist/umd/sync/applyServerChanges.d.ts +3 -0
- package/dist/umd/sync/connectWebSocket.d.ts +2 -0
- package/dist/umd/sync/encodeIdsForServer.d.ts +4 -0
- package/dist/umd/sync/extractRealm.d.ts +2 -0
- package/dist/umd/sync/getLatestRevisionsPerTable.d.ts +6 -0
- package/dist/umd/sync/getTablesToSyncify.d.ts +3 -0
- package/dist/umd/sync/isOnline.d.ts +1 -0
- package/dist/umd/sync/isSyncNeeded.d.ts +2 -0
- package/dist/umd/sync/listClientChanges.d.ts +9 -0
- package/dist/umd/sync/listSyncifiedChanges.d.ts +5 -0
- package/dist/umd/sync/messageConsumerIsReady.d.ts +2 -0
- package/dist/umd/sync/messagesFromServerQueue.d.ts +8 -0
- package/dist/umd/sync/modifyLocalObjectsWithNewUserId.d.ts +4 -0
- package/dist/umd/sync/myId.d.ts +1 -0
- package/dist/umd/sync/numUnsyncedMutations.d.ts +2 -0
- package/dist/umd/sync/old_startSyncingClientChanges.d.ts +39 -0
- package/dist/umd/sync/performGuardedJob.d.ts +2 -0
- package/dist/umd/sync/ratelimit.d.ts +3 -0
- package/dist/umd/sync/registerSyncEvent.d.ts +3 -0
- package/dist/umd/sync/sync.d.ts +15 -0
- package/dist/umd/sync/syncIfPossible.d.ts +5 -0
- package/dist/umd/sync/syncWithServer.d.ts +6 -0
- package/dist/umd/sync/triggerSync.d.ts +2 -0
- package/dist/umd/sync/updateBaseRevs.d.ts +5 -0
- package/dist/umd/types/DXCAlert.d.ts +25 -0
- package/dist/umd/types/DXCInputField.d.ts +11 -0
- package/dist/umd/types/DXCUserInteraction.d.ts +93 -0
- package/dist/umd/types/NewIdOptions.d.ts +3 -0
- package/dist/umd/types/SWMessageEvent.d.ts +3 -0
- package/dist/umd/types/SWSyncEvent.d.ts +4 -0
- package/dist/umd/types/SyncState.d.ts +9 -0
- package/dist/umd/types/TXExpandos.d.ts +11 -0
- package/dist/umd/updateSchemaFromOptions.d.ts +3 -0
- package/dist/umd/userIsActive.d.ts +7 -0
- package/dist/umd/verifyConfig.d.ts +2 -0
- package/dist/umd/verifySchema.d.ts +2 -0
- package/dist/umd/yjs/YDexieCloudSyncState.d.ts +3 -0
- package/dist/umd/yjs/YTable.d.ts +3 -0
- package/dist/umd/yjs/applyYMessages.d.ts +9 -0
- package/dist/umd/yjs/awareness.d.ts +3 -0
- package/dist/umd/yjs/createYClientUpdateObservable.d.ts +4 -0
- package/dist/umd/yjs/createYHandler.d.ts +2 -0
- package/dist/umd/yjs/downloadYDocsFromServer.d.ts +3 -0
- package/dist/umd/yjs/getUpdatesTable.d.ts +3 -0
- package/dist/umd/yjs/listUpdatesSince.d.ts +3 -0
- package/dist/umd/yjs/listYClientMessagesAndStateVector.d.ts +26 -0
- package/dist/umd/yjs/reopenDocSignal.d.ts +10 -0
- package/dist/umd/yjs/updateYSyncStates.d.ts +6 -0
- package/oauth_flow.md +307 -0
- package/package.json +1 -1
package/oauth_flow.md
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
# OAuth Authorization Code Flow for Dexie Cloud SPA Integration
|
|
2
|
+
|
|
3
|
+
## Actors
|
|
4
|
+
|
|
5
|
+
- **SPA** – Customer's frontend application
|
|
6
|
+
- **Dexie Cloud** – Auth broker + database access control
|
|
7
|
+
- **OAuth Provider** – Google, GitHub, Apple, Microsoft, etc.
|
|
8
|
+
|
|
9
|
+
## Preconditions
|
|
10
|
+
|
|
11
|
+
The SPA:
|
|
12
|
+
|
|
13
|
+
- Generates a persistent public/private keypair
|
|
14
|
+
- Private key stored securely in IndexedDB
|
|
15
|
+
- Public key sent later during token exchange
|
|
16
|
+
- Needs two JWTs after login:
|
|
17
|
+
- Access Token (short-lived)
|
|
18
|
+
- Refresh Token (long-lived)
|
|
19
|
+
|
|
20
|
+
Dexie Cloud acts as OAuth broker and manages tenant + identity linkage.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Flow Overview
|
|
25
|
+
|
|
26
|
+
### 1. User Initiates Login
|
|
27
|
+
|
|
28
|
+
User clicks "Login", SPA displays list of providers:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
Google | GitHub | Apple | Microsoft
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
No nonce or PKCE is created yet.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
### 2. User Selects Provider
|
|
39
|
+
|
|
40
|
+
Example: User selects **Google**
|
|
41
|
+
|
|
42
|
+
The client initiates the OAuth flow. There are two ways to do this:
|
|
43
|
+
|
|
44
|
+
#### 2a. Full Page Redirect (Recommended for Web SPAs)
|
|
45
|
+
|
|
46
|
+
```js
|
|
47
|
+
window.location.href = `https://<db>.dexie.cloud/oauth/login/google?redirect_uri=${encodeURIComponent(location.href)}`;
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The `redirect_uri` parameter specifies where Dexie Cloud should redirect after authentication.
|
|
51
|
+
This can be any page in your app - no dedicated callback route is needed.
|
|
52
|
+
|
|
53
|
+
#### 2b. Custom URL Scheme (Capacitor / Native Apps)
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
// Open in system browser or in-app browser
|
|
57
|
+
Browser.open({
|
|
58
|
+
url: `https://<db>.dexie.cloud/oauth/login/google?redirect_uri=${encodeURIComponent('myapp://')}`
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The custom scheme `myapp://` tells Dexie Cloud to redirect back via deep link.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
### 3. Dexie Cloud Prepares OAuth
|
|
67
|
+
|
|
68
|
+
Dexie Cloud receives `/oauth/login/google` and generates:
|
|
69
|
+
|
|
70
|
+
- `state` (anti-CSRF)
|
|
71
|
+
- `code_verifier` (PKCE)
|
|
72
|
+
- `code_challenge` (PKCE)
|
|
73
|
+
|
|
74
|
+
Stores these in the challenges table, then redirects the browser to provider:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
https://accounts.google.com/o/oauth2/v2/auth?
|
|
78
|
+
client_id=...
|
|
79
|
+
redirect_uri=https://<db>.dexie.cloud/oauth/callback/google
|
|
80
|
+
state=STATE
|
|
81
|
+
code_challenge=CHALLENGE
|
|
82
|
+
code_challenge_method=S256
|
|
83
|
+
response_type=code
|
|
84
|
+
scope=openid email profile
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Note: `redirect_uri` points to the **Dexie Cloud server** callback endpoint.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
### 4. Provider Authenticates User
|
|
92
|
+
|
|
93
|
+
Provider authenticates the user and requests consent if needed.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
### 5. Provider Callback to Dexie Cloud
|
|
98
|
+
|
|
99
|
+
Provider redirects back to Dexie Cloud:
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
https://<db>.dexie.cloud/oauth/callback/google?code=CODE&state=STATE
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Dexie Cloud:
|
|
106
|
+
|
|
107
|
+
1. Verifies `state`
|
|
108
|
+
2. Performs token exchange with provider using PKCE
|
|
109
|
+
3. Extracts identity claims (email/id/name/…)
|
|
110
|
+
4. Verifies email is verified
|
|
111
|
+
5. Links identity to tenant/database
|
|
112
|
+
6. Generates a **single-use Dexie Cloud authorization code**
|
|
113
|
+
7. Deletes the OAuth state (one-time use)
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
### 6. Dexie Cloud Delivers Auth Code to Client
|
|
118
|
+
|
|
119
|
+
Dexie Cloud issues an HTTP 302 redirect back to the client with the authorization code.
|
|
120
|
+
The auth data is encapsulated in a single `dxc-auth` query parameter containing base64url-encoded JSON.
|
|
121
|
+
This avoids collisions with the app's own query parameters.
|
|
122
|
+
|
|
123
|
+
#### 6a. Full Page Redirect (Web SPAs)
|
|
124
|
+
|
|
125
|
+
If the client passed an http/https `redirect_uri`, Dexie Cloud redirects:
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
HTTP/1.1 302 Found
|
|
129
|
+
Location: https://myapp.com/?dxc-auth=eyJjb2RlIjoiLi4uIiwicHJvdmlkZXIiOiJnb29nbGUiLCJzdGF0ZSI6Ii4uLiJ9
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
The `dxc-auth` parameter contains base64url-encoded JSON:
|
|
133
|
+
|
|
134
|
+
```json
|
|
135
|
+
{ "code": "DEXIE_AUTH_CODE", "provider": "google", "state": "STATE" }
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Or in case of error:
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{ "error": "Error message", "provider": "google", "state": "STATE" }
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
The app doesn't need a dedicated OAuth callback route - the dexie-cloud client library
|
|
145
|
+
detects and processes the `dxc-auth` parameter on any page load.
|
|
146
|
+
|
|
147
|
+
#### 6b. Custom URL Scheme (Capacitor / Native Apps)
|
|
148
|
+
|
|
149
|
+
If the client passed a `redirect_uri` with a custom scheme (e.g., `myapp://`),
|
|
150
|
+
Dexie Cloud redirects to that URL with the same `dxc-auth` parameter:
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
HTTP/1.1 302 Found
|
|
154
|
+
Location: myapp://?dxc-auth=eyJjb2RlIjoiLi4uIiwicHJvdmlkZXIiOiJnb29nbGUiLCJzdGF0ZSI6Ii4uLiJ9
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
The native app intercepts this deep link and decodes the parameter.
|
|
158
|
+
|
|
159
|
+
#### 6c. Error Case
|
|
160
|
+
|
|
161
|
+
If no valid `redirect_uri` was provided, an error page is displayed
|
|
162
|
+
explaining that the auth flow cannot complete.
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
### 7. Client Receives Authorization Code
|
|
167
|
+
|
|
168
|
+
**For Full Page Redirect (6a):**
|
|
169
|
+
|
|
170
|
+
The `dexie-cloud-addon` library handles OAuth callback detection automatically:
|
|
171
|
+
|
|
172
|
+
1. When `db.cloud.configure()` is called, the addon checks for the `dxc-auth` query parameter
|
|
173
|
+
2. This check only runs in DOM environments (not in Web Workers)
|
|
174
|
+
3. If the parameter is present:
|
|
175
|
+
- The URL is immediately cleaned up using `history.replaceState()` to remove `dxc-auth`
|
|
176
|
+
- A `setTimeout(cb, 0)` is scheduled to initiate the token exchange
|
|
177
|
+
- The token exchange fetches from the configured `databaseUrl`
|
|
178
|
+
- The response is processed in the existing `db.on('ready')` callback when Dexie is ready
|
|
179
|
+
|
|
180
|
+
```js
|
|
181
|
+
// Pseudocode for dexie-cloud-addon implementation
|
|
182
|
+
function configure(options) {
|
|
183
|
+
// Only check in DOM environment, not workers
|
|
184
|
+
if (typeof window !== 'undefined' && window.location) {
|
|
185
|
+
const encoded = new URLSearchParams(location.search).get('dxc-auth');
|
|
186
|
+
if (encoded) {
|
|
187
|
+
// Decode base64url (unpadded) to JSON
|
|
188
|
+
const padded = encoded + '='.repeat((4 - (encoded.length % 4)) % 4);
|
|
189
|
+
const base64 = padded.replace(/-/g, '+').replace(/_/g, '/');
|
|
190
|
+
const payload = JSON.parse(atob(base64));
|
|
191
|
+
const { code, provider, state, error } = payload;
|
|
192
|
+
|
|
193
|
+
// Clean up URL immediately (remove dxc-auth param)
|
|
194
|
+
const url = new URL(location.href);
|
|
195
|
+
url.searchParams.delete('dxc-auth');
|
|
196
|
+
history.replaceState(null, '', url.toString());
|
|
197
|
+
|
|
198
|
+
if (!error) {
|
|
199
|
+
// Schedule token exchange (processed in db.on('ready'))
|
|
200
|
+
setTimeout(() => {
|
|
201
|
+
// Perform token exchange with options.databaseUrl
|
|
202
|
+
}, 0);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**For Capacitor/Native Apps (6b):**
|
|
210
|
+
|
|
211
|
+
App registers a deep link handler and decodes the same parameter:
|
|
212
|
+
|
|
213
|
+
```js
|
|
214
|
+
// Capacitor example
|
|
215
|
+
App.addListener('appUrlOpen', ({ url }) => {
|
|
216
|
+
const parsedUrl = new URL(url);
|
|
217
|
+
const encoded = parsedUrl.searchParams.get('dxc-auth');
|
|
218
|
+
if (encoded) {
|
|
219
|
+
const padded = encoded + '='.repeat((4 - (encoded.length % 4)) % 4);
|
|
220
|
+
const base64 = padded.replace(/-/g, '+').replace(/_/g, '/');
|
|
221
|
+
const payload = JSON.parse(atob(base64));
|
|
222
|
+
const { code, provider, state, error } = payload;
|
|
223
|
+
// Proceed to token exchange
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Upon success, client proceeds to token exchange.
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
### 8. Client Performs Token Exchange
|
|
233
|
+
|
|
234
|
+
Client sends:
|
|
235
|
+
|
|
236
|
+
```http
|
|
237
|
+
POST /token
|
|
238
|
+
Content-Type: application/json
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Payload:
|
|
242
|
+
|
|
243
|
+
```json
|
|
244
|
+
{
|
|
245
|
+
"grant_type": "authorization_code",
|
|
246
|
+
"code": "<DEXIE_AUTH_CODE>",
|
|
247
|
+
"public_key": "<SPA_PUBLIC_KEY>",
|
|
248
|
+
"scopes": ["ACCESS_DB"]
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Dexie Cloud validates:
|
|
253
|
+
|
|
254
|
+
- Dexie authorization code integrity
|
|
255
|
+
- TTL (5 minutes)
|
|
256
|
+
- Single-use constraint
|
|
257
|
+
- Database context
|
|
258
|
+
- User identity and claims from stored data
|
|
259
|
+
- Subscription/license status
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
### 9. Dexie Cloud Issues Tokens
|
|
264
|
+
|
|
265
|
+
Dexie Cloud responds with:
|
|
266
|
+
|
|
267
|
+
```json
|
|
268
|
+
{
|
|
269
|
+
"access_token": "...",
|
|
270
|
+
"refresh_token": "...",
|
|
271
|
+
"expires_in": 3600,
|
|
272
|
+
"token_type": "Bearer"
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
This completes authentication.
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Security Properties Achieved
|
|
281
|
+
|
|
282
|
+
- 🛑 No JWTs exposed via URL fragments
|
|
283
|
+
- 🛑 Provider tokens never reach SPA (only Dexie tokens)
|
|
284
|
+
- 🛡 Single-use Dexie authorization code (5 min TTL)
|
|
285
|
+
- 🛡 PKCE prevents provider code interception
|
|
286
|
+
- 🛡 State stored server-side with TTL (30 min)
|
|
287
|
+
- 🛡 CSRF protection via `state` parameter
|
|
288
|
+
- 🛡 OAuth state deleted after use
|
|
289
|
+
- 🛡 Dexie auth code deleted after use
|
|
290
|
+
- 🛡 Email verification enforced by server
|
|
291
|
+
- 🛡 All provider exchanges happen server-side
|
|
292
|
+
- 🛡 CORS + origin protections during `/token` exchange
|
|
293
|
+
- 🛡 Future PoP (Proof-of-Possession) enabled via SPA public key
|
|
294
|
+
- 🛡 Works with Apple, Google, Microsoft, GitHub
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## Resulting Benefits
|
|
299
|
+
|
|
300
|
+
- Works for SPA / PWA / Capacitor / WebViews
|
|
301
|
+
- Supports multi-tenant architectures
|
|
302
|
+
- Supports native account linking
|
|
303
|
+
- Enables refresh token rotation
|
|
304
|
+
- Supports offline-first/local-first model
|
|
305
|
+
|
|
306
|
+
This aligns with modern OIDC/OAuth best practices (2023+) and matches architectures used by:
|
|
307
|
+
Auth0, Firebase, Supabase, Okta, MSAL, Google Identity Services, Clerk, etc.
|