Add phone and display name field
Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
parent
58712c82d0
commit
d140ee8d77
|
|
@ -1,13 +1,17 @@
|
||||||
#body-login #email,
|
#body-login #email,
|
||||||
#body-login #token,
|
#body-login #token,
|
||||||
#body-login #username,
|
#body-login #loginname,
|
||||||
|
#body-login #fullname,
|
||||||
|
#body-login #phone,
|
||||||
#body-login #password {
|
#body-login #password {
|
||||||
width: calc(100% - 56px);
|
width: calc(100% - 56px);
|
||||||
padding-left: 36px;
|
padding-left: 36px;
|
||||||
}
|
}
|
||||||
#email-icon,
|
#email-icon,
|
||||||
#token-icon,
|
#token-icon,
|
||||||
#username-icon,
|
#loginname-icon,
|
||||||
|
#fullname-icon,
|
||||||
|
#phone-icon,
|
||||||
#password-icon {
|
#password-icon {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 16px;
|
left: 16px;
|
||||||
|
|
@ -16,8 +20,8 @@
|
||||||
filter: alpha(opacity=30);
|
filter: alpha(opacity=30);
|
||||||
opacity: .3;
|
opacity: .3;
|
||||||
}
|
}
|
||||||
#username-icon {
|
#email-icon {
|
||||||
top: 17px;
|
top: 27px;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="submit"] {
|
input[type="submit"] {
|
||||||
|
|
@ -41,3 +45,7 @@ input[type="submit"] {
|
||||||
.groupofone {
|
.groupofone {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.toggle-password {
|
||||||
|
top: 22px !important;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -214,11 +214,13 @@ class RegisterController extends Controller {
|
||||||
*
|
*
|
||||||
* @param string $secret
|
* @param string $secret
|
||||||
* @param string $token
|
* @param string $token
|
||||||
* @param string $username
|
* @param string $loginname
|
||||||
|
* @param string $fullname
|
||||||
|
* @param string $phone
|
||||||
* @param string $message
|
* @param string $message
|
||||||
* @return TemplateResponse
|
* @return TemplateResponse
|
||||||
*/
|
*/
|
||||||
public function showUserForm(string $secret, string $token, string $username = '', string $message = ''): TemplateResponse {
|
public function showUserForm(string $secret, string $token, string $loginname = '', string $fullname = '', string $phone = '', string $password = '', string $message = ''): TemplateResponse {
|
||||||
try {
|
try {
|
||||||
$registration = $this->validateSecretAndToken($secret, $token);
|
$registration = $this->validateSecretAndToken($secret, $token);
|
||||||
} catch (RegistrationException $e) {
|
} catch (RegistrationException $e) {
|
||||||
|
|
@ -230,8 +232,13 @@ class RegisterController extends Controller {
|
||||||
return new TemplateResponse('registration', 'form/user', [
|
return new TemplateResponse('registration', 'form/user', [
|
||||||
'email' => $registration->getEmail(),
|
'email' => $registration->getEmail(),
|
||||||
'email_is_login' => $this->config->getAppValue('registration', 'email_is_login', 'no') === 'yes',
|
'email_is_login' => $this->config->getAppValue('registration', 'email_is_login', 'no') === 'yes',
|
||||||
'username' => $username,
|
'loginname' => $loginname,
|
||||||
|
'fullname' => $fullname,
|
||||||
|
'show_fullname' => $this->config->getAppValue('registration', 'enfore_fullname', 'no') === 'yes',
|
||||||
|
'phone' => $phone,
|
||||||
|
'show_phone' => $this->config->getAppValue('registration', 'enfore_phone', 'no') === 'yes',
|
||||||
'message' => $message,
|
'message' => $message,
|
||||||
|
'password' => $password,
|
||||||
'additional_hint' => $additional_hint,
|
'additional_hint' => $additional_hint,
|
||||||
], 'guest');
|
], 'guest');
|
||||||
}
|
}
|
||||||
|
|
@ -243,11 +250,13 @@ class RegisterController extends Controller {
|
||||||
*
|
*
|
||||||
* @param string $secret
|
* @param string $secret
|
||||||
* @param string $token
|
* @param string $token
|
||||||
* @param string $username
|
* @param string $loginname
|
||||||
|
* @param string $fullname
|
||||||
|
* @param string $phone
|
||||||
* @param string $password
|
* @param string $password
|
||||||
* @return RedirectResponse|TemplateResponse
|
* @return RedirectResponse|TemplateResponse
|
||||||
*/
|
*/
|
||||||
public function submitUserForm(string $secret, string $token, string $username, string $password): Response {
|
public function submitUserForm(string $secret, string $token, string $loginname, string $fullname, string $phone, string $password): Response {
|
||||||
try {
|
try {
|
||||||
$registration = $this->validateSecretAndToken($secret, $token);
|
$registration = $this->validateSecretAndToken($secret, $token);
|
||||||
} catch (RegistrationException $e) {
|
} catch (RegistrationException $e) {
|
||||||
|
|
@ -255,13 +264,13 @@ class RegisterController extends Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->config->getAppValue('registration', 'email_is_login', 'no') === 'yes') {
|
if ($this->config->getAppValue('registration', 'email_is_login', 'no') === 'yes') {
|
||||||
$username = $registration->getEmail();
|
$loginname = $registration->getEmail();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$user = $this->registrationService->createAccount($registration, $username, $password);
|
$user = $this->registrationService->createAccount($registration, $loginname, $fullname, $phone, $password);
|
||||||
} catch (Exception $exception) {
|
} catch (Exception $exception) {
|
||||||
return $this->showUserForm($secret, $token, $username, $exception->getMessage());
|
return $this->showUserForm($secret, $token, $loginname, $fullname, $phone, $password, $exception->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete registration
|
// Delete registration
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,10 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace OCA\Registration\Service;
|
namespace OCA\Registration\Service;
|
||||||
|
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use libphonenumber\NumberParseException;
|
||||||
|
use libphonenumber\PhoneNumber;
|
||||||
|
use libphonenumber\PhoneNumberUtil;
|
||||||
use OC\Authentication\Exceptions\InvalidTokenException;
|
use OC\Authentication\Exceptions\InvalidTokenException;
|
||||||
use OC\Authentication\Exceptions\PasswordlessTokenException;
|
use OC\Authentication\Exceptions\PasswordlessTokenException;
|
||||||
use OC\Authentication\Token\IProvider;
|
use OC\Authentication\Token\IProvider;
|
||||||
|
|
@ -37,6 +41,7 @@ use OC\Authentication\Token\IToken;
|
||||||
use OCA\Registration\AppInfo\Application;
|
use OCA\Registration\AppInfo\Application;
|
||||||
use OCA\Registration\Db\Registration;
|
use OCA\Registration\Db\Registration;
|
||||||
use OCA\Registration\Db\RegistrationMapper;
|
use OCA\Registration\Db\RegistrationMapper;
|
||||||
|
use OCP\Accounts\IAccountManager;
|
||||||
use OCP\AppFramework\Db\DoesNotExistException;
|
use OCP\AppFramework\Db\DoesNotExistException;
|
||||||
use OCP\ILogger;
|
use OCP\ILogger;
|
||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
|
|
@ -66,6 +71,8 @@ class RegistrationService {
|
||||||
private $registrationMapper;
|
private $registrationMapper;
|
||||||
/** @var IUserManager */
|
/** @var IUserManager */
|
||||||
private $userManager;
|
private $userManager;
|
||||||
|
/** @var IAccountManager */
|
||||||
|
private $accountManager;
|
||||||
/** @var IConfig */
|
/** @var IConfig */
|
||||||
private $config;
|
private $config;
|
||||||
/** @var IGroupManager */
|
/** @var IGroupManager */
|
||||||
|
|
@ -92,6 +99,7 @@ class RegistrationService {
|
||||||
IURLGenerator $urlGenerator,
|
IURLGenerator $urlGenerator,
|
||||||
RegistrationMapper $registrationMapper,
|
RegistrationMapper $registrationMapper,
|
||||||
IUserManager $userManager,
|
IUserManager $userManager,
|
||||||
|
IAccountManager $accountManager,
|
||||||
IConfig $config,
|
IConfig $config,
|
||||||
IGroupManager $groupManager,
|
IGroupManager $groupManager,
|
||||||
ISecureRandom $random,
|
ISecureRandom $random,
|
||||||
|
|
@ -108,6 +116,7 @@ class RegistrationService {
|
||||||
$this->urlGenerator = $urlGenerator;
|
$this->urlGenerator = $urlGenerator;
|
||||||
$this->registrationMapper = $registrationMapper;
|
$this->registrationMapper = $registrationMapper;
|
||||||
$this->userManager = $userManager;
|
$this->userManager = $userManager;
|
||||||
|
$this->accountManager = $accountManager;
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
$this->groupManager = $groupManager;
|
$this->groupManager = $groupManager;
|
||||||
$this->random = $random;
|
$this->random = $random;
|
||||||
|
|
@ -229,17 +238,44 @@ class RegistrationService {
|
||||||
* @throws RegistrationException
|
* @throws RegistrationException
|
||||||
*/
|
*/
|
||||||
public function validateUsername(string $username): void {
|
public function validateUsername(string $username): void {
|
||||||
if ($username === "") {
|
if ($username === '') {
|
||||||
throw new RegistrationException($this->l10n->t('Please provide a valid user name.'));
|
throw new RegistrationException($this->l10n->t('Please provide a valid login name.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$regex = $this->config->getAppValue($this->appName, 'username_policy_regex', '');
|
$regex = $this->config->getAppValue($this->appName, 'username_policy_regex', '');
|
||||||
if ($regex && preg_match($regex, $username) === 0) {
|
if ($regex && preg_match($regex, $username) === 0) {
|
||||||
throw new RegistrationException($this->l10n->t('Please provide a valid user name.'));
|
throw new RegistrationException($this->l10n->t('Please provide a valid login name.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->registrationMapper->usernameIsPending($username) || $this->userManager->get($username) !== null) {
|
if ($this->registrationMapper->usernameIsPending($username) || $this->userManager->get($username) !== null) {
|
||||||
throw new RegistrationException($this->l10n->t('The username you have chosen already exists.'));
|
throw new RegistrationException($this->l10n->t('The login name you have chosen already exists.'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $phone
|
||||||
|
* @throws RegistrationException
|
||||||
|
*/
|
||||||
|
public function validatePhoneNumber(string $phone): void {
|
||||||
|
$defaultRegion = $this->config->getSystemValueString('default_phone_region', '');
|
||||||
|
|
||||||
|
if ($defaultRegion === '') {
|
||||||
|
// When no default region is set, only +49… numbers are valid
|
||||||
|
if (strpos($phone, '+') !== 0) {
|
||||||
|
throw new RegistrationException($this->l10n->t('The phone number needs to contain the country code.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$defaultRegion = 'EN';
|
||||||
|
}
|
||||||
|
|
||||||
|
$phoneUtil = PhoneNumberUtil::getInstance();
|
||||||
|
try {
|
||||||
|
$phoneNumber = $phoneUtil->parse($phone, $defaultRegion);
|
||||||
|
if (!$phoneNumber instanceof PhoneNumber || !$phoneUtil->isValidNumber($phoneNumber)) {
|
||||||
|
throw new RegistrationException($this->l10n->t('The phone number is invalid.'));
|
||||||
|
}
|
||||||
|
} catch (NumberParseException $e) {
|
||||||
|
throw new RegistrationException($this->l10n->t('The phone number is invalid.'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -290,41 +326,53 @@ class RegistrationService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $registration
|
* @param Registration $registration
|
||||||
* @param string|null $username
|
* @param string|null $loginName
|
||||||
|
* @param string|null $fullName
|
||||||
|
* @param string|null $phone
|
||||||
* @param string|null $password
|
* @param string|null $password
|
||||||
* @return IUser
|
* @return IUser
|
||||||
* @throws RegistrationException|InvalidTokenException
|
* @throws RegistrationException|InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function createAccount(Registration $registration, ?string $username = null, ?string $password = null): IUser {
|
public function createAccount(Registration $registration, ?string $loginName = null, ?string $fullName = null, ?string $phone = null, ?string $password = null): IUser {
|
||||||
if ($password === null && $registration->getPassword() === null) {
|
if ($loginName === null) {
|
||||||
$generatedPassword = $this->generateRandomDeviceToken();
|
$loginName = $registration->getUsername();
|
||||||
$registration->setPassword($this->crypto->encrypt($generatedPassword));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($username === null) {
|
|
||||||
$username = $registration->getUsername();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($registration->getPassword() !== null) {
|
if ($registration->getPassword() !== null) {
|
||||||
$password = $this->crypto->decrypt($registration->getPassword());
|
$password = $this->crypto->decrypt($registration->getPassword());
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->validateUsername($username);
|
if (!$password) {
|
||||||
|
throw new RegistrationException($this->l10n->t('Please provide a password.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->validateUsername($loginName);
|
||||||
|
|
||||||
|
if ($this->config->getAppValue('registration', 'enfore_fullname', 'no') === 'yes') {
|
||||||
|
$this->validateDisplayname($fullName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($phone) {
|
||||||
|
$this->validatePhoneNumber($phone);
|
||||||
|
} elseif ($this->config->getAppValue('registration', 'enfore_phone', 'no') === 'yes') {
|
||||||
|
throw new RegistrationException($this->l10n->t('Please provide a valid phone number.'));
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO
|
/* TODO
|
||||||
* createUser tests username validity once, but validateUsername already checked it,
|
* createUser tests username validity once, but validateUsername already checked it,
|
||||||
* but createUser doesn't check if there is a pending registration with that name
|
* but createUser doesn't check if there is a pending registration with that name
|
||||||
*
|
*
|
||||||
* And validateUsername will throw RegistrationException while
|
* And validateUsername will throw RegistrationException while
|
||||||
* createUser throws \InvalidTokenException in NC, \Exception in OC
|
* createUser throws \InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
$user = $this->userManager->createUser($username, $password);
|
$user = $this->userManager->createUser($loginName, $password);
|
||||||
if ($user === false) {
|
if ($user === false) {
|
||||||
throw new RegistrationException($this->l10n->t('Unable to create user, there are problems with the user backend.'));
|
throw new RegistrationException($this->l10n->t('Unable to create user, there are problems with the user backend.'));
|
||||||
}
|
}
|
||||||
$userId = $user->getUID();
|
$userId = $user->getUID();
|
||||||
|
|
||||||
|
|
||||||
// Set user email
|
// Set user email
|
||||||
try {
|
try {
|
||||||
$user->setEMailAddress($registration->getEmail());
|
$user->setEMailAddress($registration->getEmail());
|
||||||
|
|
@ -332,6 +380,22 @@ class RegistrationService {
|
||||||
throw new RegistrationException($this->l10n->t('Unable to set user email: ' . $e->getMessage()));
|
throw new RegistrationException($this->l10n->t('Unable to set user email: ' . $e->getMessage()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set display name
|
||||||
|
if ($fullName) {
|
||||||
|
$user->setDisplayName($fullName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set phone number in account data
|
||||||
|
$account = $this->accountManager->getAccount($user);
|
||||||
|
$property = $account->getProperty(IAccountManager::PROPERTY_PHONE);
|
||||||
|
$account->setProperty(
|
||||||
|
IAccountManager::PROPERTY_PHONE,
|
||||||
|
$phone,
|
||||||
|
$property->getScope(),
|
||||||
|
IAccountManager::NOT_VERIFIED
|
||||||
|
);
|
||||||
|
$this->accountManager->updateAccount($account);
|
||||||
|
|
||||||
// Add user to group
|
// Add user to group
|
||||||
$registeredUserGroup = $this->config->getAppValue($this->appName, 'registered_user_group', 'none');
|
$registeredUserGroup = $this->config->getAppValue($this->appName, 'registered_user_group', 'none');
|
||||||
if ($registeredUserGroup !== 'none') {
|
if ($registeredUserGroup !== 'none') {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ script('registration', 'form');
|
||||||
<?php if (!empty($_['additional_hint'])): ?>
|
<?php if (!empty($_['additional_hint'])): ?>
|
||||||
<ul class="msg">
|
<ul class="msg">
|
||||||
<li><?php p($_['additional_hint']); ?></li>
|
<li><?php p($_['additional_hint']); ?></li>
|
||||||
</ul>
|
</ul>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -30,19 +30,45 @@ script('registration', 'form');
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<?php if (!$_['email_is_login']) { ?>
|
<?php if (!$_['email_is_login']) { ?>
|
||||||
|
<p class="groupmiddle">
|
||||||
|
<input type="text" name=loginname" id="loginname" value="<?php if (!empty($_['login'])) {
|
||||||
|
p($_['login']);
|
||||||
|
} ?>" placeholder="<?php p($l->t('Login name')); ?>" />
|
||||||
|
<label for="loginname" class="infield"><?php p($l->t('Login name')); ?></label>
|
||||||
|
<img id="loginname-icon" class="svg" src="<?php print_unescaped(image_path('', 'categories/auth.svg')); ?>" alt=""/>
|
||||||
|
</p>
|
||||||
|
<?php } else { ?>
|
||||||
|
<input type="hidden" name="loginname" value="<?php p($_['email']); ?>" />
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
<?php if ($_['show_fullname']) { ?>
|
||||||
<p class="groupmiddle">
|
<p class="groupmiddle">
|
||||||
<input type="text" name="username" id="username" value="<?php if (!empty($_['entered_data']['user'])) {
|
<input type="text" name="fullname" id="fullname" value="<?php if (!empty($_['fullname'])) {
|
||||||
p($_['entered_data']['user']);
|
p($_['fullname']);
|
||||||
} ?>" placeholder="<?php p($l->t('Username')); ?>" />
|
} ?>" placeholder="<?php p($l->t('Full name')); ?>" />
|
||||||
<label for="username" class="infield"><?php p($l->t('Username')); ?></label>
|
<label for="fullname" class="infield"><?php p($l->t('Full name')); ?></label>
|
||||||
<img id="username-icon" class="svg" src="<?php print_unescaped(image_path('', 'actions/user.svg')); ?>" alt=""/>
|
<img id="fullname-icon" class="svg" src="<?php print_unescaped(image_path('', 'actions/user.svg')); ?>" alt=""/>
|
||||||
</p>
|
</p>
|
||||||
<?php } else { ?>
|
<?php } else { ?>
|
||||||
<input type="hidden" name="username" value="<?php p($_['email']); ?>" />
|
<input type="hidden" name="fullname" value="" />
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
<?php if ($_['show_phone']) { ?>
|
||||||
|
<p class="groupmiddle">
|
||||||
|
<input type="text" name="phone" id="phone" value="<?php if (!empty($_['phone'])) {
|
||||||
|
p($_['phone']);
|
||||||
|
} ?>" placeholder="<?php p($l->t('Phone number')); ?>" />
|
||||||
|
<label for="phone" class="infield"><?php p($l->t('Phone number')); ?></label>
|
||||||
|
<img id="phone-icon" class="svg" src="<?php print_unescaped(image_path('', 'clients/phone.svg')); ?>" alt=""/>
|
||||||
|
</p>
|
||||||
|
<?php } else { ?>
|
||||||
|
<input type="hidden" name="phone" value="" />
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
||||||
<p class="groupbottom">
|
<p class="groupbottom">
|
||||||
<input type="password" name="password" id="password" placeholder="<?php p($l->t('Password')); ?>"/>
|
<input type="password" name="password" id="password" value="<?php if (!empty($_['password'])) {
|
||||||
|
p($_['password']);
|
||||||
|
} ?>" placeholder="<?php p($l->t('Password')); ?>"/>
|
||||||
<label for="password" class="infield"><?php p($l->t('Password')); ?></label>
|
<label for="password" class="infield"><?php p($l->t('Password')); ?></label>
|
||||||
<img id="password-icon" class="svg" src="<?php print_unescaped(image_path('', 'actions/password.svg')); ?>" alt=""/>
|
<img id="password-icon" class="svg" src="<?php print_unescaped(image_path('', 'actions/password.svg')); ?>" alt=""/>
|
||||||
<a id="showadminpass" href="#" class="toggle-password">
|
<a id="showadminpass" href="#" class="toggle-password">
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue