I am attempting to render user information, including the Avatar of the user (if available). Whilst i can get the profilePicture information from the user JSON, it does not include the actual instance information.
I have seen how to retrieve baseUrl for Jira but cannot rely on the requestJira Fetch API.
Is there a Confluence alternative for retrieving the instances baseUrl when using Forge CustomUI? (Or am i going about this wrong? Hitting <myinstance-baseUrl>/<userJson-profileUrl> in browser returns the correct Avatar icon, but without the baseUrl the Avatars will be rendered as anonymous users)
@DennyMiller hey, I’m on the Forge team. Could you please share the JSON that you get from Confluence API? My understanding was that the profile icons should be absolute URLs according to the docs.
Any <> tags removed user information, but the profilePicture path is still shown. If i append this to my dev instance baseUrl in browser, it renders the icon.
Attempting to use Atlaskits’ Avatar presents the following error, even if using hard-coded absolute URLS (again <> redacted information):
Content Security Policy: The page's settings blocked the loading of a resource at <baseUrl>/wiki/aa-avatar/5d6cd2ca8f0aa30dba0af03c ("img-src").
Edit I should also point out this is using the get Group members endpoint docs
Using the endpoint you shared above, the path is the same, but _links contains a ‘base’ value that holds the baseUrl - get group members does not include this property
@DennyMiller this is interesting as I’m not a pro in Custom UI. However, just a sanity check question, did you set the img-src CSP in your manifest.yml with the base domain for these avatars?
At current, not yet but it was my next step to try to get this thing working (gimme a mo and i’ll give you an answer on if it changes anything).
I would question why we would need to expose the app using External Egress Permissions to hit the dev instance the app is installed on? (This may be something users raise an eyebrow at when allowing access if they see external permissions to access their own instance)
Adding the BaseURL img-src CSP into the manifest file (and redeploying) removes the Browser error, but the Avatar icons are still returning as anonymous icons - this is tested with:
The path provided from the user JSON
The BaseURL hard coded before the user JSON path
The full BaseURL hardcoded
Edit To further test, a full jpg img location was added to the manifest and tested with a hardcoded URL including the baseURL hardcoded - still returning grey anonymous user icon
This works, but isn’t what we require (especially when trying to use the icon path in the user JSON.
Upon further investigation, using a URL of "< instance >/< user path form json > " requires the manifest to include the dev instance, along with any redirect domains the avatar icon is stored at - For example:
-Using a basic avatar containing the first letter of Users names:
Hardcoding the baseURL + path provided in JSON redirects to the following domain:
This is just using 2 example avatars, both of which require an additional external domain on top of the instance being used. Not only that, but in doing so raises a few questions:
How exactly can we add in the Users instance into the manifest if using a production version? (For now, it’s hardcoded using my dev instance, meaning it only works on that instance, correct?)
Surely the solution is not "Just keep adding external img-scp’s and re-deploy anytime you cannot render a specific avatar? (At this point is it not possible to allow UI-Kit extension from within CustomUI? Specifying an avatar using a User ID is much simpler, but the functionality for our app requirements just isn’t there with UI-Kit)
Even if this is the solution and just something we have to manage whenever icons cannot be found, the original problem of ‘we still cannot access the baseURL of the instance we are in’ still exists. At the time of writing, Confluence Cloud Rest API offers no way of retrieving this information, whilst Jira’s API has access to this.
Many thanks for getting to the end of my long response, hoepfully it gives an insight into the Use Case/The problem occurring. You may not be able to provide a response with things in the response, but that’s okay as any problems/current lack of support will be compiled for CodeGeist
Regarding point 1, <instance-baseURL > plus the path in User JSON provided (the /wiki/aa-avatar/... ) will redirect to the avatar-management URL (for example)… I have tried with multiple avatars (both default avatars and those the User has changed).
For Proof of Concept, rendering these icons is not a huge priority, so I will most likely leave this until a future point - perhaps with answers to my previous comment this functionality may be explained a bit better in regards to why we would need to add external img-src permissions into the manifest when attempting to access default, internal, Avatar icons.
@DennyMiller now I got it. Thanks for explaining. I believe this is a problem on the edge of Forge and product API. We actually have a team that can help here. I will let them know about this problem.
UPD: out of interest, did you try using *.atlassian.net in your permissions.external.images? This should work for all installations if I’m not mistaken.
I can confirm that using ‘*.atlassian.net’ allows all instances as they are subdomains, however this is not the problem so I think I need to step back a bit and re-state the current problem in simpler terms:
In theory
If i want to retrieve a users avatar, I can use the path provided in the Users JSON. Let me provide a few examples of User Avatars:
User A
User JSON path: /wiki/aa-avatar/5d6cd2ca8f0aa30dba0af03c
The Atlaskit <Avatar> component will only display the image if I hardcode my Test Instance’s baseURL into the src property - for example:
//The baseURL of the test instance is placed here
let baseURL = "https://TESTINSTANCE.atlassian.net";
<Avatar
appearance="circle"
/*avatar src is baseUrl + path from userJSON*/
src={`${baseUrl}/wiki/aa-avatar/5d6cd2ca8f0aa30dba0af03c"}
size="large"
name="John Doe"
/>
The above avatar will only render when both '*.atlassian.net'AND'https://i0.wp.com/' are added in the manifest. This is just for one avatar, and as shown with the above examples, each one would need yet another img-scp added to the manifest (what if 1000 users have different paths, you can’t expect us to add all 1000 domains into the manifest - and if so, how do we know the domains until a User provides feedback their avatar is not being displayed?)
To get a solution
I am still hard-coding the baseURL - without a way to retrieve the baseURL in confluence, this will only work on the hardcoded instance - if the User JSON path does not provide an Absolute URL, could you (or someone that is aware of how) please explain how we are supposed to get the absolute URL
Are we expected to add EVERY domain, updating the manifest as we encounter a user with a new one? - If users install the app and it says “Share data with 1000 domains outside of Atlassian” because we’ve had to keep appending new domains for every User, they won’t like seeing that (and it’s a poor way of maintaining how we allow access to the avatars?)
Perhaps going off this comment may be easier to understand the problem at hand. I’m surprised this hasn’t been spoken about before, but this is CustomUI specific - (using UIKit would allow avatar rendering from the users accountId)… Maybe consideration on allowing UIKit components to be used in CustomUI is something to look into?)
Solution
The provided endpoints either don’t provide the absolute URL, or when used alongside the baseUrl get joined with 2 /wiki directories. Seems like a poor design overlook .
The workaround I have used is as follows: Manifest File
For default avatar icons, both of the above img-scp permissions are required. This will allow the default icons to be rendered when used with the instance’s baseUrl
To retrieve the Users profilePicture path
This does not provide the absolute URL, but can be retrieved from the returned user JSON, for example:
/wiki/aa-avatar/60eeeae4a0de58006ab76f54
To retrieve the baseUrl
With the new changes to Product API without the need for Custom Resolvers.
The returned value also contains /wiki so needs to be stripped
//Retrieves instance baseUrl
useEffect(() => {
async function getBaseUrl(){
let newVar = await requestConfluence(`/wiki/rest/api/settings/systemInfo`);
let baseUrl = newVar.body.baseUrl;
//remove the '/wiki' path, or using the given url would search for instanceUrl/wiki/wiki/xyz
let trimmedBaseUrl = baseUrl.substring(0, baseUrl.length - 5);
setBaseUrl(trimmedBaseUrl);
}
getBaseUrl();
}, []);
Avatar Rendering
Without stripping the wiki on baseUrl, this will not function.
Would it be fair to assume that this is how it should be achieved if the returned user JSON does not provide an absolute URL? Along with the fact that combining the default baseUrl would result in an incorrect URL?
Hey @DennyMiller, your solution seems to be a good workaround at the moment. We have this Confluence API to retrieve the base URL - and yes you would need to strip the wiki on this for the function to work.