We have a requirement to create an admin page in our firefly app which will be configured to take all the API's endpoints and API key initially on App setup and set those values for all the app users. It's mostly all the fields that go in .env file but we want it to be configurable by admin.
1. Can we use aio-lib-state for this?
2. If yes, whether these configurations would be available for all users?
3. And how to initialize this as the first thing app loads for any user.
4. Also, we're not sure how to retrieve values from aio-lib-state from different action files.
This would be similar to how the ims object becomes available on bootstrapping the app in index.js
Thanks in advance.
@shelly-goel - a Firefly app is deployed to a workspace that you specify, which assigns a Runtime namespace and relevant State lib access for it.
Speaking about app state, there are 2 separate concepts:
Can you elaborate on the request? Which kind of variables are you asking about?
Hi @shelly-goel we have implemented something like this, maybe the following ideas give you a starting point.
"Define Admins": we use "Product Profiles" to define which user should be an admin. basically we created a new product profile and added users as needed. The benefit is that you can now check the ims object if the current user of the firefly app is an admin or not (by looping through ims.profile.roles - is some work to figure out the details about a specific role). remark: the Role ID is stored in the ENV-File, so you need to create the product profile before deployment. But since you might use the same product profile for all environments, you already need it for testing and therefore it is aready available for production.
"Store Config Settings": we store the config settings using aio-lib-files and store the config as json object in a single file. but you can use aio-lib-state as well, but don't forget to set the right expiry if using state... using this setup allows to change the config after deployment (see below) without the need to redeploy anything.
Remark: the filename for the config file is defined in the .env file so that all actions have access to the right file - no need to change all over the app...
"Admin Screen": the core of the solution is a defined view in react with special behaviour and some additional actions. here are some points about this admin screen
As an additional security step we implemented a manual check for the user permission on "fetch settings" and "change settings". Just in case somebody is able to see the admin screen, this additional check would prevent the display and modification of any data. How it works: on both actions (2+3 above) we make a manual API call to Adobe User Management and fetch the roles of the end user separately. Drawback is that you need some special permissions (and therefore additional API credentials) to access the User Management API. maybe it is enough if you just add an additional (almost hidden) key + timestamp to the action request which you check before doing anything.
"Use settings in the app/actions": last step is a class that allows to fetch the current app settings. basically you load the class and on init it returns the config object. this way all actions can access the same settings ...
While I think this setup allows a lot of flexibility, it also takes some time to make the setup. so be aware that this will cause more effort compared to just releasing a new version on the desired environment.
Happy to discuss pros and cons - or to answer additional questions
@Urs_Boller- Below is how it would be written into the file, there's just write method and no append method that's why it's overridden.
await files.write('public/index.html', '<h1>Hello World!</h1>')
Theoretically I understand what needs to be done but not getting the actual code implementation. I'm getting stuck with the code so if you have snippets that would be useful.
@shelly-goelyou need to check if there is any old file either by looping through all files with files.list or check files.property of desired file. if the file already exists and has valid content, then use this content, otherwise use some "hard coded" content (so default might be directly in your src code). hope this helps