ColdFusion form and session variable setting - coldfusion

I have a checkbox inside of a form tag and I basically want to persist the checked state of the checkbox using a session. Apparently I'm doing it wrong because whenever I reload the page it sets the session back to off(which is the default value for the checkbox param). Here is the code i'm using.
Form:
<cfform name="matureContent" method="post" action="/index.cfm?fuseaction=main.Channels_Detail&c=#URL.c#" enctype="multipart/form-data">
<cfif SESSION.matureSession eq "on">
<input name="myCheckbox" type="checkbox" checked="checked" />
<cfelse>
<input name="myCheckbox" type="checkbox"/>
</cfif>
<input type="submit" value="Save" />
</cfform>
Session variable and params if they are not present on page load.
<cfparam name="form.myCheckbox" default="off">
<cfparam name="SESSION.maturesession" default="off">
<cfset SESSION.maturesession = form.myCheckbox>
If i'm going about this completely the wrong way let me know. Thanks.

<cfparam name="form.myCheckbox"
default="off">
<cfparam name="SESSION.maturesession"
default="off">
<cfset SESSION.maturesession =
form.myCheckbox>
I think that will result in overwriting the saved value if you return to the page from somewhere else. Instead, try updating the session value only when the form was submitted. Also, since you are using a cfform you could shortcut things by using yes/no instead of on/off.
Update I forgot the cfparam for the session variable. But if you truly want to carry it throughout the session, you could also initialize it onSessionStart instead.
<cfparam name="SESSION.maturesession" default="no">
<cfif structKeyExists(FORM, "submit")>
<cfparam name="form.myCheckbox" default="no">
<cfset SESSION.maturesession = form.myCheckbox>
</cfif>
<cfform name="test" method="post" ....>
<cfinput name="myCheckbox" type="checkbox" value="yes" checked="#session.matureSession#" />
<input type="submit" name="submit" value="Save" />
</cfform>

Do you actually have sessions turned on?
You have to explicitly turn on sessions for your app using the CFAPPLICATION tag if you're using Application.cfm, or, if you're using Application.cfc, by setting this.sessionManagement = true.
Application.cfm:
<cfapplication
name = "application name"
applicationTimeout = #CreateTimeSpan(0,2,0,0)#
sessionManagement = "yes"
sessionTimeout = #CreateTimeSpan(0,0,20,0)#>
Application.cfc:
<cfcomponent output="false">
<!--- Application name, should be unique --->
<cfset this.name = "ApplicationName">
<!--- How long application vars persist --->
<cfset this.applicationTimeout = createTimeSpan(0,2,0,0)>
<!--- Should we even use sessions? --->
<cfset this.sessionManagement = true>
<!--- How long do session vars persist? --->
<cfset this.sessionTimeout = createTimeSpan(0,0,20,0)>
</cfcomponent>
OK, then if sessions ARE turned on, when you submit the form, what does the code look like that you're posting the form to?

Related

Passing <cfselect> hard coded values into a session scope

I have a cfform with multiple fields and I'm using an onpage post method to post information gathered from the user's entries into a session to pass onto each page of the registration process.
What I cannot figure out for the life of me and this is probably something simple is that if I have hard coded options for a how can I pass what is selected into the session? I can get a session.house.main.form.saletype is undefined error when trying to display the value selected on the next page. All my other form fields show up fine.
I removed all the other form fields to make it easier to check my code:
<cfif not structKeyExists(session.house, "main")>
<cfset session.house.main= {saletype="",
name=""}>
</cfif>
<cfparam name="form.saletype" default="#session.house.main.saletype#">
<cfparam name="form.name" default="#session.house.main.name#">
<cfif structKeyExists(form, "submit")>
<cfset session.house.main = {saletype=form.saletype,
name=form.name}>
<cflocation url="page2.cfm" addtoken="false" />
</cfif>
<cfform method="post">
<cfselect name="saletype" size="1">
<option value="Lease" selected>Lease</option>
<option value="Rent Now">Rent Now</option>
</cfselect><br />
<cfinput type="text" name="name" id="name" value="#form.name#" required="yes" message="Please enter your name"><br />
<cfinput type="submit" name="submit" id="submit" value="Save"><br />
</cfform>
Edit: Fixed cfselect name. How would I set the form.saletype into the cfselect with two hardcoded options?

Setting a form variable inside the form (coldfusion)

I am trying to manually set a variable INSIDE a form, because it contains html and placing it in the value attribute of a tag would cause errors in the display. Currently, I check to see if that attribute contained html, and if so, the field is empty.
I'd like to be able to set the variable as the old value if it contained html in previous entries of the form, so that the user wouldn't have to enter that field every time they loaded that ORM object to edit.
Here's a snippet:
<cfif ("#dataobject.getField()#" NEQ "" AND Left(dataobject.getField(), 1) EQ "<")>
<cfscript>
temp = dataobject.getField();
temp2=temp;
temp2 = Insert("---", temp2, 0);
temp2 = Insert("<!", temp2, 0);
temp2 = Insert("--->", temp2, Len(temp2));
dataobject.setField(temp2);
</cfscript>
<label for="name">
Field:
</label>
<input type="text" name="Field" value="">
<button id="savefield" name="savefield">Save</button>
<cfif form.Field EQ ""><cfset form.Field = temp></cfif>
<cfscript>
dataobject.setField(temp);
</cfscript>
<cfelse>
<label for="name">
Field:
</label>
<input type="text" name="Field" <cfif ("#dataobject.getField()#" NEQ "")>value="#dataobject.getField()#"</cfif>>
<button id="savefield" name="savefield">Save</button>
</cfif>
The code I was trying to use:
<cfif form.Field EQ ""><cfset form.Field = temp></cfif>
Coldfusion throws an error saying that the FORM variable is undefined (which doesn't surprise me). The "savefield" button calls javascript that opens a window allowing the user to set the value, then closes. Should I put my code there instead?
-The inserts which turn the string into a comment was an early attempt at a workaround that didn't work :/
Ok hopefully the following pointers will help you going:
Verify that the field exists in the form via; structKeyExists(form, "field") or use cfparam to initialize a default value
Escape the value with HTMLEditFormat(dataObject.getField()) to escape any HTML code which breaks the html
So e.g.;
<cfparam name="form.field" default="" />
<label for="field">
Field:
</label>
<input type="text" id="field" name="field" value="#htmlEditFormat(form.field)#" />
<button id="savefield" name="savefield">Save</button>
Gl !
if you want to force a value into the form (or any) scope you'll want to use cfparam before you use it.
<cfparam name = "form.field" default = "">
<cfif form.Field EQ "">
<cfset form.Field = temp>
</cfif>
Essentially this is the same thing as
<cfif !structKeyExists(form,"field")>
<cfset form.field = "">
</cfif>
Don't forget that preservedata is your friend.
You don't have to worry about the value="" attribute if you populate the form field ahead of time.
<cfquery name="qry">
SELECT Field1,Field2
FROM table
WHERE ID=<cfqueryparam cfsqltype="cf_sql_integer" value="#url.ID#">
</cfquery>
<cfloop list="#qry.Columnlist#" index="FieldName">
<cfset form[FieldName] = HTMLEditFormat(qry[FieldName][1])>
</cfloop>
<cfform preservedata="yes">
<label for="Field1">Field One:</label>
<cfinput name="Field1">
<label for="Field2">Field Two:</label>
<cfinput name="Field2">
</cfform>

Can't get my reCaptcha to work on my ColdFusion form

I signed up for reCaptcha, got my private/public keys, made my recaptcha.cfm and put the code in my form. The form renders perfectly when you go to the URL but it submits even when the person doesn't put anything in the captcha. This is the code for my recaptcha.cfm and I have the relevant code for the form page commented out in recaptcha.cfm under "Sample." Any help would be greatly appreciated. Thank you.
<cfsetting enablecfoutputonly="true">
<!---
Use the reCAPTCHA API to verify human input.
reCAPTCHA improves the process of digitizing books by sending words that
cannot be read by computers to the Web in the form of CAPTCHAs for
humans to decipher. More specifically, each word that cannot be read
correctly by OCR is placed on an image and used as a CAPTCHA. This is
possible because most OCR programs alert you when a word cannot be read
correctly.
You will need a key pair from http://recaptcha.net/api/getkey to use this tag.
Sample
--------------------------------
<html>
<body>
<cfform>
<cf_recaptcha
privateKey="6LepjdQSAAAAAMspsO04gZUXltxddkiI0ZgSF02h"
publicKey="6LepjdQSAAAAADoLvfvgkwacBAI_GbL-nTy2zvS6">
<cfinput type="submit" name="submit">
</cfform>
<cfif isDefined("form.submit")>
<cfoutput>recaptcha says #form.recaptcha#</cfoutput>
</cfif>
</body>
</html>
--->
<cfscript>
CHALLENGE_URL = "http://api.recaptcha.net";
SSL_CHALLENGE_URL = "https://api-secure.recaptcha.net";
VERIFY_URL = "http://api-verify.recaptcha.net/verify";
</cfscript>
<cfif not structKeyExists(attributes, "publicKey")>
<cfthrow type="RECAPTCHA_ATTRIBUTE"
message="recaptcha: required attribute 'publicKey' is missing">
</cfif>
<cfif not structKeyExists(attributes, "privateKey")>
<cfthrow type="RECAPTCHA_ATTRIBUTE"
message="recaptcha: required attribute 'privateKey' is missing">
</cfif>
<cftry>
<cfparam name="attributes.action" default="render">
<cfif not listContains("render,check", attributes.action)>
<cfset sInvalidAttr="action not render|check">
<cfthrow>
</cfif>
<cfset sInvalidAttr="ssl not true|false">
<cfparam name="attributes.ssl" type="boolean" default="false">
<cfparam name="attributes.theme" type="regex" pattern="(red|white|blackglass)" default="red">
<cfif not listContains("red,white,blackglass", attributes.theme)>
<cfset sInvalidAttr="theme not red|white|blackglass">
<cfthrow>
</cfif>
<cfset sInvalidAttr="tabIndex not numeric">
<cfparam name="attributes.tabIndex" type="numeric" default="0">
<cfcatch type="any">
<cfthrow type="RECAPTCHA_ATTRIBUTE"
message="recaptcha: attribute #sInvalidAttr#">
</cfcatch>
</cftry>
<cfif isDefined("form.recaptcha_challenge_field") and isDefined("form.recaptcha_response_field")>
<cftry>
<cfhttp url="#VERIFY_URL#" method="post" timeout="5" throwonerror="true">
<cfhttpparam type="formfield" name="privatekey" value="#attributes.privateKey#">
<cfhttpparam type="formfield" name="remoteip" value="#cgi.REMOTE_ADDR#">
<cfhttpparam type="formfield" name="challenge" value="#form.recaptcha_challenge_field#">
<cfhttpparam type="formfield" name="response" value="#form.recaptcha_response_field#">
</cfhttp>
<cfcatch>
<cfthrow type="RECAPTCHA_NO_SERVICE"
message="recaptcha: unable to contact recaptcha verification service on url '#VERIFY_URL#'">
</cfcatch>
</cftry>
<cfset aResponse = listToArray(cfhttp.fileContent, chr(10))>
<cfset form.recaptcha = aResponse[1]>
<cfset structDelete(form, "recaptcha_challenge_field")>
<cfset structDelete(form, "recaptcha_response_field")>
<cfif aResponse[1] eq "false" and aResponse[2] neq "incorrect-captcha-sol">
<cfthrow type="RECAPTCHA_VERIFICATION_FAILURE"
message="recaptcha: the verification service responded with error '#aResponse[2]#'. See http://recaptcha.net/apidocs/captcha/ for error meanings.">
</cfif>
<cfelse>
<cfset form.recaptcha = false>
</cfif>
<cfif attributes.action eq "render">
<cfif attributes.ssl>
<cfset challengeURL = SSL_CHALLENGE_URL>
<cfelse>
<cfset challengeURL = CHALLENGE_URL>
</cfif>
<cfoutput>
<script type="text/javascript">
<!--
var RecaptchaOptions = {
theme : '#attributes.theme#',
tabindex : #attributes.tabIndex#
};
//-->
</script>
<script type="text/javascript"
src="#challengeURL#/challenge?k=#attributes.publicKey#">
</script>
<noscript>
<iframe src="#challengeURL#/noscript?k=#attributes.publicKey#"
height="300" width="500" frameborder="0"></iframe><br>
<textarea name="recaptcha_challenge_field" rows="3" cols="40">
</textarea>
<input type="hidden" name="recaptcha_response_field"
value="manual_challenge">
</noscript>
</cfoutput>
</cfif>
<cfsetting enablecfoutputonly="false">
That custom tag is badly out of date. You need to update the URLs because Google changed them. Change them to this:
CHALLENGE_URL = "http://www.google.com/recaptcha/api";
SSL_CHALLENGE_URL = "https://www.google.com/recaptcha/api";
VERIFY_URL = "http://www.google.com/recaptcha/api/verify";
I have posted an updated version of this custom tag as a Gist here: https://gist.github.com/2210356

Unwanted Facebook button at first time use of my FB application in coldfusion

I am playing around with facebook application, making them in iframe using coldfusion.
Following is the url of my app http://apps.facebook.com/firstones/
Instead of going directly going to the permissions page, it goes to the page shown below in picture.
And after clicking on that big 'Facebook' button it goes to ask for applications permission. And once permissions are granted it takes to my website, where I have hosted the application, instead of opening it in Facebook only.
Following is the code of my canvas url [http://www.dkyadav.com/firstOnes/auth/]
index.cfm
<cfparam name="client_id" default="1234"> <!---same as app_id --->
<cfparam name="redirect_uri" default="http://www.dkyadav.com/firstOnes/auth/">
<cfparam name="redirect_uri_final" default="http://www.dkyadav.com/firstOnes/">
<cfparam name="scope" default="user_education_history,user_hometown,friends_education_history ">
<cfparam name="client_secret" default="56789"> <!---- App_secret key ---->
<cfif not isdefined('url.code')>
<Cflocation url="https://www.facebook.com/dialog/oauth?client_id=#client_id#&redirect_uri=#redirect_uri#&scope=#scope#" >
<Cfelse>
<Cfif isdefined('url.error')>
<Cfoutput>
#url.error#<br />
Access denied.
</Cfoutput>
<cfelse>
<cfoutput>#url.code#<br />
<cfhttp url="https://graph.facebook.com/oauth/access_token" result="token">
<cfhttpparam name="client_id" value="#client_id#" encoded="no" type="url">
<cfhttpparam name="redirect_uri" value="#redirect_uri#" encoded="no" type="url">
<cfhttpparam name="client_secret" value="#client_secret#" encoded="no" type="url">
<cfhttpparam name="code" value="#url.code#" encoded="no" type="url">
</cfhttp>
<cflocation url="#redirect_uri_final#?#token.filecontent#" addtoken="no">
</cfoutput>
</Cfif>
</cfif>
And in http://www.dkyadav.com/firstOnes/index.cfm I look for access_token and have rest of my application.
I does the above said things only for the first time it run. Once its permission get approved, it works normally as expected.
You can try out this app running yourself http://apps.facebook.com/firstones/
Please help and let me know what I am actually missing. Thanks!!
I think the problem you have is that your initial display page on Facebook is actually bursting out of the iframe.
You can see the Javascript doing that on http://www.dkyadav.com/firstOnes/index.cfm in the fbLogin() function:
top.location.href = "https://graph.facebook.com/oauth/authorize?...
top refers to the window at the top of your window hierarchy which in your case will mean the actual Facebook home page with the iframe in it.
Hope that helps!
I think I dont need access_token, I just need oauth_token that I get by Decoding the result I got from submitting my client_id to 'https://www.facebook.com/dialog/oauth....'
Below is the code that I am using:
<cfif isdefined('signed_request')>
<cfoutput>
<cfset b64 = signed_request>
<!--- Split the param by the . --->
<cfset raw_str = ListGetAt(b64, 2, ".")>
<cfset res = Len(raw_str) % 4>
<cfif res eq 2>
<cfset raw_str &= "==">
<cfelseif res eq 3>
<cfset raw_str &= "=">
</cfif>
<!--- Base 64 Decode --->
<cfset result = ToString(BinaryDecode(raw_str, "Base64"))>
<!--- String to JSON --->
<cfset json = DeserializeJSON(result)>
<cfif StructKeyExists(json,'oauth_token')>
<Cfset at = json.oauth_token>
<cfhttp url="https://graph.facebook.com/me/friends?access_token=#at#" result="newsFeed" />
<cfif IsJSON(newsFeed.filecontent)>
<cfset cfData=DeserializeJSON(newsFeed.filecontent)>
<cfdump var = #cfData#>
<cfelse>
filecontent not in json format
</cfif>
<cfelse>
<script>
top.location.href='https://www.facebook.com/dialog/oauth?client_id=12345XXX&redirect_uri=http://apps.facebook.com/test_app/&scope=read_stream,email'
</script>
</cfif>
</cfoutput>
</cfif>

Value for my session variable?

Here my code to create a session variable:
<cflock timeout="999" scope="Session" type="Exclusive">
<cfset Session.IDUsers = "">
</cflock>
I need to put a value in = "" but I want the value to change to be the users ID depending on which user is logged in. So I can't just put any number etc. in there. What do I have to do?
Basically, you're going to do this when you log your user in. A sign-in routine might look like the following:
<cfquery datasource="cfgossip" name="signin">
SELECT
ID_USERS
FROM
USERS
WHERE
UN = <cfqueryparam cfsqltype="cf_sql_varchar" value="#form.un#" />
AND PW = <cfqueryparam cfsqltype="cf_sql_varchar" value="#form.pw#" />
</cfquery>
<cfif signin.recordCount>
<cfset session.idUsers = signin.id_users />
</cfif>
Until they've logged in, you can't know what the value you need is. However, once you've determined that they are who they say they are and you're going to let them in, you can then set the session variable.
Ok I think you need a basic breakdown of how this should work.
Step 1: User goes to a section of your website/app that needs login. You check if the session.userid is set to a valid value. If not goto login screen.
Step 2: Present user with a login form.
<form action="checklogin.cfm">
<input type="text" name="username" value="">
<input type="password" name="pass" value="">
<input type="submit" value="login">
</form>
Step 3: On clicking login the form is submitted to an action page which checks if the credentials supplied match a valid user.
<cfquery datasource = "myDB" name = "getUsers">
SELECT userID
FROM USERS
WHERE username = <cfqueryparam cfsqltype = "cf_sql_varchar" value = "#form.username#" />
AND password = <cfqueryparam cfsqltype = "cf_sql_varchar" value = "#form.pass#" />
</cfquery>
Step 4: If valid user goto the logged in area else return to login screen
<cfif getUsers.recordCount GT 0>
<cfset session.IDUsers = getUsers.userID />
<cflocation url="home page for logged in users">
<cfelse>
<cflocation url="return to login form and display invalid login message">
</cfif>
This is a very basic login form but it should get you started.