@drmhse/sso-sdk 0.3.13 → 0.4.0
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 +78 -6
- package/dist/index.d.mts +396 -62
- package/dist/index.d.ts +396 -62
- package/dist/index.js +221 -25
- package/dist/index.mjs +221 -25
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -98,7 +98,9 @@ const loginUrl = sso.auth.getLoginUrl('github', {
|
|
|
98
98
|
await sso.auth.login({
|
|
99
99
|
email: 'user@example.com',
|
|
100
100
|
password: 'SecurePass123!',
|
|
101
|
-
org_slug: 'acme-corp'
|
|
101
|
+
org_slug: 'acme-corp', // Optional: scopes JWT to this org
|
|
102
|
+
service_slug: 'main-app',
|
|
103
|
+
redirect_uri: 'https://app.acme.com/callback'
|
|
102
104
|
});
|
|
103
105
|
// JWT contains: { org: 'acme-corp', ... }
|
|
104
106
|
```
|
|
@@ -138,11 +140,15 @@ const loginUrl = sso.auth.getLoginUrl('github', {
|
|
|
138
140
|
});
|
|
139
141
|
window.location.href = loginUrl;
|
|
140
142
|
|
|
141
|
-
// Handle callback -
|
|
142
|
-
|
|
143
|
-
const
|
|
143
|
+
// Handle callback - tokens are returned in URL fragment (#) for security
|
|
144
|
+
// (prevents tokens from being logged in server access logs)
|
|
145
|
+
const hashParams = new URLSearchParams(window.location.hash.substring(1));
|
|
146
|
+
const accessToken = hashParams.get('access_token');
|
|
144
147
|
|
|
145
148
|
if (accessToken) {
|
|
149
|
+
// Clear hash from URL for security
|
|
150
|
+
window.history.replaceState(null, '', window.location.pathname);
|
|
151
|
+
|
|
146
152
|
// Initialize SDK with OAuth token - automatically stored
|
|
147
153
|
const sso = new SsoClient({
|
|
148
154
|
baseURL: 'https://sso.example.com',
|
|
@@ -183,6 +189,48 @@ const result = await sso.user.mfa.verify('123456'); // TOTP code from authentica
|
|
|
183
189
|
console.log('Backup codes:', result.backup_codes); // Save these securely!
|
|
184
190
|
```
|
|
185
191
|
|
|
192
|
+
### Hosted Auth Context & Passwordless
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
const context = await sso.auth.getContext({
|
|
196
|
+
org: 'acme-corp',
|
|
197
|
+
service: 'main-app',
|
|
198
|
+
redirect_uri: 'https://app.acme.com/callback'
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
console.log(context.organization?.name);
|
|
202
|
+
console.log(context.available_providers); // ['github', 'google', 'microsoft']
|
|
203
|
+
|
|
204
|
+
await sso.magicLinks.request({
|
|
205
|
+
email: 'user@example.com',
|
|
206
|
+
org_slug: 'acme-corp',
|
|
207
|
+
service_slug: 'main-app',
|
|
208
|
+
redirect_uri: 'https://app.acme.com/callback'
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
const passkeyLogin = await sso.passkeys.login('user@example.com', {
|
|
212
|
+
org_slug: 'acme-corp',
|
|
213
|
+
service_slug: 'main-app',
|
|
214
|
+
redirect_uri: 'https://app.acme.com/callback'
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
await sso.setSession({
|
|
218
|
+
access_token: passkeyLogin.access_token,
|
|
219
|
+
refresh_token: passkeyLogin.refresh_token
|
|
220
|
+
});
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Passkey Self-Service
|
|
224
|
+
|
|
225
|
+
```typescript
|
|
226
|
+
const passkeys = await sso.passkeys.list();
|
|
227
|
+
|
|
228
|
+
if (passkeys.length > 0) {
|
|
229
|
+
await sso.passkeys.updateName(passkeys[0].id, 'Work Laptop');
|
|
230
|
+
await sso.passkeys.delete(passkeys[0].id);
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
186
234
|
### Device Flow (for CLIs)
|
|
187
235
|
|
|
188
236
|
```typescript
|
|
@@ -251,7 +299,7 @@ if (currentRefreshToken) {
|
|
|
251
299
|
|
|
252
300
|
```typescript
|
|
253
301
|
// Create organization
|
|
254
|
-
const org = await sso.organizations.
|
|
302
|
+
const org = await sso.organizations.create({
|
|
255
303
|
name: 'Acme Corp',
|
|
256
304
|
slug: 'acme-corp'
|
|
257
305
|
});
|
|
@@ -263,7 +311,7 @@ await sso.organizations.oauthCredentials.set('acme-corp', 'github', {
|
|
|
263
311
|
});
|
|
264
312
|
|
|
265
313
|
// Invite team members
|
|
266
|
-
await sso.
|
|
314
|
+
await sso.invitations.create('acme-corp', {
|
|
267
315
|
email: 'member@acme.com',
|
|
268
316
|
role: 'admin'
|
|
269
317
|
});
|
|
@@ -341,6 +389,26 @@ const backendClient = new SsoClient({
|
|
|
341
389
|
baseURL: 'https://sso.example.com',
|
|
342
390
|
apiKey: apiKey.key
|
|
343
391
|
});
|
|
392
|
+
|
|
393
|
+
const rotated = await sso.services.rotateSecret('acme-corp', 'main-app');
|
|
394
|
+
console.log('New client secret:', rotated.client_secret);
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
## Fine-Grained Member Access
|
|
398
|
+
|
|
399
|
+
```typescript
|
|
400
|
+
const access = await sso.organizations.members.updateServiceAccess(
|
|
401
|
+
'acme-corp',
|
|
402
|
+
'user-id',
|
|
403
|
+
{
|
|
404
|
+
grants: [
|
|
405
|
+
{ service_slug: 'main-app', access: 'manager' },
|
|
406
|
+
{ service_slug: 'docs-app', access: 'viewer' }
|
|
407
|
+
]
|
|
408
|
+
}
|
|
409
|
+
);
|
|
410
|
+
|
|
411
|
+
console.log(access);
|
|
344
412
|
```
|
|
345
413
|
|
|
346
414
|
## Analytics
|
|
@@ -420,6 +488,10 @@ console.log(overview); // { total_users, total_orgs, total_logins, ... }
|
|
|
420
488
|
|
|
421
489
|
// Search users across all organizations
|
|
422
490
|
const users = await sso.platform.users.search('user@example.com');
|
|
491
|
+
|
|
492
|
+
// Inspect operational health
|
|
493
|
+
const ops = await sso.platform.getOperationsStatus();
|
|
494
|
+
console.log(ops.jobs_pending, ops.webhook_deliveries_failed);
|
|
423
495
|
```
|
|
424
496
|
|
|
425
497
|
## TypeScript Support
|