@memberjunction/actions 2.113.1 → 2.114.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.
@@ -0,0 +1,209 @@
1
+ /**
2
+ * Configuration options for OAuth2Manager
3
+ */
4
+ export interface OAuth2Config {
5
+ /**
6
+ * OAuth2 client ID
7
+ */
8
+ clientId: string;
9
+ /**
10
+ * OAuth2 client secret
11
+ */
12
+ clientSecret: string;
13
+ /**
14
+ * Token endpoint URL (e.g., 'https://api.example.com/oauth/token')
15
+ */
16
+ tokenEndpoint: string;
17
+ /**
18
+ * Authorization endpoint URL (e.g., 'https://api.example.com/oauth/authorize')
19
+ * Only needed for authorization_code flow
20
+ */
21
+ authorizationEndpoint?: string;
22
+ /**
23
+ * Redirect URI for authorization_code flow
24
+ */
25
+ redirectUri?: string;
26
+ /**
27
+ * OAuth2 scopes to request
28
+ */
29
+ scopes?: string[];
30
+ /**
31
+ * Initial access token (if already obtained)
32
+ */
33
+ accessToken?: string;
34
+ /**
35
+ * Initial refresh token (if available)
36
+ */
37
+ refreshToken?: string;
38
+ /**
39
+ * Initial token expiration timestamp (milliseconds since epoch)
40
+ */
41
+ tokenExpiresAt?: number;
42
+ /**
43
+ * Buffer time in milliseconds before token expiration to trigger refresh (default: 60000 = 1 minute)
44
+ */
45
+ refreshBufferMs?: number;
46
+ /**
47
+ * Custom transformation for token response (for non-standard OAuth2 implementations)
48
+ */
49
+ tokenResponseTransform?: (response: any) => OAuth2TokenResponse;
50
+ /**
51
+ * Custom transformation for token request body (for provider-specific requirements)
52
+ */
53
+ tokenRequestTransform?: (params: Record<string, string>) => Record<string, string>;
54
+ /**
55
+ * Additional headers to include in token requests
56
+ */
57
+ additionalHeaders?: Record<string, string>;
58
+ /**
59
+ * Callback invoked when tokens are updated (for persistence)
60
+ */
61
+ onTokenUpdate?: (tokens: OAuth2TokenData) => void | Promise<void>;
62
+ }
63
+ /**
64
+ * Standard OAuth2 token response
65
+ */
66
+ export interface OAuth2TokenResponse {
67
+ access_token: string;
68
+ refresh_token?: string;
69
+ expires_in?: number;
70
+ token_type?: string;
71
+ scope?: string;
72
+ }
73
+ /**
74
+ * OAuth2 token data with computed expiration
75
+ */
76
+ export interface OAuth2TokenData {
77
+ accessToken: string;
78
+ refreshToken?: string;
79
+ expiresAt: number;
80
+ tokenType?: string;
81
+ scope?: string;
82
+ }
83
+ /**
84
+ * Generic OAuth2 token manager supporting multiple grant types and automatic token refresh.
85
+ *
86
+ * This class provides a standardized way to handle OAuth2 authentication flows including:
87
+ * - Authorization code flow (with PKCE support)
88
+ * - Client credentials flow
89
+ * - Refresh token flow
90
+ * - Direct access token usage
91
+ *
92
+ * Features:
93
+ * - Automatic token refresh before expiration
94
+ * - Thread-safe token refresh (prevents concurrent refresh requests)
95
+ * - Provider customization hooks for non-standard OAuth2 implementations
96
+ * - Token persistence callbacks
97
+ * - Support for multiple grant types
98
+ *
99
+ * @example
100
+ * ```typescript
101
+ * // Initialize with client credentials
102
+ * const oauth = new OAuth2Manager({
103
+ * clientId: 'your-client-id',
104
+ * clientSecret: 'your-client-secret',
105
+ * tokenEndpoint: 'https://api.example.com/oauth/token',
106
+ * authorizationEndpoint: 'https://api.example.com/oauth/authorize',
107
+ * scopes: ['read', 'write']
108
+ * });
109
+ *
110
+ * // Get a valid access token (auto-refreshes if needed)
111
+ * const token = await oauth.getAccessToken();
112
+ *
113
+ * // Use the token in API requests
114
+ * const response = await fetch('https://api.example.com/data', {
115
+ * headers: { 'Authorization': `Bearer ${token}` }
116
+ * });
117
+ * ```
118
+ */
119
+ export declare class OAuth2Manager {
120
+ private config;
121
+ private accessToken;
122
+ private refreshToken;
123
+ private tokenExpiresAt;
124
+ private refreshPromise;
125
+ /**
126
+ * Creates a new OAuth2Manager instance
127
+ *
128
+ * @param config - OAuth2 configuration options
129
+ */
130
+ constructor(config: OAuth2Config);
131
+ /**
132
+ * Gets the authorization URL for the authorization code flow
133
+ *
134
+ * @param state - Optional state parameter for CSRF protection
135
+ * @param additionalParams - Additional query parameters to include
136
+ * @returns The authorization URL
137
+ */
138
+ getAuthorizationUrl(state?: string, additionalParams?: Record<string, string>): string;
139
+ /**
140
+ * Exchanges an authorization code for an access token
141
+ *
142
+ * @param code - The authorization code received from the authorization endpoint
143
+ * @returns The token data
144
+ */
145
+ exchangeAuthorizationCode(code: string): Promise<OAuth2TokenData>;
146
+ /**
147
+ * Obtains an access token using client credentials flow
148
+ *
149
+ * @returns The token data
150
+ */
151
+ getClientCredentialsToken(): Promise<OAuth2TokenData>;
152
+ /**
153
+ * Refreshes the access token using the refresh token
154
+ *
155
+ * @returns The new token data
156
+ * @throws Error if no refresh token is available
157
+ */
158
+ refreshAccessToken(): Promise<OAuth2TokenData>;
159
+ /**
160
+ * Gets a valid access token, automatically refreshing if needed
161
+ *
162
+ * This is the main method to use when you need an access token for API requests.
163
+ * It handles token refresh automatically if the current token is expired or about to expire.
164
+ *
165
+ * @returns A valid access token
166
+ * @throws Error if no token is available and cannot be obtained
167
+ */
168
+ getAccessToken(): Promise<string>;
169
+ /**
170
+ * Performs the actual token refresh operation
171
+ *
172
+ * @private
173
+ * @returns The new access token
174
+ */
175
+ private performTokenRefresh;
176
+ /**
177
+ * Makes a token request to the OAuth2 server
178
+ *
179
+ * @private
180
+ * @param params - Token request parameters
181
+ * @returns The token data
182
+ */
183
+ private requestToken;
184
+ /**
185
+ * Checks if the current access token is valid (exists and not expired)
186
+ *
187
+ * @returns True if the token is valid, false otherwise
188
+ */
189
+ isTokenValid(): boolean;
190
+ /**
191
+ * Sets the access token directly (for cases where token is obtained externally)
192
+ *
193
+ * @param accessToken - The access token
194
+ * @param refreshToken - Optional refresh token
195
+ * @param expiresIn - Optional expiration time in seconds
196
+ */
197
+ setTokens(accessToken: string, refreshToken?: string, expiresIn?: number): void;
198
+ /**
199
+ * Clears all stored tokens
200
+ */
201
+ clearTokens(): void;
202
+ /**
203
+ * Gets the current token state (for debugging or persistence)
204
+ *
205
+ * @returns The current token data or null if no tokens are available
206
+ */
207
+ getTokenState(): OAuth2TokenData | null;
208
+ }
209
+ //# sourceMappingURL=OAuth2Manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OAuth2Manager.d.ts","sourceRoot":"","sources":["../../src/generic/OAuth2Manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,328 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OAuth2Manager = void 0;
4
+ /**
5
+ * Generic OAuth2 token manager supporting multiple grant types and automatic token refresh.
6
+ *
7
+ * This class provides a standardized way to handle OAuth2 authentication flows including:
8
+ * - Authorization code flow (with PKCE support)
9
+ * - Client credentials flow
10
+ * - Refresh token flow
11
+ * - Direct access token usage
12
+ *
13
+ * Features:
14
+ * - Automatic token refresh before expiration
15
+ * - Thread-safe token refresh (prevents concurrent refresh requests)
16
+ * - Provider customization hooks for non-standard OAuth2 implementations
17
+ * - Token persistence callbacks
18
+ * - Support for multiple grant types
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * // Initialize with client credentials
23
+ * const oauth = new OAuth2Manager({
24
+ * clientId: 'your-client-id',
25
+ * clientSecret: 'your-client-secret',
26
+ * tokenEndpoint: 'https://api.example.com/oauth/token',
27
+ * authorizationEndpoint: 'https://api.example.com/oauth/authorize',
28
+ * scopes: ['read', 'write']
29
+ * });
30
+ *
31
+ * // Get a valid access token (auto-refreshes if needed)
32
+ * const token = await oauth.getAccessToken();
33
+ *
34
+ * // Use the token in API requests
35
+ * const response = await fetch('https://api.example.com/data', {
36
+ * headers: { 'Authorization': `Bearer ${token}` }
37
+ * });
38
+ * ```
39
+ */
40
+ class OAuth2Manager {
41
+ /**
42
+ * Creates a new OAuth2Manager instance
43
+ *
44
+ * @param config - OAuth2 configuration options
45
+ */
46
+ constructor(config) {
47
+ this.accessToken = null;
48
+ this.refreshToken = null;
49
+ this.tokenExpiresAt = 0;
50
+ this.refreshPromise = null;
51
+ this.config = {
52
+ clientId: config.clientId,
53
+ clientSecret: config.clientSecret,
54
+ tokenEndpoint: config.tokenEndpoint,
55
+ authorizationEndpoint: config.authorizationEndpoint,
56
+ redirectUri: config.redirectUri,
57
+ scopes: config.scopes,
58
+ refreshBufferMs: config.refreshBufferMs ?? 60000, // Default 1 minute buffer
59
+ tokenResponseTransform: config.tokenResponseTransform,
60
+ tokenRequestTransform: config.tokenRequestTransform,
61
+ additionalHeaders: config.additionalHeaders,
62
+ onTokenUpdate: config.onTokenUpdate
63
+ };
64
+ // Initialize with provided tokens if available
65
+ if (config.accessToken) {
66
+ this.accessToken = config.accessToken;
67
+ }
68
+ if (config.refreshToken) {
69
+ this.refreshToken = config.refreshToken;
70
+ }
71
+ if (config.tokenExpiresAt) {
72
+ this.tokenExpiresAt = config.tokenExpiresAt;
73
+ }
74
+ }
75
+ /**
76
+ * Gets the authorization URL for the authorization code flow
77
+ *
78
+ * @param state - Optional state parameter for CSRF protection
79
+ * @param additionalParams - Additional query parameters to include
80
+ * @returns The authorization URL
81
+ */
82
+ getAuthorizationUrl(state, additionalParams) {
83
+ if (!this.config.authorizationEndpoint) {
84
+ throw new Error('Authorization endpoint not configured');
85
+ }
86
+ const params = new URLSearchParams({
87
+ client_id: this.config.clientId,
88
+ response_type: 'code',
89
+ ...additionalParams
90
+ });
91
+ if (this.config.redirectUri) {
92
+ params.append('redirect_uri', this.config.redirectUri);
93
+ }
94
+ if (this.config.scopes && this.config.scopes.length > 0) {
95
+ params.append('scope', this.config.scopes.join(' '));
96
+ }
97
+ if (state) {
98
+ params.append('state', state);
99
+ }
100
+ return `${this.config.authorizationEndpoint}?${params.toString()}`;
101
+ }
102
+ /**
103
+ * Exchanges an authorization code for an access token
104
+ *
105
+ * @param code - The authorization code received from the authorization endpoint
106
+ * @returns The token data
107
+ */
108
+ async exchangeAuthorizationCode(code) {
109
+ const params = {
110
+ grant_type: 'authorization_code',
111
+ code,
112
+ client_id: this.config.clientId,
113
+ client_secret: this.config.clientSecret
114
+ };
115
+ if (this.config.redirectUri) {
116
+ params.redirect_uri = this.config.redirectUri;
117
+ }
118
+ return this.requestToken(params);
119
+ }
120
+ /**
121
+ * Obtains an access token using client credentials flow
122
+ *
123
+ * @returns The token data
124
+ */
125
+ async getClientCredentialsToken() {
126
+ const params = {
127
+ grant_type: 'client_credentials',
128
+ client_id: this.config.clientId,
129
+ client_secret: this.config.clientSecret
130
+ };
131
+ if (this.config.scopes && this.config.scopes.length > 0) {
132
+ params.scope = this.config.scopes.join(' ');
133
+ }
134
+ return this.requestToken(params);
135
+ }
136
+ /**
137
+ * Refreshes the access token using the refresh token
138
+ *
139
+ * @returns The new token data
140
+ * @throws Error if no refresh token is available
141
+ */
142
+ async refreshAccessToken() {
143
+ if (!this.refreshToken) {
144
+ throw new Error('No refresh token available');
145
+ }
146
+ const params = {
147
+ grant_type: 'refresh_token',
148
+ refresh_token: this.refreshToken,
149
+ client_id: this.config.clientId,
150
+ client_secret: this.config.clientSecret
151
+ };
152
+ return this.requestToken(params);
153
+ }
154
+ /**
155
+ * Gets a valid access token, automatically refreshing if needed
156
+ *
157
+ * This is the main method to use when you need an access token for API requests.
158
+ * It handles token refresh automatically if the current token is expired or about to expire.
159
+ *
160
+ * @returns A valid access token
161
+ * @throws Error if no token is available and cannot be obtained
162
+ */
163
+ async getAccessToken() {
164
+ // If we have a valid token, return it
165
+ if (this.accessToken && this.isTokenValid()) {
166
+ return this.accessToken;
167
+ }
168
+ // If a refresh is already in progress, wait for it
169
+ if (this.refreshPromise) {
170
+ return this.refreshPromise;
171
+ }
172
+ // Start a new refresh operation
173
+ this.refreshPromise = this.performTokenRefresh();
174
+ try {
175
+ const token = await this.refreshPromise;
176
+ return token;
177
+ }
178
+ finally {
179
+ this.refreshPromise = null;
180
+ }
181
+ }
182
+ /**
183
+ * Performs the actual token refresh operation
184
+ *
185
+ * @private
186
+ * @returns The new access token
187
+ */
188
+ async performTokenRefresh() {
189
+ try {
190
+ let tokenData;
191
+ if (this.refreshToken) {
192
+ // Use refresh token if available
193
+ tokenData = await this.refreshAccessToken();
194
+ }
195
+ else {
196
+ // Fall back to client credentials if no refresh token
197
+ tokenData = await this.getClientCredentialsToken();
198
+ }
199
+ return tokenData.accessToken;
200
+ }
201
+ catch (error) {
202
+ throw new Error(`Failed to refresh access token: ${error instanceof Error ? error.message : String(error)}`);
203
+ }
204
+ }
205
+ /**
206
+ * Makes a token request to the OAuth2 server
207
+ *
208
+ * @private
209
+ * @param params - Token request parameters
210
+ * @returns The token data
211
+ */
212
+ async requestToken(params) {
213
+ try {
214
+ // Allow provider-specific transformations
215
+ const requestParams = this.config.tokenRequestTransform
216
+ ? this.config.tokenRequestTransform(params)
217
+ : params;
218
+ const headers = {
219
+ 'Content-Type': 'application/x-www-form-urlencoded',
220
+ ...this.config.additionalHeaders
221
+ };
222
+ const response = await fetch(this.config.tokenEndpoint, {
223
+ method: 'POST',
224
+ headers,
225
+ body: new URLSearchParams(requestParams)
226
+ });
227
+ if (!response.ok) {
228
+ const errorText = await response.text();
229
+ throw new Error(`Token request failed: ${response.status} ${response.statusText} - ${errorText}`);
230
+ }
231
+ const responseData = await response.json();
232
+ // Allow provider-specific response transformations
233
+ const tokenResponse = this.config.tokenResponseTransform
234
+ ? this.config.tokenResponseTransform(responseData)
235
+ : responseData;
236
+ // Update internal state
237
+ this.accessToken = tokenResponse.access_token;
238
+ if (tokenResponse.refresh_token) {
239
+ this.refreshToken = tokenResponse.refresh_token;
240
+ }
241
+ if (tokenResponse.expires_in) {
242
+ this.tokenExpiresAt = Date.now() + (tokenResponse.expires_in * 1000);
243
+ }
244
+ else {
245
+ // If no expires_in, assume token is long-lived (1 year)
246
+ this.tokenExpiresAt = Date.now() + (365 * 24 * 60 * 60 * 1000);
247
+ }
248
+ const tokenData = {
249
+ accessToken: this.accessToken,
250
+ refreshToken: this.refreshToken || undefined,
251
+ expiresAt: this.tokenExpiresAt,
252
+ tokenType: tokenResponse.token_type,
253
+ scope: tokenResponse.scope
254
+ };
255
+ // Invoke token update callback if provided
256
+ if (this.config.onTokenUpdate) {
257
+ await this.config.onTokenUpdate(tokenData);
258
+ }
259
+ return tokenData;
260
+ }
261
+ catch (error) {
262
+ throw new Error(`OAuth2 token request failed: ${error instanceof Error ? error.message : String(error)}`);
263
+ }
264
+ }
265
+ /**
266
+ * Checks if the current access token is valid (exists and not expired)
267
+ *
268
+ * @returns True if the token is valid, false otherwise
269
+ */
270
+ isTokenValid() {
271
+ if (!this.accessToken) {
272
+ return false;
273
+ }
274
+ // Check if token is expired or about to expire (within buffer time)
275
+ const now = Date.now();
276
+ const expiresWithBuffer = this.tokenExpiresAt - this.config.refreshBufferMs;
277
+ return now < expiresWithBuffer;
278
+ }
279
+ /**
280
+ * Sets the access token directly (for cases where token is obtained externally)
281
+ *
282
+ * @param accessToken - The access token
283
+ * @param refreshToken - Optional refresh token
284
+ * @param expiresIn - Optional expiration time in seconds
285
+ */
286
+ setTokens(accessToken, refreshToken, expiresIn) {
287
+ this.accessToken = accessToken;
288
+ if (refreshToken) {
289
+ this.refreshToken = refreshToken;
290
+ }
291
+ if (expiresIn) {
292
+ this.tokenExpiresAt = Date.now() + (expiresIn * 1000);
293
+ }
294
+ // Invoke token update callback if provided
295
+ if (this.config.onTokenUpdate) {
296
+ this.config.onTokenUpdate({
297
+ accessToken: this.accessToken,
298
+ refreshToken: this.refreshToken || undefined,
299
+ expiresAt: this.tokenExpiresAt
300
+ });
301
+ }
302
+ }
303
+ /**
304
+ * Clears all stored tokens
305
+ */
306
+ clearTokens() {
307
+ this.accessToken = null;
308
+ this.refreshToken = null;
309
+ this.tokenExpiresAt = 0;
310
+ }
311
+ /**
312
+ * Gets the current token state (for debugging or persistence)
313
+ *
314
+ * @returns The current token data or null if no tokens are available
315
+ */
316
+ getTokenState() {
317
+ if (!this.accessToken) {
318
+ return null;
319
+ }
320
+ return {
321
+ accessToken: this.accessToken,
322
+ refreshToken: this.refreshToken || undefined,
323
+ expiresAt: this.tokenExpiresAt
324
+ };
325
+ }
326
+ }
327
+ exports.OAuth2Manager = OAuth2Manager;
328
+ //# sourceMappingURL=OAuth2Manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OAuth2Manager.js","sourceRoot":"","sources":["../../src/generic/OAuth2Manager.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export * from './generic/BaseAction';
2
2
  export * from './generic/BaseActionFilter';
3
3
  export * from './generic/BaseOAuthAction';
4
4
  export * from './generic/ActionEngine';
5
+ export * from './generic/OAuth2Manager';
5
6
  export * from './entity-actions/EntityActionEngine';
6
7
  export * from './entity-actions/EntityActionInvocationTypes';
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AAEvC,cAAc,qCAAqC,CAAC;AACpD,cAAc,8CAA8C,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AAExC,cAAc,qCAAqC,CAAC;AACpD,cAAc,8CAA8C,CAAC"}
package/dist/index.js CHANGED
@@ -18,6 +18,7 @@ __exportStar(require("./generic/BaseAction"), exports);
18
18
  __exportStar(require("./generic/BaseActionFilter"), exports);
19
19
  __exportStar(require("./generic/BaseOAuthAction"), exports);
20
20
  __exportStar(require("./generic/ActionEngine"), exports);
21
+ __exportStar(require("./generic/OAuth2Manager"), exports);
21
22
  __exportStar(require("./entity-actions/EntityActionEngine"), exports);
22
23
  __exportStar(require("./entity-actions/EntityActionInvocationTypes"), exports);
23
24
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,uDAAqC;AACrC,6DAA2C;AAC3C,4DAA0C;AAC1C,yDAAuC;AAEvC,sEAAoD;AACpD,+EAA6D"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,uDAAqC;AACrC,6DAA2C;AAC3C,4DAA0C;AAC1C,yDAAuC;AACvC,0DAAwC;AAExC,sEAAoD;AACpD,+EAA6D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/actions",
3
- "version": "2.113.1",
3
+ "version": "2.114.0",
4
4
  "description": "Main library for MemberJunction Actions. This library is only intended to be imported on the server side.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -19,15 +19,15 @@
19
19
  "typescript": "^5.4.5"
20
20
  },
21
21
  "dependencies": {
22
- "@memberjunction/global": "2.113.1",
23
- "@memberjunction/core": "2.113.1",
24
- "@memberjunction/actions-base": "2.113.1",
25
- "@memberjunction/core-entities": "2.113.1",
26
- "@memberjunction/ai": "2.113.1",
27
- "@memberjunction/ai-core-plus": "2.113.1",
28
- "@memberjunction/aiengine": "2.113.1",
29
- "@memberjunction/ai-prompts": "2.113.1",
30
- "@memberjunction/doc-utils": "2.113.1"
22
+ "@memberjunction/global": "2.114.0",
23
+ "@memberjunction/core": "2.114.0",
24
+ "@memberjunction/actions-base": "2.114.0",
25
+ "@memberjunction/core-entities": "2.114.0",
26
+ "@memberjunction/ai": "2.114.0",
27
+ "@memberjunction/ai-core-plus": "2.114.0",
28
+ "@memberjunction/aiengine": "2.114.0",
29
+ "@memberjunction/ai-prompts": "2.114.0",
30
+ "@memberjunction/doc-utils": "2.114.0"
31
31
  },
32
32
  "repository": {
33
33
  "type": "git",
package/readme.md CHANGED
@@ -437,6 +437,45 @@ This package integrates seamlessly with:
437
437
  - **@memberjunction/core-entities**: Provides strongly-typed entity classes
438
438
  - **@memberjunction/global**: Manages class registration and instantiation
439
439
 
440
+ ## OAuth2Manager (Server-Side Only)
441
+
442
+ The package includes a generic OAuth2 token manager for server-side integrations:
443
+
444
+ ```typescript
445
+ import { OAuth2Manager } from '@memberjunction/actions';
446
+
447
+ // Initialize OAuth2 manager
448
+ const oauth = new OAuth2Manager({
449
+ clientId: process.env.OAUTH_CLIENT_ID,
450
+ clientSecret: process.env.OAUTH_CLIENT_SECRET,
451
+ tokenEndpoint: 'https://api.example.com/oauth/token',
452
+ authorizationEndpoint: 'https://api.example.com/oauth/authorize',
453
+ scopes: ['read', 'write'],
454
+ onTokenUpdate: async (tokens) => {
455
+ // Persist updated tokens to database
456
+ await saveTokens(tokens);
457
+ }
458
+ });
459
+
460
+ // Get authorization URL for user to visit
461
+ const authUrl = oauth.getAuthorizationUrl('random-state-string');
462
+
463
+ // Exchange authorization code for tokens
464
+ const tokens = await oauth.exchangeAuthorizationCode(code);
465
+
466
+ // Get valid access token (auto-refreshes if needed)
467
+ const accessToken = await oauth.getAccessToken();
468
+ ```
469
+
470
+ **Features:**
471
+ - Multiple grant type support (authorization_code, client_credentials, refresh_token)
472
+ - Automatic token refresh before expiration
473
+ - Thread-safe token refresh (prevents concurrent requests)
474
+ - Token persistence callbacks
475
+ - Provider customization hooks for non-standard OAuth2 implementations
476
+
477
+ **⚠️ Server-Side Only**: OAuth2Manager requires `process.env` and should only be used in Node.js server environments, not in browser/client code.
478
+
440
479
  ## Advanced Topics
441
480
 
442
481
  ### Custom Action Engines