@webex/plugin-authorization-browser-first-party 3.8.1 → 3.9.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 +216 -26
- package/dist/authorization.js +240 -66
- package/dist/authorization.js.map +1 -1
- package/package.json +13 -13
- package/src/authorization.js +235 -75
package/README.md
CHANGED
|
@@ -1,14 +1,30 @@
|
|
|
1
1
|
# @webex/plugin-authorization-browser-first-party
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
- [
|
|
9
|
-
- [
|
|
10
|
-
- [
|
|
11
|
-
- [
|
|
3
|
+
> First-party (Webex Web Client) browser authorization plugin. Implements hardened OAuth 2.0 Authorization Code + PKCE handling, CSRF protection, URL sanitization, and Device Authorization (QR Code) support used by the official Webex web experience.
|
|
4
|
+
> NOT intended for general third‑party application use – prefer `@webex/plugin-authorization-browser` or `@webex/plugin-authorization` (auto environment selection) unless you explicitly maintain the Webex first-party client.
|
|
5
|
+
|
|
6
|
+
## Table of Contents
|
|
7
|
+
|
|
8
|
+
- [@webex/plugin-authorization-browser-first-party](#webexplugin-authorization-browser-first-party)
|
|
9
|
+
- [Table of Contents](#table-of-contents)
|
|
10
|
+
- [Install](#install)
|
|
11
|
+
- [What It Does](#what-it-does)
|
|
12
|
+
- [When To Use This Package](#when-to-use-this-package)
|
|
13
|
+
- [Key Features](#key-features)
|
|
14
|
+
- [Basic Usage](#basic-usage)
|
|
15
|
+
- [Standard Login (Authorization Code + PKCE)](#standard-login-authorization-code--pkce)
|
|
16
|
+
- [Popup / Separate Window Login](#popup--separate-window-login)
|
|
17
|
+
- [Device Authorization (QR Code Login)](#device-authorization-qr-code-login)
|
|
18
|
+
- [Events](#events)
|
|
19
|
+
- [API Reference](#api-reference)
|
|
20
|
+
- [Methods](#methods)
|
|
21
|
+
- [Properties](#properties)
|
|
22
|
+
- [Security Considerations](#security-considerations)
|
|
23
|
+
- [Error Handling](#error-handling)
|
|
24
|
+
- [Related Packages](#related-packages)
|
|
25
|
+
- [Contribute](#contribute)
|
|
26
|
+
- [Maintainers](#maintainers)
|
|
27
|
+
- [License](#license)
|
|
12
28
|
|
|
13
29
|
## Install
|
|
14
30
|
|
|
@@ -16,38 +32,212 @@
|
|
|
16
32
|
npm install --save @webex/plugin-authorization-browser-first-party
|
|
17
33
|
```
|
|
18
34
|
|
|
19
|
-
##
|
|
35
|
+
## What It Does
|
|
20
36
|
|
|
21
|
-
This
|
|
37
|
+
This plugin provides a specialized browser-only implementation of OAuth 2.0 flows tailored for the Webex first-party web application. It:
|
|
22
38
|
|
|
23
|
-
|
|
39
|
+
- Detects redirects containing an authorization `code`
|
|
40
|
+
- Validates and removes transient sensitive parameters (`code`, CSRF token) from the URL
|
|
41
|
+
- Implements PKCE (S256) generation + verification
|
|
42
|
+
- Exchanges the authorization code for an access + refresh (supertoken) bundle
|
|
43
|
+
- Optionally pre-collects a *preauth service catalog* using hints (email hash / orgId)
|
|
44
|
+
- Supports device (QR Code) authorization polling for login via secondary devices
|
|
24
45
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
46
|
+
## When To Use This Package
|
|
47
|
+
|
|
48
|
+
Use this package **only** if you are:
|
|
49
|
+
|
|
50
|
+
- Working directly on the Webex first-party browser client
|
|
51
|
+
- Needing feature parity with internal flows (preauth catalog, QR device login)
|
|
52
|
+
- Debugging or extending internal auth behavior in the mono-repo
|
|
53
|
+
|
|
54
|
+
Otherwise choose:
|
|
55
|
+
|
|
56
|
+
| Use Case | Recommended Package |
|
|
57
|
+
| -------------------------- | ------------------------------------- |
|
|
58
|
+
| Generic browser SPA | `@webex/plugin-authorization-browser` |
|
|
59
|
+
| Auto environment selection | `@webex/plugin-authorization` |
|
|
60
|
+
| Node.js / server-side | `@webex/plugin-authorization-node` |
|
|
61
|
+
|
|
62
|
+
## Key Features
|
|
63
|
+
|
|
64
|
+
| Feature | Description |
|
|
65
|
+
| ------------------------- | -------------------------------------------------------------------- |
|
|
66
|
+
| Authorization Code + PKCE | Secure code flow with SHA256 (S256) code challenge |
|
|
67
|
+
| CSRF Protection | Random state-bound CSRF token validated on return |
|
|
68
|
+
| URL Sanitization | Removes `code` & CSRF artifacts post-redirect to reduce leakage risk |
|
|
69
|
+
| Preauth Catalog Hinting | Uses `emailhash` or extracted `orgId` to prefetch service catalog |
|
|
70
|
+
| Device Authorization (QR) | Implements OAuth Device Code grant with polling + slow-down handling |
|
|
71
|
+
| Popup Support | Optional separate window login (configurable dimensions) |
|
|
72
|
+
| Event Emitter | Emits granular events for QR/device flow progress |
|
|
73
|
+
| Supertoken Storage | Consolidated access + refresh token assignment to credentials plugin |
|
|
28
74
|
|
|
29
|
-
## Usage
|
|
75
|
+
## Basic Usage
|
|
30
76
|
|
|
31
|
-
|
|
77
|
+
> NOTE: This plugin is *internal*; examples below assume you intentionally select this package.
|
|
32
78
|
|
|
79
|
+
```javascript
|
|
33
80
|
const Webex = require('webex');
|
|
34
81
|
|
|
35
|
-
const webex = Webex.init(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
82
|
+
const webex = Webex.init({
|
|
83
|
+
credentials: {
|
|
84
|
+
client_id: 'first-party-client-id',
|
|
85
|
+
client_secret: 'first-party-client-secret',
|
|
86
|
+
redirect_uri: 'https://web.webex.com/auth/callback',
|
|
87
|
+
scope: 'spark:all'
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// Initiate login (generates PKCE + CSRF + email hash if provided)
|
|
92
|
+
webex.authorization.initiateLogin({
|
|
93
|
+
email: 'user@example.com', // optional; hashed internally
|
|
94
|
+
state: { returnTo: '/home' }, // additional app state
|
|
95
|
+
separateWindow: { width: 600, height: 800 } // popup mode (optional)
|
|
96
|
+
});
|
|
97
|
+
```
|
|
40
98
|
|
|
99
|
+
### Standard Login (Authorization Code + PKCE)
|
|
100
|
+
|
|
101
|
+
1. `initiateLogin()` creates:
|
|
102
|
+
- CSRF token
|
|
103
|
+
- PKCE code_verifier + code_challenge
|
|
104
|
+
- Encoded state (base64) containing security + optional fields
|
|
105
|
+
2. Browser navigates to IdBroker
|
|
106
|
+
3. Redirect returns with `?code=...&state=...`
|
|
107
|
+
4. Plugin `initialize()`:
|
|
108
|
+
- Validates CSRF
|
|
109
|
+
- Cleans URL
|
|
110
|
+
- Exchanges code (`requestAuthorizationCodeGrant`)
|
|
111
|
+
- Stores tokens on `webex.credentials`
|
|
112
|
+
|
|
113
|
+
### Popup / Separate Window Login
|
|
114
|
+
|
|
115
|
+
```javascript
|
|
116
|
+
webex.authorization.initiateLogin({
|
|
117
|
+
separateWindow: true // or object with window features
|
|
118
|
+
});
|
|
41
119
|
```
|
|
42
120
|
|
|
43
|
-
|
|
121
|
+
### Device Authorization (QR Code Login)
|
|
122
|
+
|
|
123
|
+
```javascript
|
|
124
|
+
// Subscribe to QR code events
|
|
125
|
+
webex.authorization.eventEmitter.on(
|
|
126
|
+
webex.authorization.Events.qRCodeLogin,
|
|
127
|
+
({eventType, userData, data}) => {
|
|
128
|
+
switch (eventType) {
|
|
129
|
+
case 'getUserCodeSuccess':
|
|
130
|
+
// Display userData.userCode & create QR pointing to userData.verificationUriComplete
|
|
131
|
+
break;
|
|
132
|
+
case 'authorizationPending':
|
|
133
|
+
// Still waiting for user to complete action
|
|
134
|
+
break;
|
|
135
|
+
case 'authorizationSuccess':
|
|
136
|
+
// Tokens available in data (supertoken already set)
|
|
137
|
+
break;
|
|
138
|
+
case 'authorizationFailure':
|
|
139
|
+
case 'getUserCodeFailure':
|
|
140
|
+
// Handle error
|
|
141
|
+
break;
|
|
142
|
+
case 'pollingCanceled':
|
|
143
|
+
// User canceled or timed out
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
// Begin device (QR) login
|
|
150
|
+
webex.authorization.initQRCodeLogin();
|
|
151
|
+
|
|
152
|
+
// Optional cancel
|
|
153
|
+
// webex.authorization.cancelQRCodePolling();
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Events
|
|
157
|
+
|
|
158
|
+
| Event `eventType` | Emitted When | Payload Fields |
|
|
159
|
+
| ---------------------- | ------------------------------------------- | ----------------------------------------------------------------------------------- |
|
|
160
|
+
| `getUserCodeSuccess` | Device code created | `userData.userCode`, `userData.verificationUri`, `userData.verificationUriComplete` |
|
|
161
|
+
| `getUserCodeFailure` | User code request failed | `data` (error body/message) |
|
|
162
|
+
| `authorizationPending` | Polling continues (428) | `data` (server body) |
|
|
163
|
+
| `authorizationSuccess` | Device code exchanged | `data` (token response) |
|
|
164
|
+
| `authorizationFailure` | Terminal polling error or timeout | `data` (error body/message) |
|
|
165
|
+
| `pollingCanceled` | Explicit cancel or internal timeout cleanup | none |
|
|
166
|
+
|
|
167
|
+
## API Reference
|
|
168
|
+
|
|
169
|
+
### Methods
|
|
170
|
+
|
|
171
|
+
| Method | Description |
|
|
172
|
+
| ------------------------------------------------------- | ------------------------------------------------------------------------ |
|
|
173
|
+
| `initiateLogin(options)` | Starts PKCE + CSRF protected Authorization Code flow (popup or redirect) |
|
|
174
|
+
| `initiateAuthorizationCodeGrant(options)` | Low-level redirect builder (normally called via `initiateLogin`) |
|
|
175
|
+
| `requestAuthorizationCodeGrant({ code, codeVerifier })` | Exchanges authorization code for token bundle |
|
|
176
|
+
| `initQRCodeLogin()` | Initiates device authorization (QR) flow |
|
|
177
|
+
| `cancelQRCodePolling(withCancelEvent=true)` | Cancels active device authorization polling loop |
|
|
178
|
+
|
|
179
|
+
### Properties
|
|
180
|
+
|
|
181
|
+
| Property | Type | Description |
|
|
182
|
+
| ------------------ | ---------------- | --------------------------------------------------------- |
|
|
183
|
+
| `isAuthorizing` | boolean | True while a grant request is in flight |
|
|
184
|
+
| `isAuthenticating` | boolean | Alias of `isAuthorizing` |
|
|
185
|
+
| `ready` | boolean | Set true after initial redirect/code processing completes |
|
|
186
|
+
| `eventEmitter` | EventEmitter | Emits QR/Device login lifecycle events |
|
|
187
|
+
| `Events` | enum-like object | Accessible names for event types |
|
|
188
|
+
|
|
189
|
+
## Security Considerations
|
|
190
|
+
|
|
191
|
+
| Control | Purpose |
|
|
192
|
+
| ------------------- | ------------------------------------------------------------------ |
|
|
193
|
+
| CSRF Token in State | Prevents forged redirect responses |
|
|
194
|
+
| PKCE (S256) | Mitigates interception of authorization code |
|
|
195
|
+
| URL Cleanup | Prevents accidental sharing of `code` via history/referrers |
|
|
196
|
+
| Single-use Storage | `code_verifier` & CSRF token removed immediately after use |
|
|
197
|
+
| Email Hashing | Uses SHA256(email) to reduce raw PII propagation for preauth hints |
|
|
198
|
+
|
|
199
|
+
## Error Handling
|
|
200
|
+
|
|
201
|
+
- OAuth errors returned during redirect raise mapped `grantErrors`
|
|
202
|
+
- Device flow handles `slow_down` (400) by exponential interval adjustment
|
|
203
|
+
- Status `428` considered pending (continues polling)
|
|
204
|
+
- Terminal errors emit `authorizationFailure`
|
|
205
|
+
|
|
206
|
+
Example:
|
|
207
|
+
|
|
208
|
+
```javascript
|
|
209
|
+
webex.authorization.requestAuthorizationCodeGrant({ code })
|
|
210
|
+
.catch(err => {
|
|
211
|
+
if (err.name === 'InvalidGrantError') {
|
|
212
|
+
// Handle invalid/expired code
|
|
213
|
+
} else {
|
|
214
|
+
console.error('Authorization failure', err);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Related Packages
|
|
44
220
|
|
|
45
|
-
|
|
221
|
+
| Package | Purpose |
|
|
222
|
+
| ------------------------------------- | ------------------------------------------ |
|
|
223
|
+
| `@webex/plugin-authorization` | Auto-selects env-specific implementation |
|
|
224
|
+
| `@webex/plugin-authorization-browser` | Public browser auth (implicit + code) |
|
|
225
|
+
| `@webex/plugin-authorization-node` | Node/server-side flows |
|
|
226
|
+
| `webex` | Unified SDK bundle including authorization |
|
|
227
|
+
|
|
228
|
+
Also see:
|
|
229
|
+
|
|
230
|
+
- [Browser OAuth Flow Guide](../plugin-authorization-browser/BROWSER-OAUTH-FLOW-GUIDE.md)
|
|
231
|
+
- [Node OAuth Flow Guide](../plugin-authorization-node/NODE-OAUTH-FLOW-GUIDE.md)
|
|
46
232
|
|
|
47
233
|
## Contribute
|
|
48
234
|
|
|
49
|
-
|
|
235
|
+
Internal changes should follow repository contribution guidelines. External users generally should *not* rely on this package. See [CONTRIBUTING.md](https://github.com/webex/webex-js-sdk/blob/master/CONTRIBUTING.md).
|
|
236
|
+
|
|
237
|
+
## Maintainers
|
|
238
|
+
|
|
239
|
+
This package is maintained by Cisco Webex for Developers.
|
|
50
240
|
|
|
51
241
|
## License
|
|
52
242
|
|
|
53
|
-
© 2016-
|
|
243
|
+
© 2016-2025 Cisco and/or its affiliates. All Rights Reserved.
|