Resource Page for Jaipur Developer Festival session Publishing your app on Appexchange
Link to slide deck Publishing your app on Appexchange – Sagar Pareek
1. Storing Secrets –
What is it? : Sensitive data is exposed to user.
Remedy: Use protected custom settings.
Create custom settings with private as visibility.
Name it App Custom Settings.
Make sure setting type is List.
Create a custom object named Integration Setting
Name field should be of Auto Number ( I-{00000} )
Create 3 custom fields
Username
Password
Endpoint URL
Trigger Code –
/* Created By: Sagar Pareek
Description: This trigger replaces the password with asteriks and saves the password in protected custom settings mapped with username.
*/
trigger IntegrationSettings on Integration_Settings__c (before insert, before update) {
if (trigger.isBefore){
// Map to be checked against for the existence of a Custom Setting for a User
map userToCustomSetting = new map();
// Lists for new, updated, and existing settings.
list newSettings = new list();
list updateSettings = new list();
list existingSettings = [SELECT Id, Name, Password__c FROM App_Custom_Settings__c ORDER BY CreatedDate LIMIT 25];
list validApplicationSettings = new list();
// Populate the map based on the above query's results - keyed by the Username (name contains username)
if (!existingSettings.isEmpty()){
for (App_Custom_Settings__c s : existingSettings){
userToCustomSetting.put(s.Name,s);
}
}
for (Integration_Settings__c stg : trigger.new){
if (stg.Password__c != null && stg.Password__c != '' ){
// Inserts are easier - as long as the Password was provided, we'll add it
if (trigger.isInsert)
validApplicationSettings.add(stg);
// We'll make sure the old and new Password values don't match and aren't udpated to the "masked" value
else if (trigger.isUpdate)
if (stg.Password__c != '********' && stg.Password__c != trigger.oldMap.get(stg.id).Password__c)
validApplicationSettings.add(stg);
}
}
if (!validApplicationSettings.isEmpty()){
for (Integration_Settings__c stg : validApplicationSettings){
// Do any Custom Settings exist for this User? If so, update. Otherwise, create.
if (userToCustomSetting.containsKey(stg.Username__c)){
userToCustomSetting.get(stg.Username__c).Password__c = stg.Password__c;
updateSettings.add(userToCustomSetting.get(stg.Username__c));
}
else{
newSettings.add(new App_Custom_Settings__c(Name = stg.Username__c, Password__c = stg.Password__c));
}
// Replace the Password
stg.Password__c = '********';
}
// Do inserts and updates
if (!newSettings.isEmpty())
insert newSettings;
if (!updateSettings.isEmpty())
update userToCustomSetting.values();
}
}
}
Force.com Security Scan Report
Link to force.com security scan report
Sample ZAP Report
Reporting False Positives in ZAP report
Link to False positive documentation
On Passing your review –
