@webex/plugin-authorization-browser 3.8.1 → 3.9.0-next.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.
@@ -0,0 +1,541 @@
1
+ # Webex Browser OAuth Authorization Flow - Technical Guide
2
+
3
+ This document explains how the Webex SDK handles OAuth authorization in browser environments, covering the complete flow from initialization to token management.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Browser Webex Initialization](#1-browser-webex-initialization)
8
+ - [Browser OAuth Flow Trigger](#2-browser-oauth-flow-trigger)
9
+ - [Authorization Code Processing](#3-authorization-code-processing)
10
+ - [Token Generation and Exchange](#4-token-generation-and-exchange)
11
+ - [Refresh Token Management](#5-refresh-token-management)
12
+ - [Browser Ready and Authorization Events](#6-browser-ready-and-authorization-events)
13
+
14
+ ---
15
+
16
+ ## 1. Browser Webex Initialization
17
+
18
+ ### 1.1 Basic Browser Setup
19
+
20
+ Browser applications initialize the Webex SDK with OAuth parameters:
21
+
22
+ ```javascript
23
+ // Basic browser initialization
24
+ const webex = Webex.init({
25
+ credentials: {
26
+ client_id: 'your-client-id',
27
+ redirect_uri: 'https://your-app.com/callback',
28
+ scope: 'spark:all spark:kms',
29
+ clientType: 'public' // or 'confidential'
30
+ }
31
+ });
32
+ ```
33
+
34
+ Parameters:
35
+
36
+ - **client_id**: Your registered application ID
37
+ - **redirect_uri**: Where to send the user after authentication
38
+ - **scope**: Requested permissions (e.g., 'spark:all spark:kms')
39
+ - **clientType**: 'public' (default) or 'confidential'
40
+
41
+ **Reference**: See `docs/samples/browser-auth/app.js` for a working example
42
+
43
+ ### 1.2 Browser Flow Type Determination
44
+
45
+ The browser plugin automatically selects OAuth flow based on `clientType`:
46
+
47
+ ```javascript
48
+ // Public client (default) - uses response_type=token
49
+ const webex = Webex.init({
50
+ credentials: {
51
+ client_id: 'your-client-id',
52
+ clientType: 'public' // or omit (defaults to public)
53
+ }
54
+ });
55
+ // Calls initiateImplicitGrant() -> response_type=token
56
+
57
+ // Confidential client - uses response_type=code
58
+ const webex = Webex.init({
59
+ credentials: {
60
+ client_id: 'your-client-id',
61
+ clientType: 'confidential'
62
+ }
63
+ });
64
+ // Calls initiateAuthorizationCodeGrant() -> response_type=code
65
+ ```
66
+
67
+ Flow selection:
68
+
69
+ - **Public Client** (`clientType: 'public'` or undefined): Uses **Implicit Grant** with `response_type=token`
70
+ - **Confidential Client** (`clientType: 'confidential'`): Uses **Authorization Code Grant** with `response_type=code`
71
+
72
+ **Reference**: `initiateLogin()` method in `packages/@webex/plugin-authorization-browser/src/authorization.js`
73
+
74
+ ### 1.3 Webex ID Broker Grant Types and Browser SDK Implementation
75
+
76
+ Webex ID Broker supports several OAuth 2.0 grant types. The browser SDK implements them as follows:
77
+
78
+ #### 1. Authorization Code Grant (`clientType: 'confidential'`)
79
+
80
+ **Webex ID Broker**: Returns authorization code after user authentication
81
+ **Browser SDK**: Uses `response_type=code`, then exchanges code for tokens
82
+
83
+ ```javascript
84
+ // SDK automatically handles this flow
85
+ const webex = Webex.init({
86
+ credentials: { clientType: 'confidential', /* other config */ }
87
+ });
88
+ webex.authorization.initiateLogin(); // Uses response_type=code
89
+ ```
90
+
91
+ #### 2. Implicit Grant (`clientType: 'public'` - default)
92
+
93
+ **Webex ID Broker**: Returns access token directly after user authentication
94
+ **Browser SDK**: Uses `response_type=token`, receives token in URL hash
95
+
96
+ ```javascript
97
+ // SDK automatically handles this flow
98
+ const webex = Webex.init({
99
+ credentials: { clientType: 'public', /* other config */ }
100
+ });
101
+ webex.authorization.initiateLogin(); // Uses response_type=token
102
+ ```
103
+
104
+ #### 3. Refresh Token Grant (automatic)
105
+
106
+ **Webex ID Broker**: Exchanges refresh token for new access token
107
+ **Browser SDK**: Automatically uses `grant_type=refresh_token` when tokens expire
108
+
109
+ ```javascript
110
+ // SDK handles refresh automatically, or manually:
111
+ webex.credentials.supertoken.refresh(); // Uses grant_type=refresh_token
112
+ ```
113
+
114
+ #### 4. Client Credentials Grant (Node.js only)
115
+
116
+ **Webex ID Broker**: Application-to-application authentication
117
+ **Browser SDK**: Not supported (requires client secret)
118
+
119
+ **Note**: Client credentials grant is only available in Node.js SDK since it requires a client secret that cannot be safely stored in browsers.
120
+
121
+ ### 1.4 Browser Implementation Differences
122
+
123
+ #### Implicit Grant Flow (Public Clients)
124
+
125
+ - **Security**: Tokens exposed in browser URL (less secure)
126
+ - **Client Secret**: No client secret required
127
+ - **Token Location**: Access token in URL hash fragment
128
+ - **Redirect**: Single redirect with token
129
+ - **Best For**: Single-page applications, mobile apps
130
+
131
+ #### Authorization Code Grant Flow (Confidential Clients)
132
+
133
+ - **Security**: More secure, tokens never exposed to browser
134
+ - **Client Secret**: Requires client secret
135
+ - **Token Location**: Authorization code in URL, exchanged server-side
136
+ - **Redirect**: Two-step process (code → token exchange)
137
+ - **Best For**: Web applications with backend
138
+
139
+ ### 1.5 Browser URL Parsing on Load
140
+
141
+ During browser initialization, the plugin automatically:
142
+
143
+ 1. **Parses current URL** for OAuth tokens/codes
144
+ 2. **Checks for OAuth errors** in URL parameters
145
+ 3. **Validates CSRF tokens** for security
146
+ 4. **Cleans the URL** by removing sensitive parameters
147
+
148
+ **Reference**: `initialize()` method in `packages/@webex/plugin-authorization-browser/src/authorization.js`
149
+
150
+ ---
151
+
152
+ ## 2. Browser OAuth Flow Trigger
153
+
154
+ ### 2.1 Initiating Browser Login
155
+
156
+ The `initiateLogin()` method redirects users to Webex's identity broker for authentication. It does **NOT** accept email/password directly.
157
+
158
+ ```javascript
159
+ // Basic login - redirects to Webex login page
160
+ webex.authorization.initiateLogin()
161
+
162
+ // Login with custom state data
163
+ webex.authorization.initiateLogin({
164
+ state: {
165
+ returnUrl: '/dashboard',
166
+ userId: 'user123'
167
+ }
168
+ })
169
+
170
+ // Login in popup window (default dimensions: 600x800)
171
+ webex.authorization.initiateLogin({
172
+ separateWindow: true
173
+ })
174
+
175
+ // Login in popup with custom dimensions
176
+ webex.authorization.initiateLogin({
177
+ separateWindow: {
178
+ width: 800,
179
+ height: 600
180
+ }
181
+ })
182
+ ```
183
+
184
+ Parameters:
185
+
186
+ - **options.state** (Object, optional): Custom data included in OAuth state
187
+ - **options.separateWindow** (Boolean|Object, optional): Open in popup window
188
+
189
+ Process:
190
+
191
+ 1. **Generates CSRF token** for security
192
+ 2. **Determines flow type** based on client configuration
193
+ 3. **Builds OAuth URL** with required parameters
194
+ 4. **Redirects user** to Webex identity broker
195
+
196
+ **Reference**: `initiateLogin()` method in browser authorization plugin
197
+
198
+ ### 2.2 Browser CSRF Token Generation
199
+
200
+ Browser-specific CSRF protection:
201
+
202
+ 1. **Generates UUID token** using `uuid.v4()`
203
+ 2. **Stores in sessionStorage** for later verification
204
+ 3. **Includes in state parameter** of OAuth request
205
+
206
+ **Reference**: `_generateSecurityToken()` method in browser plugin
207
+
208
+ ### 2.3 Browser Redirection Options
209
+
210
+ Browser supports multiple redirection methods:
211
+
212
+ - **Same window**: Default behavior (full page redirect)
213
+ - **Popup window**: Optional separate window with configurable dimensions
214
+
215
+ **Reference**: `initiateImplicitGrant()` and `initiateAuthorizationCodeGrant()` methods
216
+
217
+ ---
218
+
219
+ ## 3. Authorization Code Processing
220
+
221
+ ### 3.1 User Authentication at ID Broker
222
+
223
+ User experience at Webex identity broker:
224
+
225
+ 1. **User enters credentials** (username/password, SSO, etc.)
226
+ 2. **Identity verification** occurs
227
+ 3. **Consent screen** may appear for scope approval
228
+ 4. **Authorization decision** is made
229
+
230
+ ### 3.2 Browser Redirect Back
231
+
232
+ After successful authentication:
233
+
234
+ - **Implicit Grant**: User redirected with access token in URL hash
235
+ - **Authorization Code Grant**: User redirected with authorization code in query parameters
236
+
237
+ ### 3.3 Browser Code/Token Reception
238
+
239
+ Browser SDK processes the return URL automatically:
240
+
241
+ 1. **URL parsing** during plugin initialization
242
+ 2. **Error checking** for OAuth errors
243
+ 3. **Token/code extraction** from URL parameters
244
+ 4. **State validation** for CSRF protection
245
+
246
+ **Reference**: `initialize()` and `_parseHash()` methods in browser plugin
247
+
248
+ ### 3.4 Browser CSRF Token Verification
249
+
250
+ Browser security validation:
251
+
252
+ 1. **Extract state parameter** from redirect URL
253
+ 2. **Decode Base64 state** object
254
+ 3. **Compare CSRF tokens** (URL vs sessionStorage)
255
+ 4. **Throw error** if tokens don't match
256
+
257
+ **Reference**: `_verifySecurityToken()` method in browser plugin
258
+
259
+ ---
260
+
261
+ ## 4. Token Generation and Exchange
262
+
263
+ ### 4.1 Browser Implicit Grant Processing
264
+
265
+ For browser implicit grant, access token comes directly in URL hash:
266
+
267
+ - access_token
268
+ - token_type (Bearer)
269
+ - expires_in
270
+ - scope
271
+
272
+ > **Note:** Refresh tokens are generally not provided in implicit grant flows due to security reasons. Most OAuth providers, including Webex, do not issue refresh tokens for implicit grant to prevent long-lived tokens from being exposed in browser environments. Applications using implicit grant should expect to obtain new access tokens by re-authenticating the user when the current token expires.
273
+
274
+ **Reference**: Token parsing in `_parseHash()` method
275
+
276
+ ### 4.2 Browser Authorization Code Exchange
277
+
278
+ For browser confidential clients, code exchange happens:
279
+
280
+ - **Client-side**: Code captured from URL
281
+ - **Server-side**: Code exchanged for tokens using client secret
282
+
283
+ ### 4.3 Browser JWT Authentication
284
+
285
+ Browser JWT authentication for guest users:
286
+
287
+ ```javascript
288
+ // Create JWT token
289
+ webex.authorization.createJwt({
290
+ issuer: 'your-guest-issuer-id',
291
+ secretId: 'your-base64-encoded-secret',
292
+ displayName: 'Guest User Name',
293
+ expiresIn: '12h'
294
+ }).then(({jwt}) => {
295
+ console.log('Created JWT:', jwt);
296
+
297
+ // Exchange JWT for access token
298
+ return webex.authorization.requestAccessTokenFromJwt({jwt});
299
+ }).then(() => {
300
+ console.log('Guest user authenticated');
301
+ }).catch(error => {
302
+ console.error('JWT authentication failed:', error);
303
+ });
304
+ ```
305
+
306
+ Process:
307
+
308
+ 1. **Create JWT token** with issuer, secret, display name
309
+ 2. **Exchange JWT for access token** via API call
310
+
311
+ **Reference**: `createJwt()` and `requestAccessTokenFromJwt()` methods in browser plugin
312
+
313
+ ### 4.4 Browser Token Storage
314
+
315
+ Browser token storage:
316
+
317
+ 1. **Stored in credentials object** via `webex.credentials.set()`
318
+ 2. **Persisted in browser storage** (localStorage/sessionStorage)
319
+ 3. **Monitored for expiration** by interceptors
320
+
321
+ ---
322
+
323
+ ## 5. Refresh Token Management
324
+
325
+ ### 5.1 Browser Token Expiration Detection
326
+
327
+ Browser monitors token validity through:
328
+
329
+ ```javascript
330
+ // Check if token is expired
331
+ if (webex.credentials.supertoken.isExpired) {
332
+ console.log('Token is expired');
333
+ // SDK will automatically refresh if refresh token available
334
+ }
335
+
336
+ // Check if token can be refreshed
337
+ if (webex.credentials.supertoken.canRefresh) {
338
+ console.log('Token can be refreshed');
339
+ } else {
340
+ console.log('User needs to re-authenticate');
341
+ webex.authorization.initiateLogin();
342
+ }
343
+
344
+ // Manual token refresh
345
+ webex.credentials.supertoken.refresh().then((newToken) => {
346
+ console.log('Token refreshed successfully');
347
+ }).catch((error) => {
348
+ console.error('Token refresh failed:', error);
349
+ webex.authorization.initiateLogin();
350
+ });
351
+ ```
352
+
353
+ Detection mechanisms:
354
+
355
+ - **HTTP interceptors** checking responses
356
+ - **Automatic refresh triggers** before expiration
357
+ - **Error handling** for 401 Unauthorized responses
358
+
359
+ ### 5.2 Browser Refresh Token Flow
360
+
361
+ Browser refresh token process using `refreshCallback`:
362
+
363
+ ```javascript
364
+ // Configure refresh callback during initialization
365
+ const webex = Webex.init({
366
+ credentials: {
367
+ client_id: 'your-client-id',
368
+ redirect_uri: 'https://your-app.com/callback',
369
+ scope: 'spark:all spark:kms',
370
+ refreshCallback: (webex, token) => {
371
+ // Custom refresh logic for browser
372
+ return webex.request({
373
+ method: 'POST',
374
+ uri: 'https://webexapis.com/v1/access_token',
375
+ form: {
376
+ grant_type: 'refresh_token',
377
+ refresh_token: token.refresh_token,
378
+ client_id: token.config.client_id
379
+ }
380
+ }).then(response => response.body);
381
+ }
382
+ }
383
+ });
384
+ ```
385
+
386
+ Refresh process:
387
+
388
+ 1. **POST request** to `/access_token` endpoint
389
+ 2. **grant_type**: "refresh_token"
390
+ 3. **Current refresh token** as parameter
391
+ 4. **Client ID** for identification
392
+ 5. **New tokens returned** and stored automatically
393
+
394
+ ### 5.3 Browser Automatic Refresh
395
+
396
+ SDK automatically handles token refresh:
397
+
398
+ ```javascript
399
+ // SDK automatically refreshes tokens before API calls
400
+ webex.people.get('me').then(person => {
401
+ // Token was automatically refreshed if needed
402
+ console.log('Current user:', person.displayName);
403
+ }).catch(error => {
404
+ if (error.message.includes('unauthorized')) {
405
+ // Refresh failed, user needs to re-authenticate
406
+ webex.authorization.initiateLogin();
407
+ }
408
+ });
409
+
410
+ // Listen for token refresh events
411
+ webex.credentials.on('change:supertoken', () => {
412
+ console.log('Token was refreshed');
413
+ });
414
+ ```
415
+
416
+ ### 5.4 Browser JWT Refresh
417
+
418
+ Browser JWT refresh using callback:
419
+
420
+ ```javascript
421
+ // Configure JWT refresh callback
422
+ const webex = Webex.init({
423
+ credentials: {
424
+ jwtRefreshCallback: async (webex) => {
425
+ // Get new JWT from your backend
426
+ const response = await fetch('/api/jwt-refresh', {
427
+ method: 'POST',
428
+ credentials: 'include'
429
+ });
430
+ const { jwt } = await response.json();
431
+ return jwt;
432
+ }
433
+ }
434
+ });
435
+
436
+ // SDK automatically uses jwtRefreshCallback when JWT expires
437
+ ```
438
+
439
+ **Reference**: JWT refresh implementation in browser authorization plugin
440
+
441
+ ---
442
+
443
+ ## 6. Browser Ready and Authorization Events
444
+
445
+ ### 6.1 Browser SDK Initialization Lifecycle
446
+
447
+ Browser SDK initialization phases:
448
+
449
+ 1. **Construction**: Basic object creation
450
+ 2. **Plugin Loading**: Authorization and other plugins initialize
451
+ 3. **Storage Loading**: Browser storage data retrieval
452
+ 4. **Authentication Check**: Token validation and refresh
453
+ 5. **Ready State**: All systems operational
454
+
455
+ ### 6.2 Browser Authorization Events
456
+
457
+ Browser-specific events:
458
+
459
+ ```javascript
460
+ // Listen for SDK ready event
461
+ webex.once('ready', () => {
462
+ console.log('Webex SDK is ready and authenticated');
463
+ });
464
+
465
+ // Listen for unauthorized event
466
+ webex.on('unauthorized', () => {
467
+ console.log('User authentication lost - redirect to login');
468
+ webex.authorization.initiateLogin();
469
+ });
470
+
471
+ // Listen for logout event
472
+ webex.on('client:logout', () => {
473
+ console.log('User has logged out');
474
+ });
475
+ ```
476
+
477
+ Events:
478
+
479
+ - **ready**: SDK fully initialized and authenticated
480
+ - **unauthorized**: User authentication lost
481
+ - **client:logout**: User has logged out
482
+
483
+ ### 6.3 Browser Authentication Status
484
+
485
+ Check browser authentication status:
486
+
487
+ ```javascript
488
+ // Check if user can make authenticated requests
489
+ if (webex.canAuthorize) {
490
+ console.log('User is authenticated');
491
+ // Make API calls
492
+ } else {
493
+ console.log('User needs to login');
494
+ webex.authorization.initiateLogin();
495
+ }
496
+
497
+ // Check if authorization is in progress
498
+ if (webex.authorization.isAuthorizing) {
499
+ console.log('Authorization in progress...');
500
+ }
501
+
502
+ // Check if SDK is fully ready
503
+ if (webex.ready) {
504
+ console.log('SDK is fully initialized');
505
+ }
506
+ ```
507
+
508
+ Status Properties:
509
+
510
+ - `webex.canAuthorize`: Boolean for authenticated requests capability
511
+ - `webex.authorization.isAuthorizing`: Boolean for authorization in progress
512
+ - `webex.ready`: Boolean for SDK fully initialized
513
+
514
+ ### 6.4 Browser Ready State Dependencies
515
+
516
+ Browser ready state depends on:
517
+
518
+ - **Credentials loaded** from browser storage
519
+ - **All plugins initialized**
520
+ - **Services catalog loaded**
521
+ - **Authentication state established**
522
+
523
+ ---
524
+
525
+ ## Browser Code References
526
+
527
+ - **Main Browser Plugin**: `packages/@webex/plugin-authorization-browser/src/authorization.js`
528
+ - **Browser Auth Sample**: `docs/samples/browser-auth/app.js`
529
+ - **Browser Plugin Docs**: `packages/@webex/plugin-authorization-browser/README.md`
530
+
531
+ ## Maintainers
532
+
533
+ This package is maintained by [Cisco Webex for Developers](https://developer.webex.com/).
534
+
535
+ ## Contribute
536
+
537
+ Pull requests welcome. Please see [CONTRIBUTING.md](https://github.com/webex/webex-js-sdk/blob/master/CONTRIBUTING.md) for more details.
538
+
539
+ ## License
540
+
541
+ © 2016-2025 Cisco and/or its affiliates. All Rights Reserved.
package/README.md CHANGED
@@ -1,14 +1,38 @@
1
1
  # @webex/plugin-authorization-browser
2
2
 
3
- [![standard-readme compliant](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)
3
+ > OAuth2 authorization plugin for browser environments in the Cisco Webex JS SDK. Handles OAuth2 flows including Implicit Grant and Authorization Code Grant for web applications.
4
4
 
5
- > Authorization plugin loaded when the Cisco Webex JS SDK is used in a web browser.
5
+ ## Table of Contents
6
6
 
7
- - [Install](#install)
8
- - [Usage](#usage)
9
- - [Contribute](#contribute)
10
- - [Maintainers](#maintainers)
11
- - [License](#license)
7
+ - [@webex/plugin-authorization-browser](#webexplugin-authorization-browser)
8
+ - [Table of Contents](#table-of-contents)
9
+ - [Install](#install)
10
+ - [What it Does](#what-it-does)
11
+ - [Usage](#usage)
12
+ - [Basic OAuth2 Login](#basic-oauth2-login)
13
+ - [Implicit Grant Flow](#implicit-grant-flow)
14
+ - [Authorization Code Grant Flow](#authorization-code-grant-flow)
15
+ - [Login with Popup Window](#login-with-popup-window)
16
+ - [JWT Authentication](#jwt-authentication)
17
+ - [Guest JWT Creation](#guest-jwt-creation)
18
+ - [Logout](#logout)
19
+ - [Checking Authentication Status](#checking-authentication-status)
20
+ - [Error Handling](#error-handling)
21
+ - [API Reference](#api-reference)
22
+ - [Methods](#methods)
23
+ - [`initiateLogin(options)`](#initiateloginoptions)
24
+ - [`initiateImplicitGrant(options)`](#initiateimplicitgrantoptions)
25
+ - [`initiateAuthorizationCodeGrant(options)`](#initiateauthorizationcodegrantoptions)
26
+ - [`requestAccessTokenFromJwt({ jwt })`](#requestaccesstokenfromjwt-jwt-)
27
+ - [`createJwt(options)`](#createjwtoptions)
28
+ - [`logout(options)`](#logoutoptions)
29
+ - [Properties](#properties)
30
+ - [`isAuthorizing` (boolean)](#isauthorizing-boolean)
31
+ - [`isAuthenticating` (boolean)](#isauthenticating-boolean)
32
+ - [`ready` (boolean)](#ready-boolean)
33
+ - [Maintainers](#maintainers)
34
+ - [Contribute](#contribute)
35
+ - [License](#license)
12
36
 
13
37
  ## Install
14
38
 
@@ -16,38 +40,301 @@
16
40
  npm install --save @webex/plugin-authorization-browser
17
41
  ```
18
42
 
43
+ ## What it Does
44
+
45
+ The `@webex/plugin-authorization-browser` plugin provides OAuth2 authentication capabilities specifically for browser environments. It:
46
+
47
+ - **Automatically handles OAuth2 flows**: Supports both Implicit Grant and Authorization Code Grant flows
48
+ - **Manages authentication state**: Tracks authorization status and handles token parsing from URL
49
+ - **Provides CSRF protection**: Generates and validates CSRF tokens for security
50
+ - **Supports popup authentication**: Can open login in a separate window
51
+ - **JWT token support**: Create and use JWT tokens for guest authentication
52
+ - **URL cleanup**: Automatically removes sensitive tokens from browser URL after authentication
53
+ - **Cross-browser compatibility**: Works across different browser environments
54
+
19
55
  ## Usage
20
56
 
21
- This is a plugin for the Cisco Webex JS SDK . Please see our [developer portal](https://developer.webex.com/) and the [API docs](https://webex.github.io/webex-js-sdk/api/) for full details.
57
+ ### Basic OAuth2 Login
22
58
 
23
- ## Install
59
+ The simplest way to authenticate users:
24
60
 
25
- ```bash
26
- npm install --save @webex/plugin-authorization-browser
61
+ ```javascript
62
+ const Webex = require('webex');
63
+
64
+ // Initialize Webex SDK
65
+ const webex = Webex.init({
66
+ credentials: {
67
+ client_id: 'your-client-id',
68
+ redirect_uri: 'https://your-app.com/callback',
69
+ scope: 'spark:all'
70
+ }
71
+ });
72
+
73
+ // Start the login process
74
+ webex.authorization.initiateLogin()
75
+ .then(() => {
76
+ console.log('Login initiated');
77
+ // User will be redirected to Webex login page
78
+ });
79
+
80
+ // After redirect, check if user is authenticated
81
+ if (webex.canAuthorize) {
82
+ console.log('User is authenticated');
83
+ // Make API calls
84
+ }
27
85
  ```
28
86
 
29
- ## Usage
87
+ ### Implicit Grant Flow
30
88
 
31
- ```js
89
+ For public clients (single-page applications):
32
90
 
33
- const Webex = require('webex');
91
+ ```javascript
92
+ const webex = Webex.init({
93
+ credentials: {
94
+ client_id: 'your-client-id',
95
+ redirect_uri: 'https://your-app.com/callback',
96
+ scope: 'spark:all'
97
+ // No client_secret for public clients
98
+ }
99
+ });
100
+
101
+ // Initiate implicit grant flow
102
+ webex.authorization.initiateImplicitGrant({
103
+ state: { customData: 'value' } // Optional state data
104
+ })
105
+ .then(() => {
106
+ console.log('Implicit grant flow started');
107
+ });
108
+ ```
109
+
110
+ ### Authorization Code Grant Flow
111
+
112
+ For confidential clients with client secret:
113
+
114
+ ```javascript
115
+ const webex = Webex.init({
116
+ credentials: {
117
+ client_id: 'your-client-id',
118
+ client_secret: 'your-client-secret',
119
+ redirect_uri: 'https://your-app.com/callback',
120
+ scope: 'spark:all',
121
+ clientType: 'confidential' // This triggers authorization code flow
122
+ }
123
+ });
124
+
125
+ // Initiate authorization code grant flow
126
+ webex.authorization.initiateAuthorizationCodeGrant({
127
+ state: { customData: 'value' }
128
+ })
129
+ .then(() => {
130
+ console.log('Authorization code flow started');
131
+ });
132
+ ```
133
+
134
+ ### Login with Popup Window
135
+
136
+ Open login in a separate popup window instead of redirecting:
137
+
138
+ ```javascript
139
+ // Basic popup with default dimensions (600x800)
140
+ webex.authorization.initiateLogin({
141
+ separateWindow: true
142
+ });
143
+
144
+ // Custom popup dimensions
145
+ webex.authorization.initiateLogin({
146
+ separateWindow: {
147
+ width: 800,
148
+ height: 600
149
+ }
150
+ });
151
+
152
+ // With custom state and popup
153
+ webex.authorization.initiateLogin({
154
+ state: {
155
+ returnUrl: '/dashboard',
156
+ userId: 'user123'
157
+ },
158
+ separateWindow: {
159
+ width: 900,
160
+ height: 700
161
+ }
162
+ });
163
+ ```
164
+
165
+ ### JWT Authentication
166
+
167
+ Authenticate using a JWT token (useful for guest users):
168
+
169
+ ```javascript
170
+ // Assuming you have a JWT from your backend
171
+ const jwtToken = '<YOUR_JWT_TOKEN_HERE>';
172
+
173
+ webex.authorization.requestAccessTokenFromJwt({
174
+ jwt: jwtToken
175
+ })
176
+ .then(() => {
177
+ console.log('Authenticated with JWT');
178
+ // User is now authenticated and can make API calls
179
+ })
180
+ .catch(error => {
181
+ console.error('JWT authentication failed:', error);
182
+ });
183
+ ```
184
+
185
+ ### Guest JWT Creation
186
+
187
+ Create JWT tokens for guest users:
188
+
189
+ ```javascript
190
+ // Create a guest JWT token
191
+ webex.authorization.createJwt({
192
+ issuer: 'your-guest-issuer-id',
193
+ secretId: 'your-base64-encoded-secret',
194
+ displayName: 'Guest User Name', // Optional
195
+ expiresIn: '12h' // Token expiration
196
+ })
197
+ .then(({ jwt }) => {
198
+ console.log('Created guest JWT:', jwt);
199
+
200
+ // Use the JWT to authenticate
201
+ return webex.authorization.requestAccessTokenFromJwt({ jwt });
202
+ })
203
+ .then(() => {
204
+ console.log('Guest user authenticated');
205
+ })
206
+ .catch(error => {
207
+ console.error('Guest JWT creation failed:', error);
208
+ });
209
+ ```
210
+
211
+ ### Logout
212
+
213
+ Log out the current user:
214
+
215
+ ```javascript
216
+ // Logout and redirect to Webex logout page
217
+ webex.authorization.logout();
34
218
 
35
- const webex = Webex.init();
36
- webex.authorization-browser.get(id)
37
- .then((authorization-browser) => {
38
- console.log(authorization-browser);
39
- })
219
+ // Logout without redirect (clean up local session only)
220
+ webex.authorization.logout({ noRedirect: true });
40
221
 
222
+ // Logout with custom logout URL
223
+ webex.authorization.logout({
224
+ goto: 'https://your-app.com/goodbye'
225
+ });
41
226
  ```
42
227
 
228
+ ### Checking Authentication Status
229
+
230
+ ```javascript
231
+ // Check if SDK can authorize (has valid token)
232
+ if (webex.canAuthorize) {
233
+ console.log('User is authenticated');
234
+ }
235
+
236
+ // Check if authorization is in progress
237
+ if (webex.authorization.isAuthorizing) {
238
+ console.log('Authorization in progress...');
239
+ }
240
+
241
+ // Listen for authentication events
242
+ webex.on('ready', () => {
243
+ console.log('SDK is ready and authenticated');
244
+ });
245
+
246
+ webex.on('unauthorized', () => {
247
+ console.log('User is not authenticated');
248
+ });
249
+ ```
250
+
251
+ ### Error Handling
252
+
253
+ ```javascript
254
+ // Handle authentication errors from URL
255
+ try {
256
+ const webex = Webex.init({
257
+ credentials: { /* your config */ }
258
+ });
259
+ } catch (error) {
260
+ if (error.name === 'OAuthError') {
261
+ console.error('OAuth error:', error.message);
262
+ // Handle specific OAuth errors like access_denied
263
+ }
264
+ }
265
+
266
+ // Handle JWT authentication errors
267
+ webex.authorization.requestAccessTokenFromJwt({ jwt: 'invalid-jwt' })
268
+ .catch(error => {
269
+ console.error('JWT authentication failed:', error);
270
+ });
271
+ ```
272
+
273
+ ## API Reference
274
+
275
+ ### Methods
276
+
277
+ #### `initiateLogin(options)`
278
+
279
+ Initiates the appropriate OAuth flow based on client configuration.
280
+
281
+ - `options.state` - Optional state object for custom data
282
+ - `options.separateWindow` - Boolean or object for popup window settings
283
+
284
+ #### `initiateImplicitGrant(options)`
285
+
286
+ Starts the Implicit Grant flow for public clients.
287
+
288
+ #### `initiateAuthorizationCodeGrant(options)`
289
+
290
+ Starts the Authorization Code Grant flow for confidential clients.
291
+
292
+ #### `requestAccessTokenFromJwt({ jwt })`
293
+
294
+ Exchanges a JWT for an access token.
295
+
296
+ #### `createJwt(options)`
297
+
298
+ Creates a JWT token for guest authentication.
299
+
300
+ - `options.issuer` - Guest issuer ID
301
+ - `options.secretId` - Base64 encoded secret
302
+ - `options.displayName` - Optional display name
303
+ - `options.expiresIn` - Token expiration time
304
+
305
+ #### `logout(options)`
306
+
307
+ Logs out the current user.
308
+
309
+ - `options.noRedirect` - Skip redirect to logout page
310
+ - `options.goto` - Custom redirect URL after logout
311
+
312
+ ### Properties
313
+
314
+ #### `isAuthorizing` (boolean)
315
+
316
+ Indicates if an authorization flow is currently in progress.
317
+
318
+ #### `isAuthenticating` (boolean)
319
+
320
+ Alias for `isAuthorizing`.
321
+
322
+ #### `ready` (boolean)
323
+
324
+ Indicates if the authorization plugin has finished initialization.
325
+
326
+ ---
327
+
43
328
  ## Maintainers
44
329
 
45
- This package is maintained by [Cisco Webex for Developers](https://developer.webex.com/).
330
+ This package is maintained by Cisco Webex for Developers.
46
331
 
47
332
  ## Contribute
48
333
 
49
- Pull requests welcome. Please see [CONTRIBUTING.md](https://github.com/webex/webex-js-sdk/blob/master/CONTRIBUTING.md) for more details.
334
+ Pull requests welcome. Please see CONTRIBUTING.md for more details.
50
335
 
51
336
  ## License
52
337
 
53
- © 2016-2020 Cisco and/or its affiliates. All Rights Reserved.
338
+ This project is licensed under the Cisco General Terms - see the LICENSE for details.
339
+
340
+ © 2016-2025 Cisco and/or its affiliates. All Rights Reserved.
@@ -421,7 +421,7 @@ var Authorization = _webexCore.WebexPlugin.extend((_dec = (0, _common.whileInFli
421
421
  throw new Error("CSRF token ".concat(token, " does not match stored token ").concat(sessionToken));
422
422
  }
423
423
  },
424
- version: "3.8.1"
424
+ version: "3.9.0-next.1"
425
425
  }, ((0, _applyDecoratedDescriptor2.default)(_obj, "initiateImplicitGrant", [_dec], (0, _getOwnPropertyDescriptor.default)(_obj, "initiateImplicitGrant"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "initiateAuthorizationCodeGrant", [_dec2], (0, _getOwnPropertyDescriptor.default)(_obj, "initiateAuthorizationCodeGrant"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "requestAccessTokenFromJwt", [_common.oneFlight], (0, _getOwnPropertyDescriptor.default)(_obj, "requestAccessTokenFromJwt"), _obj)), _obj)));
426
426
  var _default = exports.default = Authorization;
427
427
  //# sourceMappingURL=authorization.js.map
package/package.json CHANGED
@@ -24,23 +24,23 @@
24
24
  "@webex/eslint-config-legacy": "0.0.0",
25
25
  "@webex/jest-config-legacy": "0.0.0",
26
26
  "@webex/legacy-tools": "0.0.0",
27
- "@webex/test-helper-appid": "3.8.1",
28
- "@webex/test-helper-automation": "3.8.1",
29
- "@webex/test-helper-chai": "3.8.1",
30
- "@webex/test-helper-mocha": "3.8.1",
31
- "@webex/test-helper-mock-webex": "3.8.1",
32
- "@webex/test-helper-test-users": "3.8.1",
27
+ "@webex/test-helper-appid": "3.8.1-next.11",
28
+ "@webex/test-helper-automation": "3.8.1-next.11",
29
+ "@webex/test-helper-chai": "3.8.1-next.11",
30
+ "@webex/test-helper-mocha": "3.8.1-next.11",
31
+ "@webex/test-helper-mock-webex": "3.8.1-next.11",
32
+ "@webex/test-helper-test-users": "3.8.1-next.11",
33
33
  "eslint": "^8.24.0",
34
34
  "prettier": "^2.7.1",
35
35
  "sinon": "^9.2.4"
36
36
  },
37
37
  "dependencies": {
38
- "@webex/common": "3.8.1",
39
- "@webex/internal-plugin-device": "3.8.1",
40
- "@webex/plugin-authorization-node": "3.8.1",
41
- "@webex/storage-adapter-local-storage": "3.8.1",
42
- "@webex/storage-adapter-spec": "3.8.1",
43
- "@webex/webex-core": "3.8.1",
38
+ "@webex/common": "3.8.1-next.11",
39
+ "@webex/internal-plugin-device": "3.9.0-next.1",
40
+ "@webex/plugin-authorization-node": "3.9.0-next.1",
41
+ "@webex/storage-adapter-local-storage": "3.9.0-next.1",
42
+ "@webex/storage-adapter-spec": "3.8.1-next.11",
43
+ "@webex/webex-core": "3.9.0-next.1",
44
44
  "jsonwebtoken": "^9.0.2",
45
45
  "lodash": "^4.17.21",
46
46
  "uuid": "^3.3.2"
@@ -54,5 +54,5 @@
54
54
  "test:style": "eslint ./src/**/*.*",
55
55
  "test:unit": "webex-legacy-tools test --unit --runner jest"
56
56
  },
57
- "version": "3.8.1"
57
+ "version": "3.9.0-next.1"
58
58
  }