Jump to content
kyle

Activate user account via email

Recommended Posts

If urls without trailing slash are not allowed in the template's settings then it will redirect to the url with slash swallowing the get parameters.

  • Like 1

Share this post


Link to post
Share on other sites

Correction: The GET parameters will be sent - I can see it for a short moment in the url, than they will be removed - for me it looks like a redirect. Maybe from a module. After that the page is visible.

?????


Maybe this could be the reason @ LostKobraKai. I will add the slash and try it once more.

Share this post


Link to post
Share on other sites

Unfortunately the slash at the end doesnt work. I can remember that there is a module which (I dont know the name) which is responsible for redirects if a url has changed. Could be this the reason?

Share this post


Link to post
Share on other sites

No I dont want to mix up - adding the slash is the most consistent method in this case.

Share this post


Link to post
Share on other sites

I just used this, just that i used Ryan's suggestion for the random string

$rand = new Password();
$hash = $rand->randomBase64String(100);

and there is a problem with the second check here:

 if(strcmp(wire("users")->get($activate_username)->user_activation, $activate_hash) == 0 || wire("users")->get($activate_username)->user_activation == 0)

If wire("users")->get($activate_username)->user_activation is a string starting with a letter it will be converted to integer 0 so the if statement is true, if the string starts with a number that number will be converted to an integer.

To solve this use === in that comparison, or put 0 in quotes "0", or omit it altogether (if it's already 0 no need to set it again to 0).

 

This is how i handle the activation:

$username = $sanitizer->pageName($_GET["user"]);
$hash = $sanitizer->text($_GET['hash']);
// get the user
$u = $pages->get("template=user, name={$username}");
// user exists
if($u->id)
{
  // check if user is activated
  if($u->user_activation === "active")
  {
      echo "Account is already active.";
  }
  // not activated compare hash from $_GET with hash from db
  // http://php.net/manual/en/function.strcmp.php
  else if(strcmp($u->user_activation, $hash) == 0)
  {
      // hashes are the same activate user
      echo "Your account has been activated!<br>";
      $u->of(false);
      $u->user_activation = "active";
      $u->save();
  }
  // hashes don't match
  else
  {
      echo "There was an error activating your account!  Please contact us!<br><br>";
  }
}

 

  • Like 2

Share this post


Link to post
Share on other sites

I've a function to clean out non URL conform chars.....since i had problems with the hashes in URL Segments this works for me:

/*
 * create a valid url save one time token
 *
 */
function RandomToken($lenght = 32) {
	$p = new Password();
	$h = $p->randomBase64String($lenght);
	$given = array("/", ".");
	$replace = array("_", "-");

	$hash = str_replace($given, $replace, $h);

	return $hash;
}

 

  • Like 3

Share this post


Link to post
Share on other sites

Could you set user active/not active by user role instead of having a 0 in a custom field? Maybe initially leave role empty - addRole('') - and then after validation add a role like 'subscriber' or 'member'? Then you won't need the if($user->user_activation != 0) check.

Edit: I tried this and it seems to work fine. Or am I missing something?

Spoiler

<?php
function usernamer($str = '') {
$str = strip_tags($str); 
$str = preg_replace('/[\r\n\t ]+/', ' ', $str);
$str = preg_replace('/[\"\*\/\:\<\>\?\'\|]+/', ' ', $str);
$str = strtolower($str);
$str = html_entity_decode( $str, ENT_QUOTES, "utf-8" );
$str = htmlentities($str, ENT_QUOTES, "utf-8");
$str = preg_replace("/(&)([a-z])([a-z]+;)/i", '$2', $str);
$str = str_replace(' ', '', $str);
$str = str_replace('-', '', $str);
$str = str_replace('--', '', $str);
$str = rawurlencode($str);
$str = str_replace('%', '', $str);
return $str;
}

function passworder( $length ) {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return substr(str_shuffle($chars),0,$length);
}

$pass = passworder(8);
$activation = md5($pass."randomstringhereforextraprotection");

if($input->post->submit) {
    $u = new User();
    $u->fullname = $sanitizer->text($input->post->fullname);
    $u->name = usernamer($u->fullname);
    $u->email = $sanitizer->text($input->post->email);
    $u->pass = $pass;
    $u->activation = $activation;
    $u->registrationDate = time();
    $u->addRole('');
    $u->save();
	
	$activationlink = $config->httpHost .'/signup/?key='. $activation;
	
	echo '<style>form { display: none }</style>';
	echo '<p>Thank you for your interest. Check your email inbox for the account activation link.</p>';
	
	$welcome = '<p>Hello '. $u->fullname .',<br>Thank you for submitting your data. Your username is ' . $u->name . ' and your pass is '. $pass .' and your activation link: '. $activationlink .'</p>';
	$mail->send($u->email, 'Company <admin@company.com>', 'Your Account Activation Link', $welcome);
}

/* get activation code from URL */
if (isset($_GET['key'])) {

$activation =  $sanitizer->text($_GET['key']);
$newuser = $users->get('activation='. $activation);

	if ($newuser->activation == $_GET['key']) {
	$newuser->of(false);
	$newuser->addRole('subscriber'); /* activate by updating role */
	$newuser->activation = '0'; /* remove validation key */
	$newuser->save(); 
	$newuser->of(true);
	echo 'You now have an active account';
    }
    else {
	echo 'Your account is already active or you have an invalid key<br><br>';
	}
} else { ?>
<form method=post>

<div class=field>
	<label for=fullname>Full name</label>
	<input id=fullname type=text name=fullname placeholder=fullname required>
</div>

<div class=field>
	<label for=email>Email</label>
	<input id=email type=email name=email placeholder=email required>
</div>
	
	<input type=submit name=submit>
</form>
<?php } ?>

 

I generate password and username with custom functions; isn't there a built-in PW function to generate a password? I saw 'new Password()' in Ryan's post, but couldn't get that to work. And I guess the PW way to do usernamer() is $sanitizer->pageName()?

You have to add custom fields 'fullname' and 'activation' to the user template for this to work.

Anything wrong with this approach? Any dumb mistakes?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...