"Issue viewing email? View email online?" unique link in Codeigniter email - php

I'm not sure where to begin with this task, so I'm looking for an answer on just the idea of how to go about doing this.
When a new user creates an account on my Codeigniter site I send him/her an email about signing up (very typical). Here is how I'm sending the email...
...
$subject = 'Welcome to __________, ' . $firstName . '!';
$emailData = array(
'name' => $name,
'blah' => $blah,
'blah' => $blah,
// etc.
);
$html_email = $this->load->view('emails/signup_html_view', $emailData, true);
$text_email = $this->load->view('emails/signup_text_view', $emailData, true);
$this->email->from('team#_________.com', '________ Team');
$this->email->to($to);
$this->email->subject($subject);
$this->email->message($html_email);
$this->email->set_alt_message($text_email);
$this->email->send();
...
As you can see, I'm passing data to those views to send the email. In the email view, at the top, I have a link that says "Problem viewing email? Click here to view it online.". That is common practice for emails on newsletters, signups emails, etc. so that the user can view the email online if it renders weird or something goes wrong.
Where I'm getting lost is how do I generate that unique "...view it online." link so that when the user clicks it, they see an online version of the email and the online version still has all the data still passed to it? Do I need to create a separate controller or what is the best way to handle that? How do I generate that unique link?

#zach,
yes, what you do is:
1) create a separate controller that can display this email, just like you were making a page
2) I'm assuming the user is already created in the db, but is not yet activated or taken steps to be able to login. So, backing up a bit, when you make your user record, also create a random hashtag & store that.
Now, in the email link, set it to www.mysite.com/welcome/hashtag
This way you are allowing them to get a unique record without using an id that they could just use to go look at everyone else
This welcome page, of course, doesn't require them to be logged in. Probably you give them a submit (maybe after they fill out some more info) that will then activate their account
Hope that was close enough to what you were asking to get you through

Related

A secure enough way of identifying and activating a user in MySQL PHP with a URL

Is checking against my table with the user's email and dedicated hash enough to verify and activate an account if a match is found against those two values?
A user is asked to register themselves with user data and their email id. They are then sent a URL to their email which they are asked to click on to confirm and activate their account.
This is my current setup:
<?php //The user-account-creation processing page
$email_id = taken from user input;
$randomnessWhateverItsCalled = "lots-of-randomness-here";
UPDATE advert SET advert_hash = SHA1(CONCAT($email_id, $randomnessWhateverItsCalled))
//For simplicity's sake I omitted the PDO stuff
INSERT INTO table_name (..., user_email, hash, account_activated, ...) VALUES (..., usersEmail, advert_hash, NO, ...)
/**
Send an email with some php code with the URL that would look like this
URL to click on attached to email body:
*/
$attachStringToEmailBody = "http://www.domainname.com/activate-user?email_id=" . $usersEmail . "&hash=" . $randomnessWhateverItsCalled;
enter code here
//Send email from this process page with a little email php code
//Redirect user to a page informing the user to activate the account by visiting their email and clicking on the url
?>
Then in the activate-user.php page I have the following:
<?ph
$user_email = $_GET['email_id'];
$hash = $_GET['hash'];
/**
search database and return a row if there is a match containing both the $user_email and the $hash
if(match){
Update database and set the `account_activated` column to `YES`
}
else{
//Tell if there was no match then activation failed
//Let the user know that we do not recognise the link they used to try and activate their account.
}
*/
?>
It seems secure enough, as long as you made the "randomness" part hard to guess. You can put there the email, username, password, etc. and mix them up with another key - all encrypted - that's what I usually do.
But I would advise you to use 0/1 for active/inactive - why using strings, when you can do the same with smallint (1) - and save some space, thus making the database a bit lighter ?

Job Notes in a custom php web app not showing

Hoping some of you out there are great with php!
Basically the guy who made this is MIA so I can't ask him what I need to do to fix the problem we are having.
Background:
We are a locksmith company that uses a custom web app to inform our locksmiths on the road when they have a new job. This web app also does a few extra things like providing gps location, time taken at the job and the ability to have save signature from the client upon work completion.
Problem:
The app works by picking up an email sent from our account management application called E3, the email (example: http://cl.ly/image/2E433O330T0N) is read by this web app, parsed into both an email and a web page and sent to the locksmith to view his new job. When the locksmith arrives at the web page on his phone (example: http://cl.ly/image/0P1I0R0h0O3K), he can see the job details including the Name, address and contact details for the client. The problem is though, because Job Notes isn't assigned a heading in the original email the code has to work out where Job Notes is located, this is the part that has the problem as the web app is no longer showing the data in Job Notes. Job Notes is important because it tells the locksmith what he needs to fix. This worked previously but has now just stopped working and we aren't sure why.
How the data is transferred to the web app is very interesting, instead of having a database to store data to, it is put in the address bar and then the webpage interprets the code and formats it into the page.
For example, this is how the current link looks (data taken out, replaced with xxxxxxx):
http://www.xxxxxxx.com/apps/xxxxxx/on-my-way?client=xxxxxx&company=xxxxxx&mobile=xxxxxxx&phone=xxxxxxx&contact=xxxxxxxx&addressData=Array&addressIndex=3&streetAddress=xxxxxxxxx&addressLocality=xxxxxxxx&postcode=xxxxxxx&city=xxxxxxx&clientEmail=&jobDate=11/22/2012&jobTime=1:30:00%20PM&jobID=xxxxxx&jobAMPM=PM&adminEmail=xxxxxxx&noreplyEmail=xxxxxxxxxx&companyPhone=xxxxxxxx&staffEmail=xxxxxxxx&staffName=xxxxxxx&staffPhone=xxxxxxxx
Previously, when working, this link had a jobNotes field added:
http://www.xxxxxxxx.com/apps/xxxxxxxx/on-my-way?client=xxxxxxxx&company=xxxxxxxx&mobile=xxxxxxxx&phone=&contact=xxxxxxxx&addressData=Array&addressIndex=4&streetAddress=xxxxxxxx&addressLocality=xxxxxxxx&postcode=xxxxxxxx&city=xxxxxxxx&clientEmail=xxxxxxxx&jobNotes=Quote%20on%20installing%20new%20keying%20system%0A%0AAlso%20would%20like%20a%20Quote%20on%20Install%20CCTV%0A%0ASub%20Total%3A%202%2C236.36%0AGST%3A%20223.64%0ATotal%3A%202%2C460.00%0A%0AMISC&*jobDate=11/19/2012*&jobTime=2:00:00%20PM&jobID=xxxxxxxx&jobAMPM=PM&adminEmail=xxxxxxxx&noreplyEmail=xxxxxxxx&companyPhone=xxxxxxxx&staffEmail=xxxxxxxx&staffName=xxxxxxxx&staffPhone=xxxxxxxx
The code:
This is an extract from e3-parser.php, the main file that translates the data from the e3 email to the web app.
// Job notes
if ($this->clientEmail) {
// REMOVED NOW THAT EMAIL IS BEING PUT ON THIRD LINE OF ADDRESS
// // If customer email present grab everything after it save it as job notes
// preg_match("/$this->clientEmail[^-]+/",$e3Output,$matches);
// $result = implode("",$matches);
// $notes = trim(str_replace($this->clientEmail,'',$result));
// $this->jobNotes = rawurlencode($notes);
// } else {
// Fall back to grabbing everything after the time
preg_match("/AM[^-]+/",$e3Output,$matchesAM);
preg_match("/PM[^-]+/",$e3Output,$matchesPM);
$resultAM = implode("",$matchesAM);
$resultPM = implode("",$matchesPM);
$notes = trim(str_replace('AM','',$resultAM) . str_replace('PM','',$resultPM));
$this->jobNotes = rawurlencode($notes);
}
Question here is, does it successfully grab the data listed after the Required Time field? (example email that it's reading from: http://cl.ly/image/2E433O330T0N)
Here is the code that places the parsed data into the web page:
// Create job link
$url = $e3->create_job_url('http://www.prvgroup.com.au/apps/jobbook/on-my-way?');
$linkName = "View job details";
$href = '<a class="btn btn-small" href="' . $url . '&staffEmail=' . $staff- >staffEmail . '&staffName=' . $staff->staffName . '&staffPhone=' . $staff->staffPhone . '">' . $linkName . '</a>';
This is sent to the locksmith via email informing him of his new job on the clickable link "View job details". The link is impregnated with the data needed. However from the looks of it the data for jobNotes isn't there. My backups of this code display the exact same thing here when the code was displaying jobNotes so I'm not exactly sure how it is putting that field in.
If you got this far, well done! I hope I was clear enough with what the issue is but if you need anymore clarification, just ask!
Cheers,
Marc
After looking through your code you are only running the preg_match if there is a clientEmail. From the sample emails above it does not look like you are ever executing this code because there is no client email or it is not found using the preg_match. The specific location to look into is on line 113 of the e3-parser.php file. You will see this:
if($this->clientEmail)
{
//matching code here.
}
on line 109 and 110 you are looking for an email address and either not finding one or it is looking in the wrong location. At any rate, you should execute this code regardless of whether there is an email address or not. The notes must be set for later use, right now nothing is being set. Removing this if statement should resolve your issue.

how to delete mysql table row from mail inbox

I want to delete mysql table row from mail inbox , Is it possible !, If yes how can i delete the table row in my server database from any mail inbox account, please tell me the solution
Table Structure:
id usrname password status usercat
1 xxxxxxx xxxxxxx new 1
2 uuuuuuu uuuuuuu new 5
$del_qry= mysql_query("DELETE FROM table_name WHERE some_column=some_value")
In my site after Registration, the registered person get alert mail and also site admin get registered user detail's mail. So if the admin want to delete the second user(username - uuuuuu) from his mail account.
How can i do this, Please tell me i am new here...
The email you send to the admin will have to contain a link like this:
http://www.example.org/admin/remove_account.php?id=123
Where 123 is the user that was registered and remove_account.php is the script that will be loaded when the link is clicked.
Within the script you would have something like this:
mysql_query("DELETE FROM table_name WHERE id=" . mysql_real_escape_string($_GET['id']));
CAUTION
A few words of caution. The above link should be protected by one of the following:
User & password protection (either using Apache or PHP)
Signature protection (example below)
The signature protection prevents tampering / forging link parameters by adding a signature. Works like this:
$secret = "some reasonably long string of random data";
$id = "123"; // like above, the user id
$sig = hash_hmac('sha1', $id, $secret);
$link = 'http://www.example.org/admin/remove_account.php?' . http_build_query(array(
'id' => $id,
'sig' => $sig,
));
To verify the signature:
$secret = "some reasonably long string of random data";
if (isset($_GET['id'], $_GET['sig'])) {
$calc_sig = hash_hmac('sha1', $_GET['id'], $secret);
if ($calc_sig === $_GET['sig']) {
// your delete query here
}
}
Please note that, although the link protects against someone trying to access your administrative script, if it falls in the wrong hands you're still pretty much screwed. Don't underestimate security :)
I think you must add a link of a page of your site in email of delete with respect of user list. and when user click on link it will redirect to particular page where it will get that user id from url of link and then you can perform delete action. It is necessary to redirect to site page from mail because in mail you can not direct connect with database.
thanks

Facebook regsitration plugin - async validation (email)

We have an existing membership site setup in php/MySQL, and are looking to integrate Facebook registration and login. The login and registration forms have been imported, and are hooked up to php/MySQL code which creates new users in the database. However, in order that we can prevent a single user having multiple logons (eg. one site logon, one Facebook logon), we need to check the email address of the user before adding a new line to the members database table.
We can do this through php/MySQL code, but that gets needlessly complex when you have to cater for all the permutation of cross-site/FB membership, plus we do not want the user to connect to the FB registration app without becoming a site member. A better solution would be to prevent the user from registering under an email address which is already present in the database (rather directing them to obtain a new password, and update connect their facebook profile to the existing profile). We have been looking for weeks for a solution, and have consulted the Facebook Developers Async Validation (http://developers.facebook.com/docs/plugins/registration/advanced/), as well as the stackexchange forum, but have not been able to implement a solution which validates the email address against the database, and prevents/allows registration accordingly.
The code we have so far is
<fb:registration redirect-uri="http://www.mysite.com/register.php"
fields='[{"name":"name"},{"name":"email"}
{"name":"username","description":"Username","type":"text"}]'
onvalidate="validate_async"></fb:registration>
<script src="https://code.jquery.com/jquery-1.4.4.min.js"></script>
<script>
function validate_async(form, cb) {
$.getJSON('http://www.mysite.com/register_check.php/' + form.email + '?callback=?',
function(response) {
if (response.error) {
// Username isn't taken, let the form submit
cb();
}
cb({username: 'That email is taken'});
});
}
</script>
register_check.php
//connect to the database
include 'mysql_connect.php'
$email = $_GET('email');
$data = array();
$sqlCommand = "SELECT * FROM members WHERE email='$email'";
$query = mysql_query($sqlCommand) or die (mysql_error());
$num_rows = mysql_num_rows($query);
if($num_rows>0){
$email_check = $row['email'];
$data['email'] = $email_check;
} else {
$data['error'] = "true";
}
echo json_encode($data);
Unfortunately, this process is not working at all. The registration form simply hangs endlessly, without validating nor passing the information to the database. We have done considerable research into how to properly code getJSON and the server-side php, but have come up against brick wall, so would very much appreciate any help or advice on this issue.
I hope this isn't too late, but after facing the same problem I found out the registration plugin doesn't send with the form object the preset details (name, email, gender, birthdate) -- only sends any custom fields. Quite dumb imo but could have an advantage or two.
Solution was to override the description of the email so as to trick it into thinking it's custom (which it would be) -- disadvantage being your regular checks will not be checked against (valid email et al) so you'll need to take care of those manually.
This may be late, but:
Change your JSON address to
http://www.mysite.com/register_check.php?email=' + form.email +
You were using facebook's check for existing user. Change:
cb({username: 'That email is taken'});
to:
cb({email: 'That email is taken'});
You want error message to appear next to email field.

Drupal Autoresponder with Token Module

I'm using Drupal autoresponder module - and I want to use tokens so I can include the username who has subscribed within the emails being sent...
Does anybody know how this can be achieved?
Thanks for any help.
Shane
Thanks for that - your answer was very close....
The autoresponder module UID is not related to the user UID so your code was bringing in a different username... So I changed it to find the user from the email address instead.
// load the full user object
$user = user_load(array('mail' => $u->mail));
// Replace user tokens in mail body
$mail->body = token_replace($mail->body, 'user', $user);
Yes indeed, I'll submit it as a patch to my other request, and hopefully it may help somebody else.
Many Thanks
Shane
EDIT after separate answer by OP: The following was based on the assumption that the $u->uid refers to the 'standard' Drupal user id, which is not correct! So one has to find the corresponding Drupal user by other means, if possible - see the OPs answer for details on this...
I have not tested it, but looking at the autoresponder source code, you should be able to add (user) token replacement in the autoresponder_mail() function by inserting the following code before the preparation of the plain text body (before line 392 in the 6.x-1.0-alpha1 release):
// load the full user object
$user = user_load($u->uid);
// Replace user tokens in mail body
$mail->body = token_replace($mail->body, 'user', $user);
Alternatively, you could do it one function call earlier in autoresponder_cron(), within the while ($message db_fetch_object($result_messages)) loop, before the if (autoresponder_mail($u, $message)) call (line 366), using $message instead of $mail:
// load the full user object
$user = user_load($u->uid);
// Replace user tokens in mail body
$message->body = token_replace($message->body, 'user', $user);
In case this works, you might want to submit it as a patch to the already existing feature request for this. (I guess you are the 'keyzo'/'shane' who already answered there ;)
If it works and you are going to create a patch, it would be 'standard' practice to add the hint on possible token replacement to the message definition form(s) in autoresponder_mail_edit_create_form().

Categories