Account creation via webpage

This section contains user-submitted tutorials.
Post Reply
User avatar
kimboslice
Normal user
Normal user
Posts: 32
Joined: 2022-02-05 16:38

Account creation via webpage

Post by kimboslice » 2022-06-29 03:07

Threw this together, hopefully it proves useful to others

A few things need to be done, its not as clean as I'd like but hey it works

Create a rule, select 'subject' contains 'NEW ACCOUNT CREATED' & set 'Action' to 'Run Function', Script Function 'ACCOUNT'

You will need to change these values in signup.php, this relies on you having a mysql/mariadb install in order to check if the account already exists

domain1.tld/domain2.tld -> your domains
C:\path\to\newacc.vbs ->wherever youre placing the newacc.vbs file
dbaddress/username/password -> to your mysql/mariadb credentials
email@address.com -> change to your postmaster/webmaster email address

signup.php

Code: Select all

<!DOCTYPE HTML>
<html>  
<head>
<style>
p {
  color: red;
  font-family: verdana;
  font-size: 80%;
}
form {
  border: 8px solid black;
  margin: auto;
  width: 200px;
  top: 50px;
  left: 50%;
}
.submit {
  position: relative;
  margin-left: 35%;
}
.domain {
  position: center;
  margin-left: 22%;
}
.email {
  position: center;
  margin-left: 5%;
}
div {text-align: center;}
p {text-align: center;}
</style>
</head>
<title>E-mail Signup form</title>
<script>
    if ( window.history.replaceState ) {
        window.history.replaceState( null, null, window.location.href );
    }
</script>
<body  style="background-color:#432938;" >
<form name="form" class="form" method="POST" action="./form.php">
  <p><label for="domain">Choose domain:</label></p>
  <select required="required" name="domain" class="domain" id="domain" required>
    <option value="domain1.tld">domain1.tld</option>
    <option value="domain2.tld">domain2.tld</option>
  </select>
<p class="Username">Username:</p> 
<input name="email" required="required" class="email" type="text" id="email" title="email" pattern="^[a-zA-Z0-9]+$" /><br>
<p>Password:</p>
<input name="password" minlength="8" class="email" required="required" type="password" id="password" />
<p>Confirm Password:</p>
<input name="password_confirm" class="email" required="required" type="password" id="password_confirm" oninput="check(this)" />
<script language='javascript' type='text/javascript'>
    function check(input) {
        if (input.value != document.getElementById('password').value) {
            input.setCustomValidity('Password Must be Matching.');
        } else {
            input.setCustomValidity('');
        }
    }
</script>
<br /><br />
<input type="submit" class="submit" name="registerBtn">
</form>

</body>
</html>
<?php
if (isset($_POST['registerBtn'])){ 
    $acc = $_POST['email'];
    $pass = $_POST['password'];
	$domain = $_POST['domain'];  

if (empty($acc)) {
    echo '<div>No account entered</div>';
	exit;
}
if (empty($pass)) {
    echo '<div>Password is empty</div>';
	exit;
}
$path_to_file = 'C:\path\to\newacc.vbs';
$path_to_newfile = 'C:\Windows\temp\run.vbs';
$file_contents = file_get_contents($path_to_file);
$file_contents = str_replace('aco', $acc, $file_contents);
$file_contents = str_replace("newpass", $pass, $file_contents);
$file_contents = str_replace("domain.com", $domain, $file_contents);
file_put_contents($path_to_newfile, $file_contents);

$mysqli = new mysqli("dbaddress", "username", "password", "mail");
$result = $mysqli->query("SELECT * FROM `hm_accounts`WHERE accountaddress = '$acc@$domain';");
if($result->num_rows == 0) {
} else {
	echo "<div><strong style=color:red;>Account taken!</strong></div>";
	exit;
}
$mysqli->close();

$success = mail("email@address.com","NEW ACCOUNT CREATED","NEW ACCOUNT $acc@$domain",'Content-Type: text/plain;charset=utf-8');
if (!$success) {
   print_r(error_get_last()['message']);
}
if ($_SERVER['REQUEST_METHOD'] == 'POST'){
    // Send email code
    die('<div><strong>Account created! <a href="/Home/">Return to Home?</a><br>Login <a href="https://mail.domain.tld">here</a></div></strong>');
}
}
?>
Set 'your_hmail_password' to your password, and change 'obAccount.Active = False' to True if youd rather accounts be immediately useable

newacc.vbs

Code: Select all

	Dim obApp
	Set obApp = CreateObject("hMailServer.Application")
	Call obApp.Authenticate("Administrator", "your_hmail_password")

	Dim obDomain
	Set obDomain = obApp.Domains.ItemByName("domain.com")
	
	Dim obAccount
	Set obAccount = obDomain.Accounts.Add

	obAccount.Address = "aco@domain.com"
	obAccount.Password = "newpass"
	obAccount.Active = False
	obAccount.MaxSize = 0

	obAccount.Save

	obAccount.IMAPFolders.add("Sent")
	obAccount.IMAPFolders.add("Drafts")
	obAccount.IMAPFolders.add("Spam")
	obAccount.IMAPFolders.add("Archive")
	obAccount.IMAPFolders.add("Trash")

Set oFso = CreateObject("Scripting.FileSystemObject") : oFso.DeleteFile Wscript.ScriptFullName, True
this goes in eventhandlers.vbs

Code: Select all

Sub ACCOUNT(oMessage)
	With CreateObject("WScript.Shell")
		.Run "C:\Windows\temp\run.vbs", 0, True
		EventLog.Write("ACCOUNT Script")
	End With
End Sub
You may also need to setup the stuff under '[mail function]' in your php.ini

palinka
Senior user
Senior user
Posts: 3589
Joined: 2017-09-12 17:57

Re: Account creation via webpage

Post by palinka » 2022-06-29 06:36

You can combine all these scripts into a single PHP script and forget about the rule altogether. PHP can access COM and DCOM, so you can use the hmailserver API directly from PHP.

User avatar
kimboslice
Normal user
Normal user
Posts: 32
Joined: 2022-02-05 16:38

Re: Account creation via webpage

Post by kimboslice » 2022-06-29 06:57

That would be awesome, I however suck at PHP... any pointers on how id do this?

palinka
Senior user
Senior user
Posts: 3589
Joined: 2017-09-12 17:57

Re: Account creation via webpage

Post by palinka » 2022-06-29 09:39

kimboslice wrote:
2022-06-29 06:57
That would be awesome, I however suck at PHP... any pointers on how id do this?
Here's one of my projects with a bunch of hMailServer api functions. Let me know if you have any questions.

https://github.com/palinkas-jo-reggelt/hMailServer_2FA

User avatar
kimboslice
Normal user
Normal user
Posts: 32
Joined: 2022-02-05 16:38

Re: Account creation via webpage

Post by kimboslice » 2022-06-29 21:14

Hmm, went through that quite thoroughly, not sure I understand it very well, got some hints from functions.php but cant seem to make anything work... I've also tried something like [link removed]this but can't make that work either :?

User avatar
kimboslice
Normal user
Normal user
Posts: 32
Joined: 2022-02-05 16:38

Re: Account creation via webpage

Post by kimboslice » 2022-06-30 00:45

Ok pretty much have this figured out, I believe 'php_com_dotnet.dll' needs to be loaded under '[ExtensionList]' for this to work

Code: Select all

<?php
		$hMS = new COM("hMailServer.Application");
		$hMS->Authenticate("Administrator", "your_hmail_password");
		
		$dom = $hMS->Domains->ItemByName("domain.com");
		$acc = $dom->Accounts->Add;
		$acc->Address = "aco@domain.com";
		$acc->Password = "newpass";
		$acc->Active = False;
		$acc->MaxSize = 0;
		$acc->Save();
		$acc->IMAPFolders->add("Sent");
		$acc->IMAPFolders->add("Drafts");
		$acc->IMAPFolders->add("Spam");
                $acc->IMAPFolders->add("Archive");
		$acc->IMAPFolders->add("Trash");
?>
If theres anything im doing wrong/incorrectly, please let me know... having some difficulty in incorporating this into the above webpage however,

User avatar
kimboslice
Normal user
Normal user
Posts: 32
Joined: 2022-02-05 16:38

Re: Account creation via webpage

Post by kimboslice » 2022-06-30 02:37

Cannot figure out whats wrong with this, can anyone spot any issues here?

Code: Select all

<!DOCTYPE HTML>
<html>
<head>
<style>
p {
  color: red;
  font-family: verdana;
  font-size: 80%;
  text-align: center;
}
form {
  position: center;
  border: 8px solid black;
  margin: auto;
  width: 200px;
  text-align: center;
}
.submit {
  position: relative;
  margin-left: auto;
}
.domain {
  position: center;
  margin-left: auto;
}
.email {
  position: center;
  margin-left: auto;
}
div {text-align: center;}
</style>
</head>
<title>E-mail Signup form</title>
<script>
    if ( window.history.replaceState ) {
        window.history.replaceState( null, null, window.location.href );
    }
</script>
<body style="background-color:#432938;" >
<form autocomplete="off" name="form" class="form" method="POST" action="./form.php">
  <p><label for="domain">Choose domain:</label></p>
  <select required="required" name="domain" class="domain" id="domain" required>
    <option value="domain.com">domain.com</option>
    <option value="domain.ca">domain.ca</option>
  </select>
<p class="Username">Username:</p> 
<input name="email" required="required" class="email" type="text" id="email" title="email" pattern="^[a-zA-Z0-9]+$" /><br>
<p>Password:</p>
<input name="password" autocomplete="new-password" minlength="8" class="email" required="required" type="password" id="password" />
<p>Confirm Password:</p>
<input name="password_confirm" class="email" required="required" type="password" id="password_confirm" oninput="check(this)" />
<script language='javascript' type='text/javascript'>
    function check(input) {
        if (input.value != document.getElementById('password').value) {
            input.setCustomValidity('Password Must be Matching.');
        } else {
            input.setCustomValidity('');
        }
    }
</script>
<br /><br />
<input type="submit" class="submit" name="registerBtn">
</form>

</body>
</html>
<?php
if (isset($_POST['registerBtn'])){ 
    $acc = $_POST['email'];
    $pass = $_POST['password'];
    $domain = $_POST['domain'];  

$mysqli = new mysqli("localhost", "root", "dbpassword", "mail");
$emailaddress = $mysqli->query("SELECT * FROM `hm_accounts`WHERE accountaddress = '$acc@$domain';");
$alias = $mysqli->query("SELECT * FROM `hm_aliases`WHERE aliasname = '$acc@$domain';");
if($emailaddress->num_rows == 0) {
} else {
	echo "<div><strong style=color:red;>Account taken!</strong></div>";
	exit;
}
if($alias->num_rows == 0) {
} else {
	echo "<div><strong style=color:red;>Alias!</strong></div>";
	exit;
}
$mysqli->close();

$hMailpass = "hmail_password";

$hMS = new COM("hMailServer.Application");
$hMS->Authenticate("Administrator", "$hMailpass");
$dom = $hMS->Domains->ItemByName("$domain");
$account = $dom->Accounts->Add;
$account->Address = "$acc@$domain";
$account->Password = "$pass";
$account->Active = False;
$account->MaxSize = 0;
$account->Save();
$account->IMAPFolders->add("Sent");
$account->IMAPFolders->add("Drafts");
$account->IMAPFolders->add("Spam");
$account->IMAPFolders->add("Archive");
$account->IMAPFolders->add("Trash");

if ($_SERVER['REQUEST_METHOD'] == 'POST'){
    die('<div><strong>Account created! <a href="/">Return to home?</a><br>Login <a href="https://mail.domain.com">here</a></div></strong>');
}
}
?>

User avatar
kimboslice
Normal user
Normal user
Posts: 32
Joined: 2022-02-05 16:38

Re: Account creation via webpage

Post by kimboslice » 2022-06-30 04:34

Fixed; it was a dcom permissions issue, mentioned here

So heres the final solution

enable dcom in php.ini i.e.

Code: Select all

extension="C:\Program Files\PHP\v7.4\ext\php_com_dotnet.dll"
Set the permissions as mentioned in the link above, and use the php from above

palinka
Senior user
Senior user
Posts: 3589
Joined: 2017-09-12 17:57

Re: Account creation via webpage

Post by palinka » 2022-06-30 07:42

OK, good to know you got it all figured out.

By the way, there's a function on that github page to validate passwords. If you're letting just anyone sign up and create an account with their own password, then you DEFINITLY want some minimum control over that process.

WEAK PASSWORDS ARE SPAM TARGETS AND WILL GET YOUR SERVER BLACKLISTED!!

Code: Select all

/*###   PASSWORD VALIDATION   ###########################*/
$pwMinLength         = 10;                 // Minimum password length
$pwValidateLowerCase = true;               // Lower case letters required
$pwValidateUpperCase = true;               // Upper case letters required
$pwValidateNumeric   = true;               // Numbers required
$pwValidateSymbols   = true;               // Symbols required
$pwSymbols           = "\!\#\$\%\^\&\*\(\)\_\-\+\=\<\>\,\.\?";   //Acceptable symbols (escape all characters to avoid conflict with php)

	Function validatePassword($password){
		global $pwMinLength;
		global $pwValidateLowerCase;
		global $pwValidateUpperCase;
		global $pwValidateNumeric;
		global $pwValidateSymbols;
		global $pwSymbols;
		$pwLenRegex = "/^.{".$pwMinLength.",}$/";
		$pwSymbolRegex = "/[".$pwSymbols."]/";
		
		$pwml = $pwlc = $pwuc = $pwn = $pws = "";
		
		if (!preg_match($pwLenRegex,$password)) {
			$pwml = "<br>* Password has too few characters. The minimum length is ".$pwMinLength." characters.";
		}
		if ($pwValidateLowerCase) {
			if (!preg_match("/[a-z]/",$password)) {
				$pwlc = "<br>* Password has no lower case letters. At least one lower case letter is required.";
			}
		}
		if ($pwValidateUpperCase) {
			if (!preg_match("/[A-Z]/",$password)) {
				$pwuc = "<br>* Password has no upper case letters. At least one upper case letter is required.";
			}
		}
		if ($pwValidateNumeric) {
			if (!preg_match("/[0-9]/",$password)) {
				$pwn = "<br>* Password has no numbers. At least one number is required.";
			}
		}
		if ($pwValidateSymbols) {
			if (!preg_match($pwSymbolRegex,$password)) {
				$pws = "<br>* Password has no symbols. At least one symbol is required.";
			}
		}

		return $pwml.$pwlc.$pwuc.$pwn.$pws;
	}

User avatar
kimboslice
Normal user
Normal user
Posts: 32
Joined: 2022-02-05 16:38

Re: Account creation via webpage

Post by kimboslice » 2022-07-02 05:39

Oh I'm not letting just anyone sign up... I just use this locally and behind a page with basic auth

I will definitely be requiring more complicated passwords though, thanks for the post

Post Reply