-
Type:
Suggestion
-
Resolution: Unresolved
-
Component/s: Forge - External API Authentication
Performing a request to the Get avatar image by ID https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-avatars/#api-rest-api-3-universal-avatar-view-type-type-avatar-id-get can be can be accessed anonymously when performing the search for default icons. However, using and displaying custom issue type icons/project avatars needs to have authentication.
With Forge applications, performing the request encounters a 403 error. Therefore, performing the same authentication for custom issue type icons/project avatars as with the default ones icons would be beneficial, one possibility would be to use directly the icon URL:
Avatar appearance='square' size='small' src={type.icon}/>
Workaround
The issue is that browser can’t match api.atlassian.com domain with document.URL and so doesn’t send authentication information when requesting custom avatars.
We can convert the URL and replace api.atlassian.com with the siteURL and then it works as the browser can match and include authentication. Here’s and example code.
import React, { useEffect, useState } from 'react'; import ForgeReconciler, { Text, Image, useProductContext } from '@forge/react'; import { requestJira } from '@forge/bridge'; const convertIconUrl = (iconUrl, siteUrl) => { const match = iconUrl.match(/https:\/\/api\.atlassian\.com\/ex\/jira\/[^/]+(\/.*)/); if (!match) return iconUrl; return `${siteUrl}${match[1]}`; }; const getIssueDetails = async (issueKey) => { const response = await requestJira(`/rest/api/3/issue/${issueKey}`); const data = await response.json(); return { key: data.key, summary: data.fields.summary, iconUrl: data.fields.issuetype.iconUrl, }; }; const App = () => { const [data, setData] = useState(null); const context = useProductContext(); useEffect(() => { if (!context) return; const issueKey = context.extension.issue.key; const siteUrl = context.siteUrl; getIssueDetails(issueKey).then((issue) => { setData({ ...issue, iconUrl: convertIconUrl(issue.iconUrl, siteUrl) }); }); }, [context]); return ( <> {data ? ( <> <Image src={data.iconUrl} alt={`${data.key} issue type icon`} /> <Text>{data.key}</Text> <Text>{data.summary}</Text> </> ) : ( <Text>Loading...</Text> )} </> ); };
- relates to
-
FRGE-680 Loading...