@agility/management-sdk 0.1.3 → 0.1.4-beta.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.
Files changed (238) hide show
  1. package/.cursor/api-documentation-manifest.md +275 -0
  2. package/.cursor/api-functions-analysis.md +111 -0
  3. package/.cursor/docs-final-check.md +269 -0
  4. package/.cursor/manifest.md +153 -0
  5. package/.env +92 -0
  6. package/README.md +219 -352
  7. package/dist/apiClient.d.ts +86 -0
  8. package/dist/apiClient.js +229 -0
  9. package/dist/apiClient.js.map +1 -0
  10. package/dist/apiMethods/assetMethods.d.ts +28 -6
  11. package/dist/apiMethods/assetMethods.js +224 -29
  12. package/dist/apiMethods/assetMethods.js.map +1 -0
  13. package/dist/apiMethods/authMethods.d.ts +239 -0
  14. package/dist/apiMethods/authMethods.js +604 -0
  15. package/dist/apiMethods/batchMethods.d.ts +32 -1
  16. package/dist/apiMethods/batchMethods.js +241 -11
  17. package/dist/apiMethods/batchMethods.js.map +1 -0
  18. package/dist/apiMethods/clientInstance.d.ts +58 -4
  19. package/dist/apiMethods/clientInstance.js +311 -44
  20. package/dist/apiMethods/clientInstance.js.map +1 -0
  21. package/dist/apiMethods/containerMethods.d.ts +15 -7
  22. package/dist/apiMethods/containerMethods.js +70 -38
  23. package/dist/apiMethods/containerMethods.js.map +1 -0
  24. package/dist/apiMethods/contentMethods.d.ts +17 -10
  25. package/dist/apiMethods/contentMethods.js +169 -70
  26. package/dist/apiMethods/contentMethods.js.map +1 -0
  27. package/dist/apiMethods/instanceMethods.d.ts +9 -0
  28. package/dist/apiMethods/instanceMethods.js +69 -0
  29. package/dist/apiMethods/instanceMethods.js.map +1 -0
  30. package/dist/apiMethods/instanceUserMethods.d.ts +3 -3
  31. package/dist/apiMethods/instanceUserMethods.js +18 -18
  32. package/dist/apiMethods/instanceUserMethods.js.map +1 -0
  33. package/dist/apiMethods/modelMethods.d.ts +6 -5
  34. package/dist/apiMethods/modelMethods.js +46 -26
  35. package/dist/apiMethods/modelMethods.js.map +1 -0
  36. package/dist/apiMethods/pageMethods.d.ts +21 -9
  37. package/dist/apiMethods/pageMethods.js +278 -76
  38. package/dist/apiMethods/pageMethods.js.map +1 -0
  39. package/dist/apiMethods/serverUserMethods.d.ts +10 -0
  40. package/dist/apiMethods/serverUserMethods.js +89 -0
  41. package/dist/apiMethods/serverUserMethods.js.map +1 -0
  42. package/dist/apiMethods/webhookMethods.d.ts +12 -0
  43. package/dist/apiMethods/webhookMethods.js +131 -0
  44. package/dist/apiMethods/webhookMethods.js.map +1 -0
  45. package/dist/enums/assetGroupingType.d.ts +3 -0
  46. package/dist/enums/assetGroupingType.js +7 -0
  47. package/dist/enums/assetGroupingType.js.map +1 -0
  48. package/dist/enums/batchItemType.d.ts +7 -0
  49. package/dist/enums/batchItemType.js +11 -0
  50. package/dist/enums/batchOperationType.js +1 -1
  51. package/dist/enums/batchOperationType.js.map +1 -0
  52. package/dist/enums/batchState..js +1 -1
  53. package/dist/enums/batchState.d.ts +7 -0
  54. package/dist/enums/batchState.js +12 -0
  55. package/dist/enums/batchState.js.map +1 -0
  56. package/dist/enums/pageItemTemplateType.d.ts +4 -0
  57. package/dist/enums/pageItemTemplateType.js +8 -0
  58. package/dist/enums/pageItemTemplateType.js.map +1 -0
  59. package/dist/enums/workflowOperationType.d.ts +26 -0
  60. package/dist/enums/workflowOperationType.js +30 -0
  61. package/dist/errors/exception.d.ts +4 -0
  62. package/dist/errors/exception.js +11 -0
  63. package/dist/errors/exception.js.map +1 -0
  64. package/dist/index.d.ts +41 -9
  65. package/dist/index.js +48 -10
  66. package/dist/index.js.map +1 -0
  67. package/dist/models/assetContainer.d.ts +7 -0
  68. package/dist/models/assetContainer.js +9 -0
  69. package/dist/models/assetGalleries.d.ts +5 -0
  70. package/dist/models/assetGalleries.js +9 -0
  71. package/dist/models/assetMediaGrouping.d.ts +17 -0
  72. package/dist/models/assetMediaGrouping.js +9 -0
  73. package/dist/models/assetMediaGroupingMetaData.d.ts +4 -0
  74. package/dist/models/assetMediaGroupingMetaData.js +9 -0
  75. package/dist/models/authTokens.d.ts +73 -0
  76. package/dist/models/authTokens.js +2 -0
  77. package/dist/models/batchItem.d.ts +1 -0
  78. package/dist/models/batchRequests.d.ts +67 -0
  79. package/dist/models/batchRequests.js +2 -0
  80. package/dist/models/batchTypes.d.ts +34 -0
  81. package/dist/models/batchTypes.js +2 -0
  82. package/dist/models/container.d.ts +2 -1
  83. package/dist/models/contentDefinitionTypeID.d.ts +17 -0
  84. package/dist/models/contentDefinitionTypeID.js +21 -0
  85. package/dist/models/contentItemHistory.d.ts +20 -0
  86. package/dist/models/contentItemHistory.js +15 -0
  87. package/dist/models/contentListFilterModel.d.ts +26 -0
  88. package/dist/models/contentListFilterModel.js +33 -0
  89. package/dist/models/contentSectionDefaultModule.d.ts +7 -0
  90. package/dist/models/contentSectionDefaultModule.js +9 -0
  91. package/dist/models/contentSectionDefinition.d.ts +35 -0
  92. package/dist/models/contentSectionDefinition.js +9 -0
  93. package/dist/models/exception.js +2 -0
  94. package/dist/models/itemComments.d.ts +14 -0
  95. package/dist/models/itemComments.js +15 -0
  96. package/dist/models/listParams.d.ts +9 -0
  97. package/dist/models/listParams.js +16 -0
  98. package/dist/models/locales.d.ts +3 -0
  99. package/dist/models/locales.js +30 -0
  100. package/dist/models/options.d.ts +2 -5
  101. package/dist/models/options.js +0 -19
  102. package/dist/models/pageHistory.d.ts +21 -0
  103. package/dist/models/pageHistory.js +15 -0
  104. package/dist/models/pageModel.d.ts +14 -0
  105. package/dist/models/pageModel.js +9 -0
  106. package/dist/models/serverUser.d.ts +21 -0
  107. package/dist/models/serverUser.js +9 -0
  108. package/dist/models/sharedModule.d.ts +7 -0
  109. package/dist/models/sharedModule.js +9 -0
  110. package/dist/models/webhook.d.ts +9 -0
  111. package/dist/models/webhook.js +9 -0
  112. package/dist/models/websiteListing.d.ts +16 -0
  113. package/dist/models/websiteListing.js +9 -0
  114. package/dist/tests/authHelper.d.ts +2 -0
  115. package/dist/tests/authHelper.js +14 -0
  116. package/dist/tests/authHelper.js.map +1 -0
  117. package/dist/tests/config/apiClient.config.d.ts +16 -0
  118. package/dist/tests/config/apiClient.config.js +84 -0
  119. package/dist/tests/config/apiClient.config.js.map +1 -0
  120. package/dist/tests/config/test.config.d.ts +24 -0
  121. package/dist/tests/config/test.config.js +47 -0
  122. package/dist/tests/config/test.config.js.map +1 -0
  123. package/dist/tokenStorage.d.ts +72 -0
  124. package/dist/tokenStorage.js +366 -0
  125. package/dist/types/apiResponse.d.ts +13 -0
  126. package/dist/types/apiResponse.js +3 -0
  127. package/dist/types/apiResponse.js.map +1 -0
  128. package/dist/types/assetContainer.d.ts +7 -0
  129. package/dist/types/assetContainer.js +3 -0
  130. package/dist/types/assetContainer.js.map +1 -0
  131. package/dist/types/assetGalleries.d.ts +5 -0
  132. package/dist/types/assetGalleries.js +3 -0
  133. package/dist/types/assetGalleries.js.map +1 -0
  134. package/dist/types/assetMediaGrouping.d.ts +17 -0
  135. package/dist/types/assetMediaGrouping.js +3 -0
  136. package/dist/types/assetMediaGrouping.js.map +1 -0
  137. package/dist/types/assetMediaGroupingMetaData.d.ts +4 -0
  138. package/dist/types/assetMediaGroupingMetaData.js +3 -0
  139. package/dist/types/assetMediaGroupingMetaData.js.map +1 -0
  140. package/dist/types/batch.d.ts +29 -0
  141. package/dist/types/batch.js +3 -0
  142. package/dist/types/batch.js.map +1 -0
  143. package/dist/types/batchItem.d.ts +13 -0
  144. package/dist/types/batchItem.js +3 -0
  145. package/dist/types/batchItem.js.map +1 -0
  146. package/dist/types/container.d.ts +47 -0
  147. package/dist/types/container.js +3 -0
  148. package/dist/types/container.js.map +1 -0
  149. package/dist/types/contentItem.d.ts +37 -0
  150. package/dist/types/contentItem.js +3 -0
  151. package/dist/types/contentItem.js.map +1 -0
  152. package/dist/types/contentItemHistory.d.ts +20 -0
  153. package/dist/types/contentItemHistory.js +3 -0
  154. package/dist/types/contentItemHistory.js.map +1 -0
  155. package/dist/types/contentListFilterModel.d.ts +26 -0
  156. package/dist/types/contentListFilterModel.js +3 -0
  157. package/dist/types/contentListFilterModel.js.map +1 -0
  158. package/dist/types/contentSectionDefaultModule.d.ts +7 -0
  159. package/dist/types/contentSectionDefaultModule.js +3 -0
  160. package/dist/types/contentSectionDefaultModule.js.map +1 -0
  161. package/dist/types/contentSectionDefinition.d.ts +35 -0
  162. package/dist/types/contentSectionDefinition.js +3 -0
  163. package/dist/types/contentSectionDefinition.js.map +1 -0
  164. package/dist/types/contentViewColumn.d.ts +8 -0
  165. package/dist/types/contentViewColumn.js +3 -0
  166. package/dist/types/contentViewColumn.js.map +1 -0
  167. package/dist/types/instanceRole.d.ts +7 -0
  168. package/dist/types/instanceRole.js +3 -0
  169. package/dist/types/instanceRole.js.map +1 -0
  170. package/dist/types/instanceUser.d.ts +14 -0
  171. package/dist/types/instanceUser.js +3 -0
  172. package/dist/types/instanceUser.js.map +1 -0
  173. package/dist/types/itemComments.d.ts +14 -0
  174. package/dist/types/itemComments.js +3 -0
  175. package/dist/types/itemComments.js.map +1 -0
  176. package/dist/types/listParams.d.ts +9 -0
  177. package/dist/types/listParams.js +3 -0
  178. package/dist/types/listParams.js.map +1 -0
  179. package/dist/types/locales.d.ts +1 -0
  180. package/dist/types/locales.js +3 -0
  181. package/dist/types/locales.js.map +1 -0
  182. package/dist/types/media.d.ts +30 -0
  183. package/dist/types/media.js +3 -0
  184. package/dist/types/media.js.map +1 -0
  185. package/dist/types/model.d.ts +30 -0
  186. package/dist/types/model.js +3 -0
  187. package/dist/types/model.js.map +1 -0
  188. package/dist/types/notification.d.ts +13 -0
  189. package/dist/types/notification.js +3 -0
  190. package/dist/types/notification.js.map +1 -0
  191. package/dist/types/options.d.ts +7 -0
  192. package/dist/types/options.js +3 -0
  193. package/dist/types/options.js.map +1 -0
  194. package/dist/types/pageHistory.d.ts +21 -0
  195. package/dist/types/pageHistory.js +3 -0
  196. package/dist/types/pageHistory.js.map +1 -0
  197. package/dist/types/pageItem.d.ts +56 -0
  198. package/dist/types/pageItem.js +3 -0
  199. package/dist/types/pageItem.js.map +1 -0
  200. package/dist/types/pageModel.d.ts +14 -0
  201. package/dist/types/pageModel.js +3 -0
  202. package/dist/types/pageModel.js.map +1 -0
  203. package/dist/types/serverUser.d.ts +21 -0
  204. package/dist/types/serverUser.js +3 -0
  205. package/dist/types/serverUser.js.map +1 -0
  206. package/dist/types/sharedModule.d.ts +7 -0
  207. package/dist/types/sharedModule.js +3 -0
  208. package/dist/types/sharedModule.js.map +1 -0
  209. package/dist/types/sitemap.d.ts +20 -0
  210. package/dist/types/sitemap.js +3 -0
  211. package/dist/types/sitemap.js.map +1 -0
  212. package/dist/types/tokenResponseData.d.ts +10 -0
  213. package/dist/types/tokenResponseData.js +3 -0
  214. package/dist/types/tokenResponseData.js.map +1 -0
  215. package/dist/types/webhook.d.ts +9 -0
  216. package/dist/types/webhook.js +3 -0
  217. package/dist/types/webhook.js.map +1 -0
  218. package/dist/types/websiteListing.d.ts +16 -0
  219. package/dist/types/websiteListing.js +3 -0
  220. package/dist/types/websiteListing.js.map +1 -0
  221. package/dist/types/websiteUser.d.ts +22 -0
  222. package/dist/types/websiteUser.js +3 -0
  223. package/dist/types/websiteUser.js.map +1 -0
  224. package/docs/asset-methods.md +382 -0
  225. package/docs/auth.md +594 -0
  226. package/docs/batch-methods.md +244 -0
  227. package/docs/cicd.md +607 -0
  228. package/docs/container-methods.md +268 -0
  229. package/docs/content-methods.md +423 -0
  230. package/docs/instance-methods.md +105 -0
  231. package/docs/instance-user-methods.md +231 -0
  232. package/docs/model-methods.md +434 -0
  233. package/docs/multi-instance-operations.md +192 -0
  234. package/docs/page-methods.md +671 -0
  235. package/docs/server-user-methods.md +280 -0
  236. package/docs/webhook-methods.md +452 -0
  237. package/package.json +14 -10
  238. package/tsconfig.json +1 -1
package/docs/auth.md ADDED
@@ -0,0 +1,594 @@
1
+ # Agility CMS & Management API TypeScript SDK
2
+
3
+ ## Authentication & Setup
4
+
5
+ This guide covers how to authenticate with the Agility CMS Management API and initialize the SDK for making API requests.
6
+
7
+ **🚀 NEW: Simplified Authentication**
8
+ We now provide a streamlined authentication experience with secure token storage and automatic token refresh. The new `ApiClient.auth()` method handles the entire OAuth flow internally.
9
+
10
+ ### Prerequisites
11
+ 1. Valid Agility CMS credentials
12
+ 2. A configured OAuth application in your Agility CMS instance
13
+ 3. A valid redirect URI for OAuth flow
14
+ 4. **Node.js**: For secure token storage, keytar is required (`npm install keytar`)
15
+
16
+ ### Setup Instructions
17
+
18
+ #### Install keytar for Secure Token Storage
19
+ ```bash
20
+ npm install keytar
21
+ ```
22
+
23
+ **Platform Requirements:**
24
+ - **macOS**: Uses Keychain (built-in)
25
+ - **Windows**: Uses Windows Credential Store (built-in)
26
+ - **Linux**: Requires `libsecret` development package
27
+ ```bash
28
+ # Ubuntu/Debian
29
+ sudo apt-get install libsecret-1-dev
30
+
31
+ # Red Hat/CentOS
32
+ sudo yum install libsecret-devel
33
+ ```
34
+
35
+ ### Authentication Approaches
36
+
37
+ You have two options for authentication:
38
+
39
+ #### 1. **Recommended: Simple OAuth Flow**
40
+ Use the new `ApiClient.auth()` method for streamlined authentication:
41
+
42
+ ```typescript
43
+ import * as mgmtApi from '@agility/management-sdk';
44
+
45
+ // Simple OAuth authentication
46
+ const apiClient = new mgmtApi.ApiClient();
47
+ await apiClient.auth();
48
+
49
+ // Client is now authenticated - make API calls directly
50
+ const guid = "your-website-guid";
51
+ const locale = "en-us";
52
+ const contentItem = await apiClient.contentMethods.getContentItem(22, guid, locale);
53
+ ```
54
+
55
+ The `auth()` method:
56
+ - Generates OAuth authorization URL
57
+ - Handles token exchange automatically
58
+ - Stores tokens securely using keytar
59
+ - Provides automatic token refresh
60
+
61
+ #### 2. **Manual Token Management (Existing Pattern)**
62
+ For applications that need to handle tokens manually, the traditional approach is still fully supported:
63
+
64
+ ```typescript
65
+ import * as mgmtApi from "@agility/management-sdk";
66
+
67
+ // Manual token approach (still supported)
68
+ const options = new mgmtApi.Options();
69
+ options.token = "your-access-token";
70
+ const apiClient = new mgmtApi.ApiClient(options);
71
+
72
+ const guid = "your-website-guid";
73
+ const locale = "en-us";
74
+
75
+ const contentItem = await apiClient.contentMethods.getContentItem(22, guid, locale);
76
+ console.log(JSON.stringify(contentItem));
77
+ ```
78
+
79
+ For custom OAuth implementations, you can handle the OAuth flow manually:
80
+
81
+ Before using the SDK, you must authenticate against the Agility Management API to obtain a valid access token. This token is required for all subsequent API requests.
82
+
83
+ The authentication process uses OAuth 2.0 and requires multiple steps:
84
+
85
+ #### Step 1: Initiate Authorization Flow
86
+
87
+ First, initiate the authorization flow by making a GET request to the authorization endpoint:
88
+
89
+ ```javascript
90
+ const authUrl = 'https://mgmt.aglty.io/oauth/authorize';
91
+
92
+ //if you wish to implement offline access using refresh tokens, use this URL (enables refresh tokens)
93
+ //const authUrl = 'https://mgmt.aglty.io/oauth/authorize?scope=offline-access ';
94
+
95
+ const params = new URLSearchParams({
96
+ response_type: 'code',
97
+ redirect_uri: 'YOUR_REDIRECT_URI',
98
+ state: 'YOUR_STATE',
99
+ scope: 'openid profile email offline_access'
100
+ });
101
+
102
+ // Redirect the user to the authorization URL
103
+ window.location.href = `${authUrl}?${params.toString()}`;
104
+ ```
105
+
106
+ #### Step 2: Exchange Authorization Code for Access Token
107
+
108
+ After successful authentication, you'll receive an authorization code at your redirect URI. Use this code to obtain an access token:
109
+
110
+ ```javascript
111
+ const response = await fetch('https://mgmt.aglty.io/oauth/token', {
112
+ method: 'POST',
113
+ headers: {
114
+ 'Content-Type': 'application/x-www-form-urlencoded'
115
+ },
116
+ body: new URLSearchParams({
117
+ code: 'YOUR_AUTHORIZATION_CODE'
118
+ })
119
+ });
120
+
121
+ const { access_token, refresh_token, expires_in } = await response.json();
122
+ ```
123
+
124
+ #### Step 3: Initialize the SDK
125
+
126
+ Use the obtained token to initialize the SDK:
127
+
128
+ ```javascript
129
+ import * as mgmtApi from "@agility/management-sdk";
130
+
131
+ // Initialize the Options Class with your authentication token
132
+ let options = new mgmtApi.Options();
133
+ options.token = access_token; // Use the token obtained from authentication
134
+
135
+ // Initialize the APIClient Class
136
+ let apiClient = new mgmtApi.ApiClient(options);
137
+
138
+ let guid = "<<Provide the Guid of the Website>>";
139
+ let locale = "<<Provide the locale of the Website>>"; // Example: en-us
140
+
141
+ // Now you can make authenticated requests
142
+ var contentItem = await apiClient.contentMethods.getContentItem(22, guid, locale);
143
+ console.log(JSON.stringify(contentItem));
144
+ ```
145
+
146
+ #### Step 4: Refresh Access Tokens
147
+
148
+ When the access token expires, use the refresh token to obtain a new access token:
149
+
150
+ ```javascript
151
+ const response = await fetch('https://mgmt.aglty.io/oauth/refresh', {
152
+ method: 'POST',
153
+ headers: {
154
+ 'Content-Type': 'application/json'
155
+ },
156
+ body: JSON.stringify({
157
+ refresh_token: 'YOUR_REFRESH_TOKEN'
158
+ })
159
+ });
160
+
161
+ const { access_token, refresh_token, expires_in } = await response.json();
162
+ ```
163
+
164
+ ### Important Authentication Notes
165
+
166
+ - **Token Lifetime**: The access token has a limited lifetime (typically 1 hour)
167
+ - **Refresh Tokens**: The refresh token can be used to obtain new access tokens
168
+ - **Security**: Store refresh tokens securely and never expose them in client-side code
169
+ - **Error Handling**: Implement proper error handling for authentication failures
170
+
171
+ ### Making API Requests
172
+
173
+ Once authenticated, you can make requests using the SDK:
174
+
175
+ #### Using New Simple Authentication (Recommended)
176
+ ```typescript
177
+ import * as mgmtApi from '@agility/management-sdk';
178
+
179
+ // Simple OAuth authentication
180
+ const apiClient = new mgmtApi.ApiClient();
181
+ await apiClient.auth();
182
+
183
+ // Client is now authenticated and handles token refresh automatically
184
+ const guid = "your-website-guid";
185
+ const locale = "en-us";
186
+ const contentItem = await apiClient.contentMethods.getContentItem(22, guid, locale);
187
+ console.log(JSON.stringify(contentItem));
188
+ ```
189
+
190
+ #### Manual Client Creation (Existing Pattern)
191
+ ```javascript
192
+ import * as mgmtApi from "@agility/management-sdk";
193
+
194
+ //initialize the Options Class
195
+ let options = new mgmtApi.Options();
196
+
197
+ options.token = "<<Provide Auth Token>>"
198
+ //Initialize the APIClient Class
199
+ let apiClient = new mgmtApi.ApiClient(options);
200
+
201
+ let guid = "<<Provide the Guid of the Website>>";
202
+ let locale = "<<Provide the locale of the Website>>"; //Example: en-us
203
+
204
+ //make the request: get a content item with the ID '22'
205
+ var contentItem = await apiClient.contentMethods.getContentItem(22,guid, locale);
206
+
207
+ //To log the response of the contentItem object in console.
208
+ console.log(JSON.stringify(contentItem));
209
+ ```
210
+
211
+ ### OAuth Flow Examples
212
+
213
+ #### For Web Applications
214
+
215
+ ```javascript
216
+ // Redirect user to authorization URL
217
+ function initiateAuth() {
218
+ const authUrl = 'https://mgmt.aglty.io/oauth/authorize';
219
+ const params = new URLSearchParams({
220
+ response_type: 'code',
221
+ redirect_uri: window.location.origin + '/auth/callback',
222
+ state: generateRandomState(),
223
+ scope: 'openid profile email offline_access'
224
+ });
225
+
226
+ window.location.href = `${authUrl}?${params.toString()}`;
227
+ }
228
+
229
+ // Handle callback in your redirect URI endpoint
230
+ async function handleAuthCallback(code) {
231
+ try {
232
+ const response = await fetch('https://mgmt.aglty.io/oauth/token', {
233
+ method: 'POST',
234
+ headers: {
235
+ 'Content-Type': 'application/x-www-form-urlencoded'
236
+ },
237
+ body: new URLSearchParams({
238
+ code: code
239
+ })
240
+ });
241
+
242
+ const tokens = await response.json();
243
+
244
+ // Store tokens securely
245
+ localStorage.setItem('access_token', tokens.access_token);
246
+ localStorage.setItem('refresh_token', tokens.refresh_token);
247
+
248
+ return tokens;
249
+ } catch (error) {
250
+ console.error('Authentication failed:', error);
251
+ throw error;
252
+ }
253
+ }
254
+ ```
255
+
256
+ #### For Server-Side Applications
257
+
258
+ ```javascript
259
+ // Express.js example
260
+ app.get('/auth/agility', (req, res) => {
261
+ const authUrl = 'https://mgmt.aglty.io/oauth/authorize';
262
+ const params = new URLSearchParams({
263
+ response_type: 'code',
264
+ redirect_uri: 'https://yourapp.com/auth/callback',
265
+ state: req.session.state,
266
+ scope: 'openid profile email offline_access'
267
+ });
268
+
269
+ res.redirect(`${authUrl}?${params.toString()}`);
270
+ });
271
+
272
+ app.get('/auth/callback', async (req, res) => {
273
+ const { code, state } = req.query;
274
+
275
+ // Verify state parameter
276
+ if (state !== req.session.state) {
277
+ return res.status(400).send('Invalid state parameter');
278
+ }
279
+
280
+ try {
281
+ const response = await fetch('https://mgmt.aglty.io/oauth/token', {
282
+ method: 'POST',
283
+ headers: {
284
+ 'Content-Type': 'application/x-www-form-urlencoded'
285
+ },
286
+ body: new URLSearchParams({
287
+ code: code
288
+ })
289
+ });
290
+
291
+ const tokens = await response.json();
292
+
293
+ // Store tokens in session or database
294
+ req.session.tokens = tokens;
295
+
296
+ res.redirect('/dashboard');
297
+ } catch (error) {
298
+ res.status(500).send('Authentication failed');
299
+ }
300
+ });
301
+ ```
302
+
303
+ ### Token Management
304
+
305
+ #### Automatic Token Refresh
306
+
307
+ ```javascript
308
+ class AgilityTokenManager {
309
+ constructor(refreshToken) {
310
+ this.refreshToken = refreshToken;
311
+ this.accessToken = null;
312
+ this.expiresAt = null;
313
+ }
314
+
315
+ async getValidToken() {
316
+ if (!this.accessToken || Date.now() >= this.expiresAt) {
317
+ await this.refreshAccessToken();
318
+ }
319
+ return this.accessToken;
320
+ }
321
+
322
+ async refreshAccessToken() {
323
+ try {
324
+ const response = await fetch('https://mgmt.aglty.io/oauth/refresh', {
325
+ method: 'POST',
326
+ headers: {
327
+ 'Content-Type': 'application/json'
328
+ },
329
+ body: JSON.stringify({
330
+ refresh_token: this.refreshToken
331
+ })
332
+ });
333
+
334
+ const tokens = await response.json();
335
+
336
+ this.accessToken = tokens.access_token;
337
+ this.refreshToken = tokens.refresh_token; // Update refresh token if provided
338
+ this.expiresAt = Date.now() + (tokens.expires_in * 1000);
339
+
340
+ return tokens;
341
+ } catch (error) {
342
+ console.error('Token refresh failed:', error);
343
+ throw error;
344
+ }
345
+ }
346
+ }
347
+
348
+ // Usage
349
+ const tokenManager = new AgilityTokenManager('your-refresh-token');
350
+ const token = await tokenManager.getValidToken();
351
+
352
+ const options = new mgmtApi.Options();
353
+ options.token = token;
354
+ const apiClient = new mgmtApi.ApiClient(options);
355
+ ```
356
+
357
+ ### Error Handling
358
+
359
+ #### Common Authentication Errors
360
+
361
+ ```javascript
362
+ async function makeAuthenticatedRequest() {
363
+ try {
364
+ const apiClient = new mgmtApi.ApiClient({ token: accessToken });
365
+ const result = await apiClient.contentMethods.getContentItem(123, guid, locale);
366
+ return result;
367
+ } catch (error) {
368
+ if (error.response?.status === 401) {
369
+ // Token expired or invalid
370
+ console.log('Authentication failed - refreshing token');
371
+ await refreshAccessToken();
372
+
373
+ // Retry the request
374
+ const apiClient = new mgmtApi.ApiClient({ token: newAccessToken });
375
+ return await apiClient.contentMethods.getContentItem(123, guid, locale);
376
+ } else if (error.response?.status === 403) {
377
+ // Insufficient permissions
378
+ console.error('Access denied - insufficient permissions');
379
+ throw new Error('User does not have permission for this operation');
380
+ } else {
381
+ // Other errors
382
+ console.error('API request failed:', error.message);
383
+ throw error;
384
+ }
385
+ }
386
+ }
387
+ ```
388
+
389
+ ### Migration Guide
390
+
391
+ #### Migrating from Manual OAuth to Simple Authentication
392
+
393
+ **Before (Manual OAuth):**
394
+ ```typescript
395
+ // Old approach - manual OAuth handling
396
+ import * as mgmtApi from '@agility/management-sdk';
397
+
398
+ const options = new mgmtApi.Options();
399
+ options.token = 'manually-obtained-token';
400
+ const apiClient = new mgmtApi.ApiClient(options);
401
+
402
+ // Manual token refresh required
403
+ const contentItem = await apiClient.contentMethods.getContentItem(22, guid, locale);
404
+ ```
405
+
406
+ **After (Simple Authentication):**
407
+ ```typescript
408
+ // New approach - automatic OAuth handling
409
+ import * as mgmtApi from '@agility/management-sdk';
410
+
411
+ const apiClient = new mgmtApi.ApiClient();
412
+ await apiClient.auth();
413
+
414
+ // Automatic token refresh handled internally
415
+ const contentItem = await apiClient.contentMethods.getContentItem(22, guid, locale);
416
+ ```
417
+
418
+ #### Migrating from AuthMethods Class
419
+
420
+ **Before (AuthMethods Class):**
421
+ ```typescript
422
+ import { AuthMethods } from '@agility/management-sdk';
423
+
424
+ const auth = new AuthMethods();
425
+ const client = auth.createAuthenticatedClient('token');
426
+ ```
427
+
428
+ **After (Simple Authentication):**
429
+ ```typescript
430
+ import * as mgmtApi from '@agility/management-sdk';
431
+
432
+ const apiClient = new mgmtApi.ApiClient();
433
+ await apiClient.auth();
434
+ ```
435
+
436
+ ### Advanced Features
437
+
438
+ #### Secure Token Storage
439
+ The new authentication system uses OS-level secure storage:
440
+
441
+ - **macOS**: Keychain Access
442
+ - **Windows**: Windows Credential Store
443
+ - **Linux**: libsecret (GNOME Keyring)
444
+
445
+ Tokens are encrypted and stored securely, with automatic cleanup on logout.
446
+
447
+ #### Automatic Token Refresh
448
+ The SDK now handles token refresh automatically:
449
+
450
+ ```typescript
451
+ const apiClient = new mgmtApi.ApiClient();
452
+ await apiClient.auth();
453
+
454
+ // Token refresh happens automatically on 401 errors
455
+ const contentItem = await apiClient.contentMethods.getContentItem(22, guid, locale);
456
+ // If token was expired, it gets refreshed transparently
457
+ ```
458
+
459
+ #### Custom OAuth Configuration
460
+ You can customize the OAuth flow:
461
+
462
+ ```typescript
463
+ const apiClient = new mgmtApi.ApiClient();
464
+ await apiClient.auth({
465
+ redirectUri: 'https://yourapp.com/custom-callback',
466
+ scope: 'openid profile email offline_access',
467
+ region: 'us' // or 'ca', 'eu', 'au', 'dev'
468
+ });
469
+ ```
470
+
471
+ #### Manual Token Exchange
472
+ For custom OAuth implementations:
473
+
474
+ ```typescript
475
+ const apiClient = new mgmtApi.ApiClient();
476
+
477
+ // Exchange authorization code for tokens
478
+ const tokens = await apiClient.exchangeCodeForToken({
479
+ code: 'authorization_code_from_callback',
480
+ redirectUri: 'https://yourapp.com/auth/callback'
481
+ });
482
+
483
+ // Tokens are automatically stored and used
484
+ ```
485
+
486
+ ### Best Practices
487
+
488
+ #### Security Considerations
489
+
490
+ 1. **Use secure token storage (automatic with new auth)**
491
+ ```typescript
492
+ // ✅ Recommended - automatic secure storage
493
+ const apiClient = new mgmtApi.ApiClient();
494
+ await apiClient.auth(); // Tokens stored securely in OS keychain
495
+
496
+ // ✅ CI/CD - manual token (for automated environments)
497
+ const options = new mgmtApi.Options();
498
+ options.token = process.env.AGILITY_ACCESS_TOKEN;
499
+ const apiClient = new mgmtApi.ApiClient(options);
500
+
501
+ // ❌ Bad - hardcoded tokens
502
+ options.token = 'your-secret-token'; // Never do this
503
+ ```
504
+
505
+ 2. **Leverage automatic token refresh**
506
+ ```typescript
507
+ // ✅ Automatic token refresh (new approach)
508
+ const apiClient = new mgmtApi.ApiClient();
509
+ await apiClient.auth();
510
+
511
+ // Token refresh happens automatically on 401 errors
512
+ const contentItem = await apiClient.contentMethods.getContentItem(22, guid, locale);
513
+ ```
514
+
515
+ 3. **Handle authentication errors gracefully**
516
+ ```typescript
517
+ const apiClient = new mgmtApi.ApiClient();
518
+
519
+ try {
520
+ await apiClient.auth();
521
+ const contentItem = await apiClient.contentMethods.getContentItem(22, guid, locale);
522
+ } catch (error) {
523
+ if (error.message.includes('OAuth flow requires manual implementation')) {
524
+ // Handle OAuth flow manually
525
+ console.log('Visit the OAuth URL to authenticate');
526
+ } else {
527
+ // Handle other auth errors
528
+ console.error('Authentication failed:', error);
529
+ }
530
+ }
531
+ ```
532
+
533
+ 4. **Clear tokens on logout**
534
+ ```typescript
535
+ const apiClient = new mgmtApi.ApiClient();
536
+ await apiClient.auth();
537
+
538
+ // ... use API client ...
539
+
540
+ // Clear tokens securely on logout
541
+ await apiClient.clearToken();
542
+ ```
543
+
544
+ #### Performance Optimization
545
+
546
+ 1. **Reuse API client instances**
547
+ ```javascript
548
+ // ✅ Good - single instance
549
+ const apiClient = new mgmtApi.ApiClient(options);
550
+
551
+ // Use the same instance for multiple requests
552
+ const content1 = await apiClient.contentMethods.getContentItem(1, guid, locale);
553
+ const content2 = await apiClient.contentMethods.getContentItem(2, guid, locale);
554
+ ```
555
+
556
+ 2. **Implement request caching**
557
+ ```javascript
558
+ class CachedAgilityClient {
559
+ constructor(options) {
560
+ this.client = new mgmtApi.ApiClient(options);
561
+ this.cache = new Map();
562
+ }
563
+
564
+ async getContentItem(id, guid, locale) {
565
+ const cacheKey = `content-${id}-${guid}-${locale}`;
566
+
567
+ if (this.cache.has(cacheKey)) {
568
+ return this.cache.get(cacheKey);
569
+ }
570
+
571
+ const result = await this.client.contentMethods.getContentItem(id, guid, locale);
572
+ this.cache.set(cacheKey, result);
573
+
574
+ return result;
575
+ }
576
+ }
577
+ ```
578
+
579
+ ---
580
+
581
+ ## Navigation
582
+ - [← Back to Main Documentation](../README.md)
583
+ - [CI/CD & Automated Environments](./cicd.md)
584
+ - [AssetMethods](./asset-methods.md)
585
+ - [BatchMethods](./batch-methods.md)
586
+ - [ContentMethods](./content-methods.md)
587
+ - [ContainerMethods](./container-methods.md)
588
+ - [InstanceMethods](./instance-methods.md)
589
+ - [InstanceUserMethods](./instance-user-methods.md)
590
+ - [ModelMethods](./model-methods.md)
591
+ - [PageMethods](./page-methods.md)
592
+ - [ServerUserMethods](./server-user-methods.md)
593
+ - [WebhookMethods](./webhook-methods.md)
594
+ - [Multi-Instance Operations](./multi-instance-operations.md)