Vulnerability in EPiServer.Forms
We recently upgraded and converted over to the new approval sequences.
I have a few questions that have been raised by our web admins:
1. As mentioned here: https://world.episerver.com/forum/developer-forum/Feature-requests/Thread-Container/2018/3/approval-sequences-can-an-admin-bypass-an-approval-sequence/ There is no way for a webadmin to approve the page directly without doing the approval sequence, sometimes the changes are small and we trust our gatekeepers to approve content immediately. If I can't get the product to do it, can I create a plugin to sit next to the publish button?
It would be very basic, if the current user has admin access to the page, run code to publish the page. I just can't find any info on customisations in this area.
2. We use groups for approvals, we would like to see the usernames of the people who are awaiting to do the approval, sometime we need to call people so we need to know who is in the group. (Again, if I have access to create something near the publish button, I could probably extract the information for the editors.)
3. Is there a way to customise the approval emails? We would like to add branding and different wording.
Thanks for your help legends!
Anyone able to help?
I can't provide the full solution, but maybe I can get you part of the way.
For #1, you could hook into the content events for the page and programmatically force approval.
Example, as done in an initialization module:
public class CustomApprovalsInitialization : IInitializableModule
public void Initialize(InitializationEngine context)
var contentEvents = ServiceLocator.Current.GetInstance<IContentEvents>();
contentEvents.RequestedApproval += ContentEvents_RequestedApproval;
private void ContentEvents_RequestedApproval(object sender, EPiServer.ContentEventArgs e)
var approvalRepository = ServiceLocator.Current.GetInstance<IApprovalRepository>();
var contentApproval = approvalRepository.GetAsync(e.ContentLink).Result;
if (contentApproval != null)
var approvalEngine = ServiceLocator.Current.GetInstance<IApprovalEngine>();
approvalEngine.ForceApproveAsync(contentApproval.ID, PrincipalInfo.Current.Name, "Auto-approved by Admin.");
public void Uninitialize(InitializationEngine context)
//Add uninitialization logic
The only downside of this approach is you'll need to refresh the page to see the auto-approval take place.
Optionally, I think if an admin is part of every step of an approval sequence, they should be able to see the "Approve Entire Approval Sequence" link below the "Approve Content" button. This is likely the better way to go.
For #3, I dug into this a bit, and there's not a super simple way to do it. The actual email template is an embedded resource, and the call to get the template is internal. To get started, you'll need to create a custom formatter (INotificationFormatter) as explained here: https://world.episerver.com/documentation/developer-guides/CMS/using-notifications/usage-examples/. From here, I would suggest digging into this more by decompiling the class "ApprovalHtmlEmailFormatter" in the EPiServer.Cms.Shell.UI.Approvals.Notifications namespace, and looking how the FormatMessagesAsync() is done.
Hope this helps!
Thanks so much Chris, forcing the approval worked well, it actually does refresh and displays a publish button.
Very much appreciated thanks!!