Skip to content

Commit c03b96b

Browse files
Merge pull request #1040 from akeneo/DXIM-rework_ui_ext_doc
DXIM rework ui ext page
2 parents 9f3a3be + 62ed6ad commit c03b96b

File tree

1 file changed

+127
-137
lines changed

1 file changed

+127
-137
lines changed

content/extensions/ui-extensions.md

Lines changed: 127 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -174,106 +174,77 @@ To delete a UI extension, you must have a valid PIM API token and the UUID of th
174174
--header "Authorization: Bearer $PIM_API_TOKEN"
175175
```
176176

177-
## Concepts
178-
179-
### Type
177+
## Types
180178

181179
UI extensions are categorized by type, which determines their capabilities. Select the type that best suits your requirements:
182180
+ action
183181
+ iframe
184182
+ link
185183

186-
#### Link
184+
### Link
187185
A **link** UI extension is crafted to open your external content in a new tab.
188186

189-
#### Iframe
190-
An **iframe** UI extension allows to open your external content inside the PIM thanks to an iframe.
187+
To create a `link` UI extension, mandatory fields are `name`, `position`, `type`, and `configuration`. Inside `configuration`, mandatory options are `default_label` and `url`.
191188

192-
An iframe (inline frame) is an HTML element that allows you to embed another HTML document within the current document. It is commonly used to display content from another source, such as a webpage, video, or interactive content, without leaving the current page.
189+
#### Url Placeholders
190+
The Url of a **link** UI extension can be based on the context thanks to a placeholder pattern.
193191

194-
For more detailed information, you can refer to the [Mozilla Developer Network (MDN) documentation on iframes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe).
192+
For example, you can configure a UI extension with the following url `https://www.google.com/search?q=%name%&tbm=shop&gl=us`. When the link is clicked, `%name%` will be replaced with the context attribute values.
195193

196-
To configure an `iframe` UI extension, mandatory fields are `name`, `position`, `type`, and `configuration`. Inside `configuration`, mandatory options are `default_label`, `secret` and `url`.
194+
Valid placeholders attributes are:
195+
- `uuid` (for products), `code` (for product models) and other attribute of type `identifier`
196+
- all `text` attributes. Links will use the value related to the current locale or channel.
197197

198-
**Ensuring security of embedded iframes**
198+
You can add a placeholder anywhere in your url as soon as they're surrounded by `%` symbol.
199199

200-
* Properly configure [Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) headers to control the sources from which content can be loaded.
200+
Examples:
201+
- `https://www.google.com/search?q=%name%`
202+
- `https://yourwebsite.com/%sku%`
203+
- `%base_url%/sub-url`
201204

202205
::: warning
203-
Please note that if these headers are misconfigured, iframe functionality may not work as intended.
206+
If the URL begins with a placeholder, we won't verify its validity. The link might not work when used.
204207
:::
205208

206-
* Add a secret to your extension. This secret will be used to generate a JWT token when the iframe is loaded by the PIM system.
207-
208-
**Receiving the JWT Token via ```postMessage```**
209-
210-
First, from your iframe, you must request for the JWT by doing a PostMessage with a payload containing ```type: 'request_jwt'```
211-
212-
Example :
213-
```js
214-
window.parent.postMessage(
215-
{
216-
type: 'request_jwt'
217-
},
218-
"*"
219-
);
220-
```
221-
222-
the PIM will then answer with a postMessage containing the JWT token. The message will be structured as follows:
223-
224-
```json
225-
{
226-
"type": "JWT_TOKEN",
227-
"token": "jwt_value"
228-
}
229-
```
230-
231-
* The JWT token in the token field is generated using SHA256 encryption based on the secret you provided.
232-
233-
For more information on how JWT tokens are structured and used, you can refer to the associated [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519).
234-
235-
**JWT Token Structure**
236-
237-
The JWT token consists of three main parts: the header, the body (payload), and the signature.
209+
### Iframe
210+
An **iframe** UI extension allows to open your external content inside the PIM thanks to an iframe.
238211

239-
*Header*
212+
An iframe (inline frame) is an HTML element that allows you to embed another HTML document within the current document. It is commonly used to display content from another source, such as a webpage, video, or interactive content, without leaving the current page.
240213

241-
* The header typically contains information about the token type and the signing algorithm. In this case, it will look like:
214+
For more detailed information, you can refer to the [Mozilla Developer Network (MDN) documentation on iframes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe).
242215

243-
```json
244-
{
245-
"typ": "JWT",
246-
"alg": "HS256"
247-
}
248-
```
216+
To configure an `iframe` UI extension, mandatory fields are `name`, `position`, `type`, and `configuration`. Inside `configuration`, mandatory options are `default_label`, `secret` and `url`.
249217

250-
*Payload*
218+
::: warning
219+
**Important security notice**
251220

252-
* The payload contains the claims. The JWT token’s will look like this:
221+
For sensitive data, we recommend implementing [security measures](#ensuring-security-of-embedded-iframes) to protect your information.
222+
:::
253223

254-
```json
255-
{
256-
"jti": "c1b6b9f1-8486-4f9e-9f96-8d1b40fccb65",
257-
"iat": 1743410036.116152,
258-
"exp": 1743413636.116162,
259-
"userId": "1"
260-
}
261-
```
224+
#### Default query parameters
225+
To help identify the **iframe** caller (insecure) and context, several parameters are sent by default as SearchParameters in the GET query.
262226

263-
* ```jti``` The unique identifier for the token.
264-
* ```iat``` The issued at time.
265-
* ```exp``` The expiration time of the token.
266-
* ```userId``` The PIM user identifier (in this case, ```1```).
227+
For example, when `url` is `https://customerwebsite.com/iframe/`, the called URL is `https://customerwebite.com/iframe/?position=pim.product.tab&user[username]=julia`
267228

268-
*A signature*
229+
For all positions, parameters relative to the connected user and the extension position are sent:
230+
- `user[username]`
231+
- `user[email]`
232+
- `user[ui_locale]`
233+
- `user[catalog_locale]` except for `pim.product-grid.action-bar`
234+
- `user[catalog_scope]` except for `pim.product-grid.action-bar`
235+
- `position`
269236

270-
* The signature is used to verify that the token is valid and has not been tampered with. It is generated by combining the encoded header and payload, and then signing them with the secret key. The resulting signature might look like:
271-
```9WBB7ayP8UnFrOlMrI9NzTj3kxaiXOWJzElyacEKt48```
237+
For `pim.product.tab` position, these parameters are sent:
238+
- `product[uuid]`
239+
- `product[identifier]`
272240

273-
**Verifying the Signature**
241+
For `pim.product-model.tab` and `pim.sub-product-model.header` position, this parameter is sent:
242+
- `product[code]`
274243

275-
To ensure that the JWT token was issued by Akeneo, you can verify the signature by re-encoding the header and payload and then signing them using the same secret key. This will allow you to confirm that the token is valid and has not been altered.
244+
For `pim.category.tab` position, this parameter is sent:
245+
- `category[code]`
276246

247+
#### Get PIM data from the iframe
277248

278249
**PostMessage**
279250

@@ -337,8 +308,88 @@ Example :
337308
```
338309
After receiving this *event*, the PIM will send a PostMessage *event*, similar to the one sent after the iframe loading.
339310

311+
#### Ensuring security of embedded iframes
312+
313+
To help ensuring the security of iframes we recommand using these two solutions:
314+
315+
* Properly configure [Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) headers to control the sources from which content can be loaded.
340316

341-
#### Action
317+
::: warning
318+
Please note that if these headers are misconfigured, iframe functionality may not work as intended.
319+
:::
320+
321+
* Use your extension secret and ```postMessage``` to get and verify the signature of a JW token. This secret will be used to generate a JWT token when the iframe is loaded by the PIM system.
322+
323+
**Get a JW Token via ```postMessage```**
324+
325+
First, from your iframe, you must request for the JWT by doing a PostMessage with a payload containing ```type: 'request_jwt'```
326+
327+
Example :
328+
```js
329+
window.parent.postMessage(
330+
{
331+
type: 'request_jwt'
332+
},
333+
"*"
334+
);
335+
```
336+
337+
the PIM will then answer with a postMessage containing the JWT token. The message will be structured as follows:
338+
339+
```json
340+
{
341+
"type": "JWT_TOKEN",
342+
"token": "jwt_value"
343+
}
344+
```
345+
346+
* The JWT token in the token field is generated using SHA256 encryption based on the secret you provided.
347+
348+
For more information on how JWT tokens are structured and used, you can refer to the associated [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519).
349+
350+
**JWT Token Structure**
351+
352+
The JWT token consists of three main parts: the header, the body (payload), and the signature.
353+
354+
*Header*
355+
356+
* The header typically contains information about the token type and the signing algorithm. In this case, it will look like:
357+
358+
```json
359+
{
360+
"typ": "JWT",
361+
"alg": "HS256"
362+
}
363+
```
364+
365+
*Payload*
366+
367+
* The payload contains the claims. The JWT token’s will look like this:
368+
369+
```json
370+
{
371+
"jti": "c1b6b9f1-8486-4f9e-9f96-8d1b40fccb65",
372+
"iat": 1743410036.116152,
373+
"exp": 1743413636.116162,
374+
"userId": "1"
375+
}
376+
```
377+
378+
* ```jti``` The unique identifier for the token.
379+
* ```iat``` The issued at time.
380+
* ```exp``` The expiration time of the token.
381+
* ```userId``` The PIM user identifier (in this case, ```1```).
382+
383+
*A signature*
384+
385+
* The signature is used to verify that the token is valid and has not been tampered with. It is generated by combining the encoded header and payload, and then signing them with the secret key. The resulting signature might look like:
386+
```9WBB7ayP8UnFrOlMrI9NzTj3kxaiXOWJzElyacEKt48```
387+
388+
**Verifying the Signature**
389+
390+
To ensure that the JWT token was issued by Akeneo, you can verify the signature by re-encoding the header and payload and then signing them using the same secret key. This will allow you to confirm that the token is valid and has not been altered.
391+
392+
### Action
342393
An **action** UI extension is designed to perform external tasks in the background. Please note the following key points regarding its functionality:
343394

344395
+ **Single execution**: An action cannot be executed multiple times simultaneously. This ensures that tasks are processed in a controlled manner.
@@ -351,7 +402,6 @@ An **action** UI extension is designed to perform external tasks in the backgrou
351402
Here is a diagram illustrating the workflow:
352403
[![action-extension-schema.png](../img/extensions/ui-extensions/action-extension-schema.png)](../img/extensions/ui-extensions/action-extension-schema.png)
353404

354-
355405
Data sent within the POST body, formatted in JSON, contains :
356406
- A `data` object with different fields depending on the [position](#position).
357407
- A `context` object containing the configured `locale` and `channel`.
@@ -416,9 +466,9 @@ Examples :
416466
}
417467
```
418468

419-
### Position
469+
## Positions
420470

421-
**Extension Position**
471+
**Extension Positions**
422472

423473
Extension position determines where your extension appears within the Akeneo PIM interface. You can select from a variety of available positions, which vary depending on the specific extension type.
424474

@@ -434,10 +484,9 @@ Extension position determines where your extension appears within the Akeneo PIM
434484
* Consider the impact of the position on the overall user experience within the PIM.
435485

436486

437-
#### The following position can be added:
487+
### Positions list
438488

439489
![PIM Header.png](../img/extensions/ui-extensions/pim-header-with-extension.png)
440-
441490
#### pim.product.header
442491
This position refers to the header of a simple product or a variant edit page.
443492

@@ -448,7 +497,6 @@ This position refers to the header of a root model edit page.
448497
This position refers to the header of a sub model edit page.
449498

450499
![PIM Tab.png](../img/extensions/ui-extensions/pim-product-with-tab-extension.png)
451-
452500
#### pim.product.tab
453501
This position refers to the left panel of a simple product or a variant edit page.
454502

@@ -462,7 +510,6 @@ This position refers to the left panel of a sub model edit page.
462510
This position refers to the horizontal list of tabs on a category edit page.
463511

464512
![PIM Product Grid.png](../img/extensions/ui-extensions/pim-product-grid-with-bulk-trigger-action.png)
465-
466513
#### pim.product-grid.action-bar
467514
This position refers to the list of commands availables after selecting some products on the product grid.
468515

@@ -473,64 +520,7 @@ This position refers to the list of commands availables after selecting some pro
473520
#### pim.activity.navigation.tab
474521
This position refers to the activity PIM menu, adding UI extensions in this position will create a new section in the activity sub-navigation.
475522

476-
### Url
477-
All types of UI extensions must have a configured URL. However, the parameters that are sent—or can be sent—vary depending on the specific type of extension.
478-
#### Query parameters placeholders
479-
For [link](#link) UI extension, you can ask for specific values to construct the urls thanks to a specific placeholder pattern.
480-
481-
For example, you can configure a UI extension with the following url `https://www.google.com/search?q=%name%&tbm=shop&gl=us`, then we will dynamically put the value of the attribute code `name` when the user will click on the button.
482-
483-
Valid placeholders attributes are:
484-
- `uuid` (for products), `code` (for product models) and other attribute of type `identifier`
485-
- all text attributes. Links will use the value related to the current locale or channel.
486-
487-
You can add a placeholder anywhere in your url as soon as they're surrounded by `%` symbol.
488-
489-
Examples:
490-
- `https://www.google.com/search?q=%name%`
491-
- `https://yourwebsite.com/%sku%`
492-
- `%base_url%/sub-url`
493-
494-
::: warning
495-
If the URL begins with a placeholder, we won't verify its validity. The link might not work when used.
496-
:::
497-
498-
#### Default query parameters
499-
For an [iframe](#iframe) UI extension, several parameters are sent by default as SearchParameters in a GET query, so the server knows who is the connected user (insecure) and in which context the iframe is opened.
500-
501-
For example, when `url` is `https://customerwebsite.com/iframe/`, the called URL is `https://customerwebite.com/iframe/?paramA=valueA&paramB=valueB`
502-
503-
For all positions, parameters relative to the connected user and the extension position are sent:
504-
- `user[username]`
505-
- `user[email]`
506-
- `user[ui_locale]`
507-
- `user[catalog_locale]` except for `pim.product-grid.action-bar`
508-
- `user[catalog_scope]` except for `pim.product-grid.action-bar`
509-
- `position`
510-
511-
::: warning
512-
**Important security notice**
513-
514-
When using iframes, please be aware of the following:
515-
516-
+ **Data confidentiality**: We do not implement any security measures to verify the identity of the caller accessing the URL.
517-
518-
+ **Access control**: Anyone with access to this link can view the content of the webpage, regardless of the parameters included.
519-
520-
For sensitive data, we recommend implementing additional security measures to protect your information.
521-
:::
522-
523-
For `pim.product.tab` position, these parameters are sent:
524-
- `product[uuid]`
525-
- `product[identifier]`
526-
527-
For `pim.product-model.tab` and `pim.sub-product-model.header` position, this parameter is sent:
528-
- `product[code]`
529-
530-
For `pim.category.tab` position, this parameter is sent:
531-
- `category[code]`
532-
533-
## Available types by position
523+
### Available types by position
534524
Each position supports a specific subset of available types. The table below outlines the compatible types for all positions.
535525

536526
| Positions | Action | Iframe | Link |

0 commit comments

Comments
 (0)