@adobe-commerce/aio-toolkit 1.2.5 → 1.2.7
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/CHANGELOG.md +250 -0
- package/README.md +450 -1
- package/dist/aio-toolkit-cli-workflow/bin/cli.js +2048 -0
- package/dist/aio-toolkit-cli-workflow/bin/cli.js.map +1 -0
- package/dist/aio-toolkit-cursor-context/bin/cli.js +16 -0
- package/dist/aio-toolkit-cursor-context/bin/cli.js.map +1 -1
- package/dist/index.d.mts +61 -6
- package/dist/index.d.ts +61 -6
- package/dist/index.js +600 -42
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +610 -38
- package/dist/index.mjs.map +1 -1
- package/files/cursor-context/commands/aio-toolkit-analyze-adobe-commerce-module.md +612 -0
- package/files/cursor-context/commands/aio-toolkit-create-amazon-sqs-consumer.md +445 -0
- package/files/cursor-context/commands/aio-toolkit-create-event-consumer-action.md +6 -0
- package/files/cursor-context/commands/aio-toolkit-create-graphql-action.md +21 -7
- package/files/cursor-context/commands/aio-toolkit-create-openwhisk-action.md +326 -0
- package/files/cursor-context/commands/aio-toolkit-create-runtime-action.md +15 -5
- package/files/cursor-context/commands/aio-toolkit-create-shipping-carrier.md +681 -0
- package/files/cursor-context/commands/aio-toolkit-create-webhook-action.md +22 -9
- package/files/cursor-context/rules/aio-toolkit-create-adobe-commerce-client.mdc +252 -116
- package/files/cursor-context/rules/aio-toolkit-oop-best-practices.mdc +10 -4
- package/files/cursor-context/rules/aio-toolkit-setup-new-relic-telemetry.mdc +167 -2
- package/files/cursor-context/rules/aio-toolkit-use-abdb-collection.mdc +610 -0
- package/files/cursor-context/rules/aio-toolkit-use-abdb-repository.mdc +705 -0
- package/files/cursor-context/rules/aio-toolkit-use-adobe-auth.mdc +442 -0
- package/files/cursor-context/rules/aio-toolkit-use-amazon-sqs-publish.mdc +397 -0
- package/files/cursor-context/rules/aio-toolkit-use-file-repository.mdc +502 -0
- package/files/cursor-context/rules/aio-toolkit-use-publish-event.mdc +510 -0
- package/files/cursor-context/rules/aio-toolkit-use-runtime-api-gateway-service.mdc +542 -0
- package/package.json +4 -2
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Using AdobeAuth to generate IMS bearer tokens in Adobe I/O Runtime actions using @adobe-commerce/aio-toolkit
|
|
3
|
+
globs: '**/{actions,lib}/**/*.{ts,js}'
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Using AdobeAuth
|
|
8
|
+
|
|
9
|
+
## Trigger Conditions
|
|
10
|
+
|
|
11
|
+
This rule applies when the user needs to generate an IMS bearer token using explicit OAuth Server-to-Server credentials with any of these phrases:
|
|
12
|
+
|
|
13
|
+
- "Get IMS token"
|
|
14
|
+
- "Generate IMS bearer token"
|
|
15
|
+
- "Use AdobeAuth"
|
|
16
|
+
- "OAuth S2S authentication"
|
|
17
|
+
- "S2S token for [service]"
|
|
18
|
+
- "Technical account credentials"
|
|
19
|
+
- "Service account token"
|
|
20
|
+
- "IMS credentials for [action-name]"
|
|
21
|
+
- "Authenticate with Adobe IMS"
|
|
22
|
+
- "Generate access token for Commerce / PublishEvent / API Gateway"
|
|
23
|
+
- "AdobeAuth.getToken"
|
|
24
|
+
|
|
25
|
+
**Important**: This rule integrates `AdobeAuth` into an existing action. It does NOT create new actions.
|
|
26
|
+
|
|
27
|
+
**When to use `AdobeAuth` vs `Core.AuthClient`**:
|
|
28
|
+
|
|
29
|
+
| Scenario | Use |
|
|
30
|
+
|---|---|
|
|
31
|
+
| Action already has `include-ims-credentials: true` and only needs its own App Builder token | `Core.AuthClient.generateAccessToken(params)` — simpler, no extra env vars |
|
|
32
|
+
| Action needs a token from **separate, explicitly stored** S2S credentials (dedicated technical account per integration) | `AdobeAuth.getToken()` — reads credentials from `params` env vars |
|
|
33
|
+
| Multiple actions share a single dedicated technical account | `AdobeAuth.getToken()` — credentials stored once in `.env`, injected via `inputs` |
|
|
34
|
+
| Calling `ImsConnection` for `AdobeCommerceClient` with a dedicated Commerce technical account | `AdobeAuth.getToken()` |
|
|
35
|
+
| Calling `PublishEvent` with a dedicated Events technical account | `AdobeAuth.getToken()` |
|
|
36
|
+
| Calling `RuntimeApiGatewayService` with a shared org-level account | `AdobeAuth.getToken()` |
|
|
37
|
+
|
|
38
|
+
**Integration with Other Rules:**
|
|
39
|
+
|
|
40
|
+
When using action creation rules (RuntimeAction, WebhookAction, EventConsumerAction, GraphQlAction, OpenwhiskAction) and the developer mentions needing S2S authentication or explicit IMS credentials:
|
|
41
|
+
|
|
42
|
+
- **Automatically trigger this rule** after the action is created
|
|
43
|
+
- This rule handles credential injection, scope selection, error handling, and caching guidance
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Step 1: Confirm Prerequisites
|
|
48
|
+
|
|
49
|
+
Before generating code, confirm:
|
|
50
|
+
|
|
51
|
+
1. **`@adobe-commerce/aio-toolkit` installed**: Check `package.json` — `AdobeAuth` is exported from it
|
|
52
|
+
- If NOT installed: `npm install @adobe-commerce/aio-toolkit`
|
|
53
|
+
|
|
54
|
+
2. **Credentials available**: The user must have an **OAuth Server-to-Server** credential in Adobe Developer Console with the required scopes already granted
|
|
55
|
+
- Scopes are configured when the credential is created — `AdobeAuth.getToken()` cannot request scopes that were not granted
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Step 2: Ask Clarifying Questions
|
|
60
|
+
|
|
61
|
+
Ask the following before generating any code:
|
|
62
|
+
|
|
63
|
+
1. **What consumes the token?**
|
|
64
|
+
- [ ] `ImsConnection` for `AdobeCommerceClient`
|
|
65
|
+
- [ ] `PublishEvent` for Adobe I/O Events
|
|
66
|
+
- [ ] `RuntimeApiGatewayService` for web action calls
|
|
67
|
+
- [ ] A custom Adobe API call (specify which)
|
|
68
|
+
|
|
69
|
+
2. **Do you already have separate IMS credentials (Client ID, Client Secret, Technical Account ID/Email, IMS Org ID)?**
|
|
70
|
+
- If NO: suggest using `Core.AuthClient.generateAccessToken(params)` with `include-ims-credentials: true` instead (no extra credentials needed)
|
|
71
|
+
- If YES: proceed with `AdobeAuth.getToken()`
|
|
72
|
+
|
|
73
|
+
3. **Which OAuth scopes are needed?** (see scope reference below — suggest based on the consumer)
|
|
74
|
+
- `ImsConnection` / Commerce → `['AdobeID', 'openid', 'adobeio_api']`
|
|
75
|
+
- `PublishEvent` → `['AdobeID', 'openid', 'adobeio_api', 'event_receiver_api']`
|
|
76
|
+
- `RuntimeApiGatewayService` → `['openid', 'AdobeID', 'adobeio_api']`
|
|
77
|
+
|
|
78
|
+
4. **High-frequency action?** If the action is invoked frequently (>10x/min), recommend caching the token using AIO State — `AdobeAuth.getToken()` makes a live IMS network call every invocation.
|
|
79
|
+
|
|
80
|
+
5. **Which action file(s) should `AdobeAuth` be added to?** (if not already clear from context)
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Step 3: Confirm Plan
|
|
85
|
+
|
|
86
|
+
Before writing code, confirm the implementation plan:
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
I'll make the following changes:
|
|
90
|
+
|
|
91
|
+
1. Action file ([path/to/action/index.ts|js]):
|
|
92
|
+
- Import AdobeAuth from @adobe-commerce/aio-toolkit
|
|
93
|
+
- Add AdobeAuth.getToken() call [with try/catch for error handling]
|
|
94
|
+
- [Pass token to: ImsConnection / PublishEvent / RuntimeApiGatewayService / custom]
|
|
95
|
+
[If caching: Import BearerToken and add TTL-based cache check]
|
|
96
|
+
|
|
97
|
+
2. app.config.yaml (or ext.config.yaml / actions.config.yaml):
|
|
98
|
+
- Add IMS credential inputs: IMS_CLIENT_ID, IMS_CLIENT_SECRET,
|
|
99
|
+
IMS_TECHNICAL_ACCOUNT_ID, IMS_TECHNICAL_ACCOUNT_EMAIL, IMS_ORG_ID
|
|
100
|
+
|
|
101
|
+
3. .env:
|
|
102
|
+
- Add IMS_CLIENT_ID, IMS_CLIENT_SECRET, IMS_TECHNICAL_ACCOUNT_ID,
|
|
103
|
+
IMS_TECHNICAL_ACCOUNT_EMAIL, IMS_ORG_ID
|
|
104
|
+
|
|
105
|
+
Scopes to request: [list based on consumer]
|
|
106
|
+
|
|
107
|
+
Shall I proceed?
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Step 4: Generate Code
|
|
113
|
+
|
|
114
|
+
### Step 4.1: Action Code
|
|
115
|
+
|
|
116
|
+
Detect language (TypeScript or JavaScript) by checking the action file extension or `tsconfig.json`. Generate in the detected language.
|
|
117
|
+
|
|
118
|
+
#### A. Basic usage — with error handling (recommended)
|
|
119
|
+
|
|
120
|
+
```javascript
|
|
121
|
+
const {
|
|
122
|
+
AdobeAuth,
|
|
123
|
+
// ... other imports
|
|
124
|
+
} = require('@adobe-commerce/aio-toolkit');
|
|
125
|
+
|
|
126
|
+
// Inside your action handler (params, ctx):
|
|
127
|
+
const { logger, telemetry } = ctx;
|
|
128
|
+
|
|
129
|
+
let imsToken;
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
imsToken = await AdobeAuth.getToken(
|
|
133
|
+
params.IMS_CLIENT_ID,
|
|
134
|
+
params.IMS_CLIENT_SECRET,
|
|
135
|
+
params.IMS_TECHNICAL_ACCOUNT_ID,
|
|
136
|
+
params.IMS_TECHNICAL_ACCOUNT_EMAIL,
|
|
137
|
+
params.IMS_ORG_ID,
|
|
138
|
+
['AdobeID', 'openid', 'adobeio_api'] // adjust scopes to your integration
|
|
139
|
+
);
|
|
140
|
+
} catch (error) {
|
|
141
|
+
logger.error({
|
|
142
|
+
message: '[action-name]-ims-token-failed',
|
|
143
|
+
...telemetry.formatError(error),
|
|
144
|
+
});
|
|
145
|
+
return RuntimeActionResponse.error(401, 'Failed to generate IMS token');
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Pass imsToken to your consumer:
|
|
149
|
+
// const connection = new ImsConnection(imsToken, logger);
|
|
150
|
+
// const publisher = new PublishEvent(params.IMS_ORG_ID, params.API_KEY, imsToken, logger);
|
|
151
|
+
// const service = new RuntimeApiGatewayService(params.NAMESPACE, params.IMS_ORG_ID, imsToken, logger);
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**TypeScript imports:**
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
import { AdobeAuth } from '@adobe-commerce/aio-toolkit';
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
#### B. With ImsConnection for AdobeCommerceClient
|
|
161
|
+
|
|
162
|
+
```javascript
|
|
163
|
+
const {
|
|
164
|
+
AdobeAuth,
|
|
165
|
+
AdobeCommerceClient,
|
|
166
|
+
ImsConnection,
|
|
167
|
+
} = require('@adobe-commerce/aio-toolkit');
|
|
168
|
+
|
|
169
|
+
let imsToken;
|
|
170
|
+
|
|
171
|
+
try {
|
|
172
|
+
imsToken = await AdobeAuth.getToken(
|
|
173
|
+
params.IMS_CLIENT_ID,
|
|
174
|
+
params.IMS_CLIENT_SECRET,
|
|
175
|
+
params.IMS_TECHNICAL_ACCOUNT_ID,
|
|
176
|
+
params.IMS_TECHNICAL_ACCOUNT_EMAIL,
|
|
177
|
+
params.IMS_ORG_ID,
|
|
178
|
+
['AdobeID', 'openid', 'adobeio_api']
|
|
179
|
+
);
|
|
180
|
+
} catch (error) {
|
|
181
|
+
logger.error({ message: '[action-name]-ims-token-failed', ...telemetry.formatError(error) });
|
|
182
|
+
return RuntimeActionResponse.error(401, 'Failed to generate IMS token');
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const client = new AdobeCommerceClient(
|
|
186
|
+
params.COMMERCE_BASE_URL,
|
|
187
|
+
new ImsConnection(imsToken, logger),
|
|
188
|
+
logger
|
|
189
|
+
);
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
#### C. With PublishEvent for Adobe I/O Events
|
|
193
|
+
|
|
194
|
+
```javascript
|
|
195
|
+
const {
|
|
196
|
+
AdobeAuth,
|
|
197
|
+
PublishEvent,
|
|
198
|
+
} = require('@adobe-commerce/aio-toolkit');
|
|
199
|
+
|
|
200
|
+
let imsToken;
|
|
201
|
+
|
|
202
|
+
try {
|
|
203
|
+
imsToken = await AdobeAuth.getToken(
|
|
204
|
+
params.IMS_CLIENT_ID,
|
|
205
|
+
params.IMS_CLIENT_SECRET,
|
|
206
|
+
params.IMS_TECHNICAL_ACCOUNT_ID,
|
|
207
|
+
params.IMS_TECHNICAL_ACCOUNT_EMAIL,
|
|
208
|
+
params.IMS_ORG_ID,
|
|
209
|
+
['AdobeID', 'openid', 'adobeio_api', 'event_receiver_api']
|
|
210
|
+
);
|
|
211
|
+
} catch (error) {
|
|
212
|
+
logger.error({ message: '[action-name]-ims-token-failed', ...telemetry.formatError(error) });
|
|
213
|
+
return RuntimeActionResponse.error(401, 'Failed to generate IMS token');
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const publisher = new PublishEvent(
|
|
217
|
+
params.IMS_ORG_ID,
|
|
218
|
+
params.API_KEY,
|
|
219
|
+
imsToken,
|
|
220
|
+
logger
|
|
221
|
+
);
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
#### D. With token caching (high-frequency actions)
|
|
225
|
+
|
|
226
|
+
Use this pattern when the action is invoked frequently and you want to avoid a live IMS call every invocation. Cache the token in Adobe I/O State with a TTL matching the token's expiry.
|
|
227
|
+
|
|
228
|
+
```javascript
|
|
229
|
+
const {
|
|
230
|
+
AdobeAuth,
|
|
231
|
+
BearerToken,
|
|
232
|
+
} = require('@adobe-commerce/aio-toolkit');
|
|
233
|
+
const { Files, State } = require('@adobe/aio-sdk');
|
|
234
|
+
|
|
235
|
+
// Module-level cache (valid for container lifetime only — not reliable across invocations)
|
|
236
|
+
let cachedToken = null;
|
|
237
|
+
|
|
238
|
+
// Inside your action handler:
|
|
239
|
+
let imsToken;
|
|
240
|
+
|
|
241
|
+
// Check in-memory cache first (fast path for warm containers)
|
|
242
|
+
if (cachedToken && BearerToken.info(cachedToken).isValid) {
|
|
243
|
+
imsToken = cachedToken;
|
|
244
|
+
} else {
|
|
245
|
+
// Fall back to AIO State for cross-invocation persistence
|
|
246
|
+
const state = await State.init();
|
|
247
|
+
const cached = await state.get('ims-token');
|
|
248
|
+
|
|
249
|
+
if (cached && BearerToken.info(cached.value).isValid) {
|
|
250
|
+
imsToken = cached.value;
|
|
251
|
+
cachedToken = imsToken;
|
|
252
|
+
} else {
|
|
253
|
+
try {
|
|
254
|
+
imsToken = await AdobeAuth.getToken(
|
|
255
|
+
params.IMS_CLIENT_ID,
|
|
256
|
+
params.IMS_CLIENT_SECRET,
|
|
257
|
+
params.IMS_TECHNICAL_ACCOUNT_ID,
|
|
258
|
+
params.IMS_TECHNICAL_ACCOUNT_EMAIL,
|
|
259
|
+
params.IMS_ORG_ID,
|
|
260
|
+
['AdobeID', 'openid', 'adobeio_api']
|
|
261
|
+
);
|
|
262
|
+
} catch (error) {
|
|
263
|
+
logger.error({ message: '[action-name]-ims-token-failed', ...telemetry.formatError(error) });
|
|
264
|
+
return RuntimeActionResponse.error(401, 'Failed to generate IMS token');
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const { timeUntilExpiry } = BearerToken.info(imsToken);
|
|
268
|
+
const ttl = timeUntilExpiry ? Math.floor(timeUntilExpiry / 1000) - 60 : 3000; // 60s safety margin
|
|
269
|
+
|
|
270
|
+
await state.put('ims-token', imsToken, { ttl });
|
|
271
|
+
cachedToken = imsToken;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
> **Caching note:** `AdobeAuth.getToken()` makes a **live IMS network call every invocation** — it has no built-in caching. If your action is called frequently, use the pattern above or implement your own TTL-based cache using Adobe I/O State.
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
### Step 4.2: Update Action Configuration
|
|
281
|
+
|
|
282
|
+
Add IMS credential inputs to the action's YAML configuration:
|
|
283
|
+
|
|
284
|
+
**In `app.config.yaml`, `ext.config.yaml`, or `actions.config.yaml`:**
|
|
285
|
+
|
|
286
|
+
```yaml
|
|
287
|
+
[action-name]:
|
|
288
|
+
function: actions/[action-name]/index.js
|
|
289
|
+
web: 'yes'
|
|
290
|
+
runtime: nodejs:22
|
|
291
|
+
inputs:
|
|
292
|
+
LOG_LEVEL: debug
|
|
293
|
+
# IMS S2S credentials
|
|
294
|
+
IMS_CLIENT_ID: $IMS_CLIENT_ID
|
|
295
|
+
IMS_CLIENT_SECRET: $IMS_CLIENT_SECRET
|
|
296
|
+
IMS_TECHNICAL_ACCOUNT_ID: $IMS_TECHNICAL_ACCOUNT_ID
|
|
297
|
+
IMS_TECHNICAL_ACCOUNT_EMAIL: $IMS_TECHNICAL_ACCOUNT_EMAIL
|
|
298
|
+
IMS_ORG_ID: $IMS_ORG_ID
|
|
299
|
+
annotations:
|
|
300
|
+
require-adobe-auth: true
|
|
301
|
+
final: true
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
> **Note:** `include-ims-credentials: true` is **NOT required** when using `AdobeAuth.getToken()`. That annotation is only needed for `Core.AuthClient.generateAccessToken(params)`. `AdobeAuth` reads credentials from the standard `inputs` you define above.
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
### Step 4.3: Add Environment Variables
|
|
309
|
+
|
|
310
|
+
Add to the project's `.env` file:
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
# IMS OAuth S2S credentials — from Adobe Developer Console → OAuth Server-to-Server
|
|
314
|
+
IMS_CLIENT_ID=your-client-id
|
|
315
|
+
IMS_CLIENT_SECRET=your-client-secret
|
|
316
|
+
IMS_TECHNICAL_ACCOUNT_ID=XXXXXXXXXXXXXXXX@techacct.adobe.com
|
|
317
|
+
IMS_TECHNICAL_ACCOUNT_EMAIL=techacct@your-org.adobe.com
|
|
318
|
+
IMS_ORG_ID=XXXXXXXXXXXXXXXX@AdobeOrg
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
**Where to find credentials:**
|
|
322
|
+
1. Open [Adobe Developer Console](https://developer.adobe.com/console)
|
|
323
|
+
2. Select your **Project** → **Workspace** (e.g. Production, Stage)
|
|
324
|
+
3. Go to **OAuth Server-to-Server** under the credentials section
|
|
325
|
+
4. Copy: **Client ID**, **Client Secret**, **Technical Account ID**, **Technical Account Email**, **IMS Org ID**
|
|
326
|
+
5. Verify the listed **Scopes** include everything you intend to request
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
## OAuth Scopes Reference
|
|
331
|
+
|
|
332
|
+
Request only the scopes your integration actually needs. Scopes must be a subset of those granted to the credential in Adobe Developer Console.
|
|
333
|
+
|
|
334
|
+
| Scope | Purpose |
|
|
335
|
+
|---|---|
|
|
336
|
+
| `AdobeID` | Basic Adobe identity — required for most integrations |
|
|
337
|
+
| `openid` | OpenID Connect identity token |
|
|
338
|
+
| `adobeio_api` | Access to Adobe I/O APIs |
|
|
339
|
+
| `event_receiver_api` | Publish and consume Adobe I/O Events (required for `PublishEvent`) |
|
|
340
|
+
| `adobeio.appregistry.read` | Read App Registry entries |
|
|
341
|
+
| `read_organizations` | Read IMS organization details |
|
|
342
|
+
| `additional_info.projectedProductContext` | Access product context in the token |
|
|
343
|
+
|
|
344
|
+
**Recommended scopes by consumer:**
|
|
345
|
+
|
|
346
|
+
| Consumer | Minimum recommended scopes |
|
|
347
|
+
|---|---|
|
|
348
|
+
| `ImsConnection` (AdobeCommerceClient) | `['AdobeID', 'openid', 'adobeio_api']` |
|
|
349
|
+
| `PublishEvent` | `['AdobeID', 'openid', 'adobeio_api', 'event_receiver_api']` |
|
|
350
|
+
| `RuntimeApiGatewayService` | `['openid', 'AdobeID', 'adobeio_api']` |
|
|
351
|
+
| Custom Adobe I/O API | `['AdobeID', 'openid', 'adobeio_api']` + any API-specific scope |
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## Key Components
|
|
356
|
+
|
|
357
|
+
### `AdobeAuth.getToken()` — generate IMS token
|
|
358
|
+
|
|
359
|
+
```typescript
|
|
360
|
+
static async getToken(
|
|
361
|
+
clientId: string, // OAuth S2S Client ID
|
|
362
|
+
clientSecret: string, // OAuth S2S Client Secret
|
|
363
|
+
technicalAccountId: string, // Technical Account ID (XXXXXXXX@techacct.adobe.com)
|
|
364
|
+
technicalAccountEmail: string, // Technical Account Email
|
|
365
|
+
imsOrgId: string, // IMS Org ID (XXXXXXXX@AdobeOrg)
|
|
366
|
+
scopes: string[], // OAuth scopes — must be granted to the credential
|
|
367
|
+
currentContext?: string // optional, default: 'onboarding-config'
|
|
368
|
+
): Promise<string> // returns raw IMS access token string
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
- **Throws** on invalid credentials, network failure, or unauthorized scopes — always wrap in `try/catch`
|
|
372
|
+
- **No caching** — makes a live IMS network call every invocation
|
|
373
|
+
- `currentContext` only needs to be overridden when managing multiple concurrent IMS contexts in the same process
|
|
374
|
+
|
|
375
|
+
### `BearerToken.info()` — inspect token validity (for caching)
|
|
376
|
+
|
|
377
|
+
```typescript
|
|
378
|
+
const { isValid, timeUntilExpiry } = BearerToken.info(token);
|
|
379
|
+
// isValid: boolean — false if expired or invalid
|
|
380
|
+
// timeUntilExpiry: number (ms) — time until expiry; 0 or undefined if expired
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### Exports
|
|
384
|
+
|
|
385
|
+
```javascript
|
|
386
|
+
const { AdobeAuth, BearerToken } = require('@adobe-commerce/aio-toolkit');
|
|
387
|
+
|
|
388
|
+
// TypeScript only
|
|
389
|
+
import type { AdobeIMSConfig } from '@adobe-commerce/aio-toolkit';
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
## Important Notes
|
|
395
|
+
|
|
396
|
+
1. **`AdobeAuth.getToken()` throws — always use try/catch**: Invalid credentials, network failures, and unauthorized scopes all propagate directly. Return a clean error response rather than letting the action crash.
|
|
397
|
+
2. **No built-in caching**: Every call makes a live round-trip to Adobe IMS. For high-frequency actions, implement TTL-based caching using AIO State + `BearerToken.info()`.
|
|
398
|
+
3. **`include-ims-credentials: true` is NOT needed**: That annotation is for `Core.AuthClient.generateAccessToken(params)` only. `AdobeAuth` reads from standard `inputs` you define in YAML.
|
|
399
|
+
4. **Scopes must be pre-granted**: You cannot request scopes at runtime that were not granted when the OAuth S2S credential was created in Adobe Developer Console.
|
|
400
|
+
5. **`currentContext` param**: Only override the default `'onboarding-config'` context if you need to manage multiple concurrent IMS contexts in the same process (rare).
|
|
401
|
+
6. **One token per consumer**: If an action uses both `ImsConnection` and `PublishEvent`, you may use the same token if the scopes cover both — or generate separate tokens if the credentials differ.
|
|
402
|
+
7. **Credential security**: Never commit `.env` to version control — confirm `.env` is in `.gitignore`. `IMS_CLIENT_SECRET` is a secret and must be treated accordingly.
|
|
403
|
+
8. **Works with any action type**: RuntimeAction, WebhookAction, EventConsumerAction, GraphQlAction, OpenwhiskAction.
|
|
404
|
+
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
## Related Rules
|
|
408
|
+
|
|
409
|
+
- **"Creating Adobe Commerce Client Operations"** (`aio-toolkit-create-adobe-commerce-client.mdc`) — uses `AdobeAuth.getToken()` to obtain a token for `ImsConnection`
|
|
410
|
+
- **"Using PublishEvent"** (`aio-toolkit-use-publish-event.mdc`) — uses `Core.AuthClient` by default; use `AdobeAuth.getToken()` instead when publishing with explicit S2S credentials
|
|
411
|
+
- **"Using RuntimeApiGatewayService"** (`aio-toolkit-use-runtime-api-gateway-service.mdc`) — uses `AdobeAuth.getToken()` as the primary token source for API Gateway calls
|
|
412
|
+
|
|
413
|
+
## Integration with Action Creation Rules
|
|
414
|
+
|
|
415
|
+
**This rule should be triggered when developers mention needing IMS token generation with explicit S2S credentials:**
|
|
416
|
+
|
|
417
|
+
### Trigger Patterns in Other Rules
|
|
418
|
+
|
|
419
|
+
When developers mention these phrases during action creation:
|
|
420
|
+
|
|
421
|
+
- "Generate an IMS token"
|
|
422
|
+
- "Authenticate with Adobe IMS"
|
|
423
|
+
- "Need an IMS bearer token for [service]"
|
|
424
|
+
- "Use my technical account credentials"
|
|
425
|
+
- "OAuth S2S token"
|
|
426
|
+
- Any phrase containing "AdobeAuth" or "IMS token" + "S2S"/"technical account"/"credentials"
|
|
427
|
+
|
|
428
|
+
**Action to take:**
|
|
429
|
+
|
|
430
|
+
1. Determine if `Core.AuthClient.generateAccessToken(params)` covers the use case first
|
|
431
|
+
2. If the user has explicit S2S credentials or needs a dedicated technical account: apply this rule
|
|
432
|
+
3. This rule handles credential injection, scope selection, error handling, caching, and config wiring
|
|
433
|
+
|
|
434
|
+
**Example Flow:**
|
|
435
|
+
|
|
436
|
+
```
|
|
437
|
+
User: "Create a runtime action that fetches products from Commerce using our technical account"
|
|
438
|
+
AI: ✓ Detected TypeScript project
|
|
439
|
+
AI: Creating runtime action... [generates .ts file]
|
|
440
|
+
AI: I see you need IMS token generation with explicit S2S credentials. Let me integrate AdobeAuth.
|
|
441
|
+
AI: [Adds AdobeAuth.getToken(), ImsConnection, config inputs, and .env entries]
|
|
442
|
+
```
|