Building a Salesforce Form using Sites that is Time-bombed
Project
Build a form off salesforce that can be sent to clients to collect information. Sent by email through salesforce as a button available to sales users off the account record
Requirements
- Secure
- Link is time-bombed to 24 hours to prevent re-entry updates
- Updates account record validates information lightly upfront
What I Currently have Accomplished
Built Visualforce form off sites
validation rules are written off jQuery
What I could use advice with
How to create a time bombed link to send to each customer listed on the record
How to send the form to each client with its information feeding back to the sending record.
Any help is appreciated! I'm looking for a discussion on the topic mostly.
If what I ask is impossible feel free to poke holes.
visualforce email account form hyperlink
add a comment |
Project
Build a form off salesforce that can be sent to clients to collect information. Sent by email through salesforce as a button available to sales users off the account record
Requirements
- Secure
- Link is time-bombed to 24 hours to prevent re-entry updates
- Updates account record validates information lightly upfront
What I Currently have Accomplished
Built Visualforce form off sites
validation rules are written off jQuery
What I could use advice with
How to create a time bombed link to send to each customer listed on the record
How to send the form to each client with its information feeding back to the sending record.
Any help is appreciated! I'm looking for a discussion on the topic mostly.
If what I ask is impossible feel free to poke holes.
visualforce email account form hyperlink
add a comment |
Project
Build a form off salesforce that can be sent to clients to collect information. Sent by email through salesforce as a button available to sales users off the account record
Requirements
- Secure
- Link is time-bombed to 24 hours to prevent re-entry updates
- Updates account record validates information lightly upfront
What I Currently have Accomplished
Built Visualforce form off sites
validation rules are written off jQuery
What I could use advice with
How to create a time bombed link to send to each customer listed on the record
How to send the form to each client with its information feeding back to the sending record.
Any help is appreciated! I'm looking for a discussion on the topic mostly.
If what I ask is impossible feel free to poke holes.
visualforce email account form hyperlink
Project
Build a form off salesforce that can be sent to clients to collect information. Sent by email through salesforce as a button available to sales users off the account record
Requirements
- Secure
- Link is time-bombed to 24 hours to prevent re-entry updates
- Updates account record validates information lightly upfront
What I Currently have Accomplished
Built Visualforce form off sites
validation rules are written off jQuery
What I could use advice with
How to create a time bombed link to send to each customer listed on the record
How to send the form to each client with its information feeding back to the sending record.
Any help is appreciated! I'm looking for a discussion on the topic mostly.
If what I ask is impossible feel free to poke holes.
visualforce email account form hyperlink
visualforce email account form hyperlink
asked Nov 30 '18 at 20:13
Ryan SherryRyan Sherry
274
274
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
You could certainly create an expiring token to "time bomb" your page. The following steps should provide an outline:
- Add a field named
Form_Token__c
Text (32)
- Add a
Time Based Workflow Rule
to clear the value after 24 hours
Update any triggers on your object (or add one if none exist) to set this token value
Since I have been looking at how to generate a UUID, the following code springs to mind:
record.Form_Token__c = EncodingUtil.ConvertTohex(Crypto.GenerateAESKey(128));
Add this property to your controller:
public Boolean getHasValidToken()
{
String token = ApexPages.currentPage().getParameters.get('token');
return (token != null && token == record.Form_Token__c);
}
- Merge
token={!record.Form_Token__c}
into your url
Update your markup to key on the
hasValidToken
value, something like below:
<apex:page controller="...">
<apex:pageMessage summary="<expiry notice>" rendered="{!NOT(hasValidToken)}" />
<apex:outputPanel layout="none" rendered="{!hasValidToken}">
<!-- existing markup -->
</apex:outputPanel>
</apex:page>
First of all Adrian, you are the man for answering this so fast! Second, let me dive into this and I'll get back to you. Appreciate this a ton.
– Ryan Sherry
Nov 30 '18 at 20:29
will that be good to put expiry dateTime in the record? and check if the current date is less than expiry dateTime? wont need workflow then, also in case you wana make that link valid(any reason), you can just extend the expiry date. instead of sending new link again?
– Pranay Jaiswal
Nov 30 '18 at 21:01
1
I thought about adding expiry date on the question, and it was in my initial writeup. But honestly it is way better to manage the interval in configuration if you can.
– Adrian Larson♦
Nov 30 '18 at 21:30
add a comment |
Another thought...
You could store a secret key in a custom setting or custom metadata. When you generate a link, it will have an expiry timestamp parameter, a customer ID parameter and a hash parameter.
The hash would be generated in Apex by appending the timestamp and the ID into one string, encrypting it with the secret key, generating a MD5 digest, and then converting to hexadecimal.
When the page is visited, Apex would validate the hash by attempting to recalculate it from the secret and the other parameters. If the output matches the hash in the URL, it's legit and they're allowed in.
What's nice about this approach is, the whole request is tamper proof. You can add more parameters and add them to the hash algorithm, and the URL will only be valid for exactly that same combination of parameters it was generated for. Also you don't have to actually store any information about ongoing validity of tokens. You can simply authenticate whether a request was genuine and unexpired on-the-fly.
This is great thank you for such a thought out response. I'll look into this further once I am farther along with my project.
– Ryan Sherry
Dec 3 '18 at 19:31
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "459"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f241092%2fbuilding-a-salesforce-form-using-sites-that-is-time-bombed%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You could certainly create an expiring token to "time bomb" your page. The following steps should provide an outline:
- Add a field named
Form_Token__c
Text (32)
- Add a
Time Based Workflow Rule
to clear the value after 24 hours
Update any triggers on your object (or add one if none exist) to set this token value
Since I have been looking at how to generate a UUID, the following code springs to mind:
record.Form_Token__c = EncodingUtil.ConvertTohex(Crypto.GenerateAESKey(128));
Add this property to your controller:
public Boolean getHasValidToken()
{
String token = ApexPages.currentPage().getParameters.get('token');
return (token != null && token == record.Form_Token__c);
}
- Merge
token={!record.Form_Token__c}
into your url
Update your markup to key on the
hasValidToken
value, something like below:
<apex:page controller="...">
<apex:pageMessage summary="<expiry notice>" rendered="{!NOT(hasValidToken)}" />
<apex:outputPanel layout="none" rendered="{!hasValidToken}">
<!-- existing markup -->
</apex:outputPanel>
</apex:page>
First of all Adrian, you are the man for answering this so fast! Second, let me dive into this and I'll get back to you. Appreciate this a ton.
– Ryan Sherry
Nov 30 '18 at 20:29
will that be good to put expiry dateTime in the record? and check if the current date is less than expiry dateTime? wont need workflow then, also in case you wana make that link valid(any reason), you can just extend the expiry date. instead of sending new link again?
– Pranay Jaiswal
Nov 30 '18 at 21:01
1
I thought about adding expiry date on the question, and it was in my initial writeup. But honestly it is way better to manage the interval in configuration if you can.
– Adrian Larson♦
Nov 30 '18 at 21:30
add a comment |
You could certainly create an expiring token to "time bomb" your page. The following steps should provide an outline:
- Add a field named
Form_Token__c
Text (32)
- Add a
Time Based Workflow Rule
to clear the value after 24 hours
Update any triggers on your object (or add one if none exist) to set this token value
Since I have been looking at how to generate a UUID, the following code springs to mind:
record.Form_Token__c = EncodingUtil.ConvertTohex(Crypto.GenerateAESKey(128));
Add this property to your controller:
public Boolean getHasValidToken()
{
String token = ApexPages.currentPage().getParameters.get('token');
return (token != null && token == record.Form_Token__c);
}
- Merge
token={!record.Form_Token__c}
into your url
Update your markup to key on the
hasValidToken
value, something like below:
<apex:page controller="...">
<apex:pageMessage summary="<expiry notice>" rendered="{!NOT(hasValidToken)}" />
<apex:outputPanel layout="none" rendered="{!hasValidToken}">
<!-- existing markup -->
</apex:outputPanel>
</apex:page>
First of all Adrian, you are the man for answering this so fast! Second, let me dive into this and I'll get back to you. Appreciate this a ton.
– Ryan Sherry
Nov 30 '18 at 20:29
will that be good to put expiry dateTime in the record? and check if the current date is less than expiry dateTime? wont need workflow then, also in case you wana make that link valid(any reason), you can just extend the expiry date. instead of sending new link again?
– Pranay Jaiswal
Nov 30 '18 at 21:01
1
I thought about adding expiry date on the question, and it was in my initial writeup. But honestly it is way better to manage the interval in configuration if you can.
– Adrian Larson♦
Nov 30 '18 at 21:30
add a comment |
You could certainly create an expiring token to "time bomb" your page. The following steps should provide an outline:
- Add a field named
Form_Token__c
Text (32)
- Add a
Time Based Workflow Rule
to clear the value after 24 hours
Update any triggers on your object (or add one if none exist) to set this token value
Since I have been looking at how to generate a UUID, the following code springs to mind:
record.Form_Token__c = EncodingUtil.ConvertTohex(Crypto.GenerateAESKey(128));
Add this property to your controller:
public Boolean getHasValidToken()
{
String token = ApexPages.currentPage().getParameters.get('token');
return (token != null && token == record.Form_Token__c);
}
- Merge
token={!record.Form_Token__c}
into your url
Update your markup to key on the
hasValidToken
value, something like below:
<apex:page controller="...">
<apex:pageMessage summary="<expiry notice>" rendered="{!NOT(hasValidToken)}" />
<apex:outputPanel layout="none" rendered="{!hasValidToken}">
<!-- existing markup -->
</apex:outputPanel>
</apex:page>
You could certainly create an expiring token to "time bomb" your page. The following steps should provide an outline:
- Add a field named
Form_Token__c
Text (32)
- Add a
Time Based Workflow Rule
to clear the value after 24 hours
Update any triggers on your object (or add one if none exist) to set this token value
Since I have been looking at how to generate a UUID, the following code springs to mind:
record.Form_Token__c = EncodingUtil.ConvertTohex(Crypto.GenerateAESKey(128));
Add this property to your controller:
public Boolean getHasValidToken()
{
String token = ApexPages.currentPage().getParameters.get('token');
return (token != null && token == record.Form_Token__c);
}
- Merge
token={!record.Form_Token__c}
into your url
Update your markup to key on the
hasValidToken
value, something like below:
<apex:page controller="...">
<apex:pageMessage summary="<expiry notice>" rendered="{!NOT(hasValidToken)}" />
<apex:outputPanel layout="none" rendered="{!hasValidToken}">
<!-- existing markup -->
</apex:outputPanel>
</apex:page>
answered Nov 30 '18 at 20:27
Adrian Larson♦Adrian Larson
106k19112238
106k19112238
First of all Adrian, you are the man for answering this so fast! Second, let me dive into this and I'll get back to you. Appreciate this a ton.
– Ryan Sherry
Nov 30 '18 at 20:29
will that be good to put expiry dateTime in the record? and check if the current date is less than expiry dateTime? wont need workflow then, also in case you wana make that link valid(any reason), you can just extend the expiry date. instead of sending new link again?
– Pranay Jaiswal
Nov 30 '18 at 21:01
1
I thought about adding expiry date on the question, and it was in my initial writeup. But honestly it is way better to manage the interval in configuration if you can.
– Adrian Larson♦
Nov 30 '18 at 21:30
add a comment |
First of all Adrian, you are the man for answering this so fast! Second, let me dive into this and I'll get back to you. Appreciate this a ton.
– Ryan Sherry
Nov 30 '18 at 20:29
will that be good to put expiry dateTime in the record? and check if the current date is less than expiry dateTime? wont need workflow then, also in case you wana make that link valid(any reason), you can just extend the expiry date. instead of sending new link again?
– Pranay Jaiswal
Nov 30 '18 at 21:01
1
I thought about adding expiry date on the question, and it was in my initial writeup. But honestly it is way better to manage the interval in configuration if you can.
– Adrian Larson♦
Nov 30 '18 at 21:30
First of all Adrian, you are the man for answering this so fast! Second, let me dive into this and I'll get back to you. Appreciate this a ton.
– Ryan Sherry
Nov 30 '18 at 20:29
First of all Adrian, you are the man for answering this so fast! Second, let me dive into this and I'll get back to you. Appreciate this a ton.
– Ryan Sherry
Nov 30 '18 at 20:29
will that be good to put expiry dateTime in the record? and check if the current date is less than expiry dateTime? wont need workflow then, also in case you wana make that link valid(any reason), you can just extend the expiry date. instead of sending new link again?
– Pranay Jaiswal
Nov 30 '18 at 21:01
will that be good to put expiry dateTime in the record? and check if the current date is less than expiry dateTime? wont need workflow then, also in case you wana make that link valid(any reason), you can just extend the expiry date. instead of sending new link again?
– Pranay Jaiswal
Nov 30 '18 at 21:01
1
1
I thought about adding expiry date on the question, and it was in my initial writeup. But honestly it is way better to manage the interval in configuration if you can.
– Adrian Larson♦
Nov 30 '18 at 21:30
I thought about adding expiry date on the question, and it was in my initial writeup. But honestly it is way better to manage the interval in configuration if you can.
– Adrian Larson♦
Nov 30 '18 at 21:30
add a comment |
Another thought...
You could store a secret key in a custom setting or custom metadata. When you generate a link, it will have an expiry timestamp parameter, a customer ID parameter and a hash parameter.
The hash would be generated in Apex by appending the timestamp and the ID into one string, encrypting it with the secret key, generating a MD5 digest, and then converting to hexadecimal.
When the page is visited, Apex would validate the hash by attempting to recalculate it from the secret and the other parameters. If the output matches the hash in the URL, it's legit and they're allowed in.
What's nice about this approach is, the whole request is tamper proof. You can add more parameters and add them to the hash algorithm, and the URL will only be valid for exactly that same combination of parameters it was generated for. Also you don't have to actually store any information about ongoing validity of tokens. You can simply authenticate whether a request was genuine and unexpired on-the-fly.
This is great thank you for such a thought out response. I'll look into this further once I am farther along with my project.
– Ryan Sherry
Dec 3 '18 at 19:31
add a comment |
Another thought...
You could store a secret key in a custom setting or custom metadata. When you generate a link, it will have an expiry timestamp parameter, a customer ID parameter and a hash parameter.
The hash would be generated in Apex by appending the timestamp and the ID into one string, encrypting it with the secret key, generating a MD5 digest, and then converting to hexadecimal.
When the page is visited, Apex would validate the hash by attempting to recalculate it from the secret and the other parameters. If the output matches the hash in the URL, it's legit and they're allowed in.
What's nice about this approach is, the whole request is tamper proof. You can add more parameters and add them to the hash algorithm, and the URL will only be valid for exactly that same combination of parameters it was generated for. Also you don't have to actually store any information about ongoing validity of tokens. You can simply authenticate whether a request was genuine and unexpired on-the-fly.
This is great thank you for such a thought out response. I'll look into this further once I am farther along with my project.
– Ryan Sherry
Dec 3 '18 at 19:31
add a comment |
Another thought...
You could store a secret key in a custom setting or custom metadata. When you generate a link, it will have an expiry timestamp parameter, a customer ID parameter and a hash parameter.
The hash would be generated in Apex by appending the timestamp and the ID into one string, encrypting it with the secret key, generating a MD5 digest, and then converting to hexadecimal.
When the page is visited, Apex would validate the hash by attempting to recalculate it from the secret and the other parameters. If the output matches the hash in the URL, it's legit and they're allowed in.
What's nice about this approach is, the whole request is tamper proof. You can add more parameters and add them to the hash algorithm, and the URL will only be valid for exactly that same combination of parameters it was generated for. Also you don't have to actually store any information about ongoing validity of tokens. You can simply authenticate whether a request was genuine and unexpired on-the-fly.
Another thought...
You could store a secret key in a custom setting or custom metadata. When you generate a link, it will have an expiry timestamp parameter, a customer ID parameter and a hash parameter.
The hash would be generated in Apex by appending the timestamp and the ID into one string, encrypting it with the secret key, generating a MD5 digest, and then converting to hexadecimal.
When the page is visited, Apex would validate the hash by attempting to recalculate it from the secret and the other parameters. If the output matches the hash in the URL, it's legit and they're allowed in.
What's nice about this approach is, the whole request is tamper proof. You can add more parameters and add them to the hash algorithm, and the URL will only be valid for exactly that same combination of parameters it was generated for. Also you don't have to actually store any information about ongoing validity of tokens. You can simply authenticate whether a request was genuine and unexpired on-the-fly.
edited Dec 1 '18 at 3:22
answered Nov 30 '18 at 23:36
Charles TCharles T
6,3311822
6,3311822
This is great thank you for such a thought out response. I'll look into this further once I am farther along with my project.
– Ryan Sherry
Dec 3 '18 at 19:31
add a comment |
This is great thank you for such a thought out response. I'll look into this further once I am farther along with my project.
– Ryan Sherry
Dec 3 '18 at 19:31
This is great thank you for such a thought out response. I'll look into this further once I am farther along with my project.
– Ryan Sherry
Dec 3 '18 at 19:31
This is great thank you for such a thought out response. I'll look into this further once I am farther along with my project.
– Ryan Sherry
Dec 3 '18 at 19:31
add a comment |
Thanks for contributing an answer to Salesforce Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f241092%2fbuilding-a-salesforce-form-using-sites-that-is-time-bombed%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown