Use Attachment Images in Custom UI

Well, I’m not sure if someone waved a magic wand or what but I closed and reopened the issue editor and now the remote image is loading just great! I guess I had just been refreshing the page previously as that is typically all I need to do. Anyway, scratch that last question.

Thanks again for all the great work on the CSP extensions.

Best Regards,
Jeff Ryan

3 Likes

Hey @SamSmyth. I am using the confluence APIs to save attachments in confluence page using forge custom UI app.
I want to display those attachments in my IMG or audio HTML tag.
After fetching the URL using the confluence APIs and putting all the permission in manifest, the audio is still blocked by CSP.

Content Security Policy: The page’s settings blocked the loading of a resource at “https://your-domain.atlassian.net/wiki/download/attachments/557079/Insane.mp3?version=2&modificationDate=1632897649047&cacheVersion=1&api=v2 (“media-src”).”

Manifest.yml permission -

I have also included the permission for it, still I’m not able to figure out why it’s blocking the resource. If you know about this error, please help.

Hey @YashShivhare,

Can you confirm that the domain listed in the error message matches the entry in the media: manifest property? If this is the case can you share with me a bit more detail about the error message (e.g. the exact message you are seeing), feel free to share this with me over a private message :slightly_smiling_face:.

Hey @SamSmyth, thanks for the reply…

I was able to solve the previous problem, but now when I’m trying to record voice using mic and creating a URL using window.URL.createObjectURL of blob for playing the recorded audio, but I’m not able to play that It display error like this -

Content Security Policy: The page’s settings blocked the loading of a resource at blob:https://8700c44c-6c5a-4527-9234-c7c035f9ddfa.cdn.prod.atlassian-dev.net/4ad70f49-cbf0-4c4b-be60-ac5581eed19d.

This is the iframe URL of my app -

https://8700c44c-6c5a-4527-9234-c7c035f9ddfa.cdn.prod.atlassian-dev.net/c53293cc-d030-4244-bbed-20470aaa81cd/e614735d-8f92-40d6-bf71-35331b451cbd/fff69f03-9ba4-460f-8c1f-430e7594a841/main/index.html

What do you suggest I include in my manifest to allow it to play?
Since it’s not a straight forward URL, it’s a blob URL. I’m a little confused and since it’s playing the audio, should I include it in my media permission inside manifest.yml.

Hey @YashShivhare,

Sadly we don’t currently support blob in our Content Security Policy. Would love if you could raise a ticket on our public feedback board to help us track and prioritise shipping this feature.

Hi @SamSmyth,

As we currently have an API to download confluence attachments, it is just about allowing that API scope. Can you please do that, I believe it is a quick fix.

Details in @spall issue here [FRGE-410] - Ecosystem Jira

Hi,

Unfortunately I got the same issue. I want to display attachment (image) in Custom UI. How can I solve it?

This still seems to be an issue…

We want to display images attached to Confluence content using Custom UI, but they are blocked by CSP. <img src="{siteUrl}/wiki/{attachment._links.download}" />

In our manifest, we have:

permissions:
  scopes:
    - read:confluence-content.all
    - readonly:content.attachment:confluence
  external:
    images:
      - '*.atlassian.net'
      - '*.media.atlassian.com'

Is there something we are missing? It can’t really be that it’s impossible to display attachments, right? @SamSmyth

Kind regards,
Christian

2 Likes

It’s a limitation of the way Custom UI macros are embedded in iFrames and the way message passing works between iFrames.

I am investigating using a custom resolver to convert the binary data to base64 data before it gets to the <img src.

Okay I got this working by adding a custom resolver called getImage as follows

import api, { route } from '@forge/api'

export const getImage = async ({ payload: { id, attachmentId } }) => {
  console.debug('getImage', attachmentId)

  const response = await api
    .asUser()
    .requestConfluence(
      route`/wiki/rest/api/content/${id}/child/attachment/${attachmentId}/download`
    )

  const contentType = response.headers.get('content-type')
  const buffer = await response.arrayBuffer()
  const imageInBase64 = Buffer.from(buffer).toString('base64')

  return `data:${contentType};base64,${imageInBase64}`
}

which is invoked from a react hook in the custom UI

const image = await invoke('getImage',{ id, attachmentId })
1 Like

Yet another bug I’ve found and reported is that they’re missing https://api.media.atlassian.com in the CSP.

So trying to render an image src of:

https://[instance].atlassian.net/rest/api/3/attachment/thumbnail/12345

Results in:

Refused to load the image 'https://api.media.atlassian.com/file/...' because it violates the following Content Security Policy directive: "img-src 'self' data: blob: [instance].atlassian.net https://secure.gravatar.com https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net https://api.atlassian.com".

Forge is such a nightmare to build on.

1 Like