@tidecloak/js 0.14.41 → 0.14.43-staging
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/README.md +32 -47
- package/dist/cjs/lib/tidecloak-dpop.js +151 -42
- package/dist/cjs/lib/tidecloak-dpop.js.map +1 -1
- package/dist/cjs/lib/tidecloak.js +300 -378
- package/dist/cjs/lib/tidecloak.js.map +1 -1
- package/dist/cjs/src/AdminAPI.js +12 -19
- package/dist/cjs/src/AdminAPI.js.map +1 -1
- package/dist/cjs/src/IAMService.js +159 -2095
- package/dist/cjs/src/IAMService.js.map +1 -1
- package/dist/cjs/src/index.js +1 -7
- package/dist/cjs/src/index.js.map +1 -1
- package/dist/esm/lib/tidecloak-dpop.js +151 -42
- package/dist/esm/lib/tidecloak-dpop.js.map +1 -1
- package/dist/esm/lib/tidecloak.js +300 -377
- package/dist/esm/lib/tidecloak.js.map +1 -1
- package/dist/esm/src/AdminAPI.js +3 -7
- package/dist/esm/src/AdminAPI.js.map +1 -1
- package/dist/esm/src/IAMService.js +156 -2062
- package/dist/esm/src/IAMService.js.map +1 -1
- package/dist/esm/src/index.js +1 -7
- package/dist/esm/src/index.js.map +1 -1
- package/dist/types/AdminAPI.d.ts +1 -1
- package/dist/types/IAMService.d.ts +57 -606
- package/dist/types/index.d.ts +1 -11
- package/dist/types/lib/tidecloak-dpop.d.ts +19 -3
- package/dist/types/lib/tidecloak.d.ts +46 -38
- package/dist/types/src/AdminAPI.d.ts +1 -1
- package/dist/types/src/IAMService.d.ts +57 -606
- package/dist/types/src/index.d.ts +1 -11
- package/docs/FRONT_CHANNEL.md +55 -55
- package/lib/README.md +10 -14
- package/package.json +4 -25
- package/dist/cjs/lib/secureFetchPolicy.js +0 -45
- package/dist/cjs/lib/secureFetchPolicy.js.map +0 -1
- package/dist/cjs/src/dpopRoute.js +0 -30
- package/dist/cjs/src/dpopRoute.js.map +0 -1
- package/dist/cjs/src/dpopServer.js +0 -77
- package/dist/cjs/src/dpopServer.js.map +0 -1
- package/dist/cjs/src/generated/dpopAuthAsset.js +0 -7
- package/dist/cjs/src/generated/dpopAuthAsset.js.map +0 -1
- package/dist/cjs/src/policy-react.js +0 -51
- package/dist/cjs/src/policy-react.js.map +0 -1
- package/dist/cjs/src/types.js +0 -6
- package/dist/cjs/src/types.js.map +0 -1
- package/dist/cjs/src/utils/dpopAuthPage.js +0 -69
- package/dist/cjs/src/utils/dpopAuthPage.js.map +0 -1
- package/dist/cjs/src/utils/fetch.js +0 -39
- package/dist/cjs/src/utils/fetch.js.map +0 -1
- package/dist/cjs/src/utils/index.js +0 -17
- package/dist/cjs/src/utils/index.js.map +0 -1
- package/dist/cjs/src/utils/initOptions.js +0 -78
- package/dist/cjs/src/utils/initOptions.js.map +0 -1
- package/dist/cjs/src/utils/pkce.js +0 -48
- package/dist/cjs/src/utils/pkce.js.map +0 -1
- package/dist/cjs/src/utils/silentCheckSso.js +0 -138
- package/dist/cjs/src/utils/silentCheckSso.js.map +0 -1
- package/dist/cjs/src/vite.js +0 -43
- package/dist/cjs/src/vite.js.map +0 -1
- package/dist/esm/lib/secureFetchPolicy.js +0 -42
- package/dist/esm/lib/secureFetchPolicy.js.map +0 -1
- package/dist/esm/src/dpopRoute.js +0 -27
- package/dist/esm/src/dpopRoute.js.map +0 -1
- package/dist/esm/src/dpopServer.js +0 -68
- package/dist/esm/src/dpopServer.js.map +0 -1
- package/dist/esm/src/generated/dpopAuthAsset.js +0 -4
- package/dist/esm/src/generated/dpopAuthAsset.js.map +0 -1
- package/dist/esm/src/policy-react.js +0 -45
- package/dist/esm/src/policy-react.js.map +0 -1
- package/dist/esm/src/types.js +0 -5
- package/dist/esm/src/types.js.map +0 -1
- package/dist/esm/src/utils/dpopAuthPage.js +0 -63
- package/dist/esm/src/utils/dpopAuthPage.js.map +0 -1
- package/dist/esm/src/utils/fetch.js +0 -36
- package/dist/esm/src/utils/fetch.js.map +0 -1
- package/dist/esm/src/utils/index.js +0 -6
- package/dist/esm/src/utils/index.js.map +0 -1
- package/dist/esm/src/utils/initOptions.js +0 -75
- package/dist/esm/src/utils/initOptions.js.map +0 -1
- package/dist/esm/src/utils/pkce.js +0 -43
- package/dist/esm/src/utils/pkce.js.map +0 -1
- package/dist/esm/src/utils/silentCheckSso.js +0 -134
- package/dist/esm/src/utils/silentCheckSso.js.map +0 -1
- package/dist/esm/src/vite.js +0 -40
- package/dist/esm/src/vite.js.map +0 -1
- package/dist/types/dpopRoute.d.ts +0 -11
- package/dist/types/dpopServer.d.ts +0 -35
- package/dist/types/generated/dpopAuthAsset.d.ts +0 -2
- package/dist/types/lib/secureFetchPolicy.d.ts +0 -37
- package/dist/types/policy-react.d.ts +0 -40
- package/dist/types/src/dpopRoute.d.ts +0 -11
- package/dist/types/src/dpopServer.d.ts +0 -35
- package/dist/types/src/generated/dpopAuthAsset.d.ts +0 -2
- package/dist/types/src/policy-react.d.ts +0 -40
- package/dist/types/src/types.d.ts +0 -114
- package/dist/types/src/utils/dpopAuthPage.d.ts +0 -22
- package/dist/types/src/utils/fetch.d.ts +0 -11
- package/dist/types/src/utils/index.d.ts +0 -5
- package/dist/types/src/utils/initOptions.d.ts +0 -69
- package/dist/types/src/utils/pkce.d.ts +0 -24
- package/dist/types/src/utils/silentCheckSso.d.ts +0 -82
- package/dist/types/src/vite.d.ts +0 -13
- package/dist/types/types.d.ts +0 -114
- package/dist/types/utils/dpopAuthPage.d.ts +0 -22
- package/dist/types/utils/fetch.d.ts +0 -11
- package/dist/types/utils/index.d.ts +0 -5
- package/dist/types/utils/initOptions.d.ts +0 -69
- package/dist/types/utils/pkce.d.ts +0 -24
- package/dist/types/utils/silentCheckSso.d.ts +0 -82
- package/dist/types/vite.d.ts +0 -13
- package/docs/HYBRID_MODE.md +0 -185
- package/docs/NATIVE_MODE.md +0 -284
package/docs/NATIVE_MODE.md
DELETED
|
@@ -1,284 +0,0 @@
|
|
|
1
|
-
# Native Mode
|
|
2
|
-
|
|
3
|
-
Build desktop and mobile apps with TideCloak. Works with Electron, Tauri, and React Native.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## What You'll Build
|
|
8
|
-
|
|
9
|
-
Your users click "Login" in your app, their browser opens, they log in, and they're back in your app - authenticated and ready to go. Tokens are stored securely on their device.
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Quick Start
|
|
14
|
-
|
|
15
|
-
### 1. Get Your Config File
|
|
16
|
-
|
|
17
|
-
Download `tidecloak.json` (your client adapter config) from your TideCloak admin console. It has all your TideCloak settings.
|
|
18
|
-
|
|
19
|
-
### 2. Create Your Adapter
|
|
20
|
-
|
|
21
|
-
The adapter handles platform-specific stuff - opening login windows, storing tokens. Here's one for Electron:
|
|
22
|
-
|
|
23
|
-
```js
|
|
24
|
-
// electronAdapter.js
|
|
25
|
-
export function createElectronAdapter() {
|
|
26
|
-
return {
|
|
27
|
-
// Where should TideCloak redirect after login?
|
|
28
|
-
getRedirectUri: () => 'myapp://auth/callback',
|
|
29
|
-
|
|
30
|
-
// Open login in a popup window (NOT external browser - see note below)
|
|
31
|
-
openExternalUrl: async (url) => {
|
|
32
|
-
await window.ipcRenderer.invoke('open-auth-popup', url);
|
|
33
|
-
},
|
|
34
|
-
|
|
35
|
-
// Listen for the auth callback
|
|
36
|
-
onAuthCallback: (callback) => {
|
|
37
|
-
const handler = (_event, data) => callback(data);
|
|
38
|
-
window.ipcRenderer.on('auth-callback', handler);
|
|
39
|
-
return () => window.ipcRenderer.off('auth-callback', handler);
|
|
40
|
-
},
|
|
41
|
-
|
|
42
|
-
// Store tokens securely
|
|
43
|
-
saveTokens: async (tokens) => {
|
|
44
|
-
await window.ipcRenderer.invoke('save-tokens', tokens);
|
|
45
|
-
return true;
|
|
46
|
-
},
|
|
47
|
-
|
|
48
|
-
// Get stored tokens
|
|
49
|
-
getTokens: async () => {
|
|
50
|
-
return await window.ipcRenderer.invoke('get-tokens');
|
|
51
|
-
},
|
|
52
|
-
|
|
53
|
-
// Clear tokens on logout
|
|
54
|
-
deleteTokens: async () => {
|
|
55
|
-
await window.ipcRenderer.invoke('delete-tokens');
|
|
56
|
-
return true;
|
|
57
|
-
},
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
That's it for the adapter. Just 6 functions, all platform-specific. The SDK handles everything else.
|
|
63
|
-
|
|
64
|
-
> **Popup Window vs External Browser**
|
|
65
|
-
>
|
|
66
|
-
> If you need **encryption/decryption**, you **must** use a popup window (Electron BrowserWindow) instead of the system's external browser. This keeps session cookies inside your Electron app, which is required for the encryption/decryption session key to work.
|
|
67
|
-
>
|
|
68
|
-
> | Approach | Session Cookies | Encryption/Decryption |
|
|
69
|
-
> |----------|-----------------|------------|
|
|
70
|
-
> | Popup window (BrowserWindow) | Stays in Electron | Works |
|
|
71
|
-
> | External browser (shell.openExternal) | Separate from Electron | Fails with "session key mismatch" |
|
|
72
|
-
>
|
|
73
|
-
> Without the session cookies, `doEncrypt()` and `doDecrypt()` will fail.
|
|
74
|
-
>
|
|
75
|
-
> Your main process should create a BrowserWindow for login, not call `shell.openExternal()`.
|
|
76
|
-
|
|
77
|
-
### 3. Initialize the SDK
|
|
78
|
-
|
|
79
|
-
```js
|
|
80
|
-
import { IAMService } from "@tidecloak/js";
|
|
81
|
-
import adapterConfig from "./tidecloak.json";
|
|
82
|
-
import { createElectronAdapter } from "./electronAdapter";
|
|
83
|
-
|
|
84
|
-
const config = {
|
|
85
|
-
authMode: "native",
|
|
86
|
-
adapter: createElectronAdapter(),
|
|
87
|
-
...adapterConfig, // Spread your tidecloak.json config
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
// Listen for events. Handlers get the event name first, then its arguments.
|
|
91
|
-
IAMService
|
|
92
|
-
.on("authSuccess", () => console.log("Logged in!"))
|
|
93
|
-
.on("authError", (_event, err) => console.error("Login failed:", err))
|
|
94
|
-
.on("logout", () => console.log("Logged out"));
|
|
95
|
-
|
|
96
|
-
// Start the SDK
|
|
97
|
-
await IAMService.initIAM(config);
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
### Session Mode
|
|
101
|
-
|
|
102
|
-
Control how the SDK handles tokens on startup:
|
|
103
|
-
|
|
104
|
-
```js
|
|
105
|
-
const config = {
|
|
106
|
-
authMode: "native",
|
|
107
|
-
adapter: createElectronAdapter(),
|
|
108
|
-
sessionMode: "offline", // or "online"
|
|
109
|
-
...adapterConfig,
|
|
110
|
-
};
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
| Mode | Behavior | Best For |
|
|
114
|
-
|------|----------|----------|
|
|
115
|
-
| `"online"` | Validates tokens with server, refreshes if needed, requires login if invalid | Always-connected apps |
|
|
116
|
-
| `"offline"` | Accepts stored tokens without server validation, even if expired | Offline-first apps |
|
|
117
|
-
|
|
118
|
-
**Offline mode** is great for apps that need to work without internet. Users can access the app with expired tokens, and you only prompt for re-login when an API call fails with 401.
|
|
119
|
-
|
|
120
|
-
### 4. Login and Logout
|
|
121
|
-
|
|
122
|
-
```js
|
|
123
|
-
// Login - opens system browser
|
|
124
|
-
IAMService.doLogin();
|
|
125
|
-
|
|
126
|
-
// Logout - clears tokens
|
|
127
|
-
IAMService.doLogout();
|
|
128
|
-
|
|
129
|
-
// Check login state
|
|
130
|
-
if (IAMService.isLoggedIn()) {
|
|
131
|
-
console.log("User is logged in");
|
|
132
|
-
}
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
---
|
|
136
|
-
|
|
137
|
-
## Everything You Can Do
|
|
138
|
-
|
|
139
|
-
```js
|
|
140
|
-
// Check auth state
|
|
141
|
-
IAMService.isLoggedIn(); // Is user logged in?
|
|
142
|
-
|
|
143
|
-
// Get tokens
|
|
144
|
-
await IAMService.getToken(); // Access token
|
|
145
|
-
IAMService.getIDToken(); // ID token
|
|
146
|
-
|
|
147
|
-
// Get user info
|
|
148
|
-
IAMService.getName(); // Username
|
|
149
|
-
IAMService.getValueFromToken("email");
|
|
150
|
-
IAMService.getValueFromIDToken("name"); // getValueFromIdToken also works
|
|
151
|
-
|
|
152
|
-
// Check roles
|
|
153
|
-
IAMService.hasRealmRole("admin");
|
|
154
|
-
IAMService.hasClientRole("editor");
|
|
155
|
-
|
|
156
|
-
// Auth actions
|
|
157
|
-
IAMService.doLogin();
|
|
158
|
-
IAMService.doLogout();
|
|
159
|
-
await IAMService.updateIAMToken(); // Refresh token
|
|
160
|
-
|
|
161
|
-
// Encryption (if configured)
|
|
162
|
-
await IAMService.doEncrypt([{ data: "secret", tags: ["personal"] }]);
|
|
163
|
-
await IAMService.doDecrypt([{ encrypted: "...", tags: ["personal"] }]);
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
---
|
|
167
|
-
|
|
168
|
-
## Events
|
|
169
|
-
|
|
170
|
-
Know when things happen:
|
|
171
|
-
|
|
172
|
-
```js
|
|
173
|
-
IAMService
|
|
174
|
-
.on("authSuccess", () => {
|
|
175
|
-
// User logged in successfully
|
|
176
|
-
})
|
|
177
|
-
.on("authError", (_event, err) => {
|
|
178
|
-
// Login failed
|
|
179
|
-
})
|
|
180
|
-
.on("logout", () => {
|
|
181
|
-
// User logged out
|
|
182
|
-
})
|
|
183
|
-
.on("tokenExpired", () => {
|
|
184
|
-
// Token expired - SDK will try to refresh
|
|
185
|
-
});
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
---
|
|
189
|
-
|
|
190
|
-
## Encryption
|
|
191
|
-
|
|
192
|
-
If your TideCloak is set up for encryption, you can protect sensitive data:
|
|
193
|
-
|
|
194
|
-
```js
|
|
195
|
-
// Encrypt
|
|
196
|
-
const [encrypted] = await IAMService.doEncrypt([
|
|
197
|
-
{ data: "sensitive info", tags: ["personal"] }
|
|
198
|
-
]);
|
|
199
|
-
|
|
200
|
-
// Decrypt
|
|
201
|
-
const [decrypted] = await IAMService.doDecrypt([
|
|
202
|
-
{ encrypted, tags: ["personal"] }
|
|
203
|
-
]);
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
Users need the right roles (`_tide_<tag>.selfencrypt` / `_tide_<tag>.selfdecrypt`) to encrypt/decrypt with specific tags.
|
|
207
|
-
|
|
208
|
-
Native mode doesn't support decryption policies. Passing a policy to `doEncrypt` or `doDecrypt` throws, and the draft/commit encryption methods aren't available.
|
|
209
|
-
|
|
210
|
-
---
|
|
211
|
-
|
|
212
|
-
## Platform Setup
|
|
213
|
-
|
|
214
|
-
### Electron
|
|
215
|
-
|
|
216
|
-
You'll need to set up your main process to:
|
|
217
|
-
|
|
218
|
-
1. **Create a popup window for login** (required for encryption):
|
|
219
|
-
```js
|
|
220
|
-
// main.js
|
|
221
|
-
ipcMain.handle('open-auth-popup', async (event, url) => {
|
|
222
|
-
const authWindow = new BrowserWindow({
|
|
223
|
-
width: 500,
|
|
224
|
-
height: 700,
|
|
225
|
-
webPreferences: {
|
|
226
|
-
nodeIntegration: false,
|
|
227
|
-
contextIsolation: true,
|
|
228
|
-
},
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
// Listen for redirect
|
|
232
|
-
authWindow.webContents.on('will-redirect', (event, redirectUrl) => {
|
|
233
|
-
if (redirectUrl.startsWith('myapp://')) {
|
|
234
|
-
const url = new URL(redirectUrl);
|
|
235
|
-
const code = url.searchParams.get('code');
|
|
236
|
-
const error = url.searchParams.get('error');
|
|
237
|
-
|
|
238
|
-
// Send back to renderer
|
|
239
|
-
mainWindow.webContents.send('auth-callback', { code, error });
|
|
240
|
-
authWindow.close();
|
|
241
|
-
}
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
authWindow.loadURL(url);
|
|
245
|
-
});
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
2. **Register a custom protocol** (e.g., `myapp://`)
|
|
249
|
-
|
|
250
|
-
3. **Store tokens securely** (use `safeStorage` or similar)
|
|
251
|
-
|
|
252
|
-
4. **Handle token storage IPC calls**
|
|
253
|
-
|
|
254
|
-
### Tauri
|
|
255
|
-
|
|
256
|
-
Similar to Electron - use a WebView window for login, register a protocol and handle callbacks.
|
|
257
|
-
|
|
258
|
-
### React Native
|
|
259
|
-
|
|
260
|
-
Use deep links for the callback URL and secure storage for tokens.
|
|
261
|
-
|
|
262
|
-
---
|
|
263
|
-
|
|
264
|
-
## Troubleshooting
|
|
265
|
-
|
|
266
|
-
**Login opens but nothing happens after**
|
|
267
|
-
|
|
268
|
-
Make sure your redirect URI is registered in TideCloak and your app is handling the callback.
|
|
269
|
-
|
|
270
|
-
**Tokens not persisting**
|
|
271
|
-
|
|
272
|
-
Check that your `saveTokens` and `getTokens` functions are working correctly.
|
|
273
|
-
|
|
274
|
-
**Encryption/decryption fails with "session key mismatch"**
|
|
275
|
-
|
|
276
|
-
You're probably using an external browser instead of a popup window. The session cookies from login must stay in your Electron app for encryption/decryption to work.
|
|
277
|
-
|
|
278
|
-
Fix: Use `new BrowserWindow()` to open the login page, not `shell.openExternal()`.
|
|
279
|
-
|
|
280
|
-
**Encryption/decryption fails with missing config**
|
|
281
|
-
|
|
282
|
-
Make sure your `tidecloak.json` includes:
|
|
283
|
-
- `vendorId` - Your Tide vendor ID
|
|
284
|
-
- `client-origin-auth-{origin}` - Auth signature for your app's origin (e.g., `client-origin-auth-http://localhost:5174`)
|