Enh #6164: Invitation by link (#6250)

* Enh #6164: Invitation by link: when registering within an SSO, the email should only be requested on the service provider

* Updated with fix #6202: Invite by link is not possible for a user already invited by email

* new AuthChoice() was causing HeadersAlreadySentException

* Allow registration by email with an SSO even if new user cannot register (in the settings)

* Added  and

* Fixed broken tests

* global token was given instead of space token

* Convert Invite when using OAuth to keep Space

* Use Session instead of Return Parameter

* Fix tests

* Fixed invalidToken Test

* Test: Fixed HTTP return code on disabled link invite

---------

Co-authored-by: Marc Farré <contact@marc.fun>
This commit is contained in:
Lucas Bartholemy 2023-05-17 22:09:14 +02:00 committed by GitHub
parent 78e09961c8
commit 933773f856
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 350 additions and 115 deletions

View File

@ -15,6 +15,8 @@ HumHub Changelog
- Enh #6236: Logging: Show log entries from migrations with category migration
- Fix #6216: Spaces icon in admin menu
- Fix #6229: Bug on saving forms: Zend OPcache API is restricted by "restrict_api"
- Enh #6240: Add ability to set showAtDashboard in SpaceMembership::addMember method
- Enh #6164: Invitation by link: when registering within an SSO, the email should only be requested on the service provider
- Enh #6240: Add ability to set showAtDashboard in SpaceMembership::addMember method
- Enh #5668: Allow Admin to sort the Spaces in a custom order
- Enh #29: AutoStart Tour for new Users

View File

@ -7,9 +7,9 @@ use humhub\modules\admin\permissions\ManageUsers;
use humhub\modules\space\jobs\AddUsersToSpaceJob;
use humhub\modules\space\models\Membership;
use humhub\modules\space\models\Space;
use humhub\modules\user\models\Invite;
use humhub\modules\user\models\User;
use humhub\modules\user\Module;
use humhub\modules\user\services\LinkRegistrationService;
use Yii;
use yii\base\Exception;
use yii\base\Model;
@ -103,7 +103,7 @@ class InviteForm extends Model
*/
public function save()
{
if(!$this->validate()) {
if (!$this->validate()) {
return false;
}
@ -354,11 +354,13 @@ class InviteForm extends Model
*/
public function getInviteLink($forceResetToken = false)
{
$token = $this->space->settings->get('inviteToken');
$linkRegistrationService = new LinkRegistrationService(null, $this->space);
$token = $linkRegistrationService->getStoredToken();
if ($forceResetToken || !$token) {
$token = Yii::$app->security->generateRandomString(Invite::LINK_TOKEN_LENGTH);
$this->space->settings->set('inviteToken', $token);
$token = $linkRegistrationService->setNewToken();
}
return Url::to(['/user/registration/by-link', 'token' => $token, 'spaceId' => $this->space->id], true);
}
}

View File

@ -20,7 +20,6 @@ use Yii;
*/
class AuthAction extends \yii\authclient\AuthAction
{
/**
* @inheritdoc
*
@ -29,13 +28,14 @@ class AuthAction extends \yii\authclient\AuthAction
*/
public function auth($client, $authUrlParams = [])
{
Yii::$app->session->set('loginRememberMe', (boolean) Yii::$app->request->get('rememberMe'));
$rememberMe = (bool)Yii::$app->request->get('rememberMe');
Yii::$app->session->set('loginRememberMe', $rememberMe);
if ($client instanceof StandaloneAuthClient) {
return $client->authAction($this);
}
return parent::auth($client);
return parent::auth($client, $authUrlParams);
}
/**

View File

@ -11,18 +11,20 @@ namespace humhub\modules\user\controllers;
use humhub\components\access\ControllerAccess;
use humhub\components\Controller;
use humhub\components\Response;
use humhub\modules\space\models\Space;
use humhub\modules\user\models\User;
use humhub\modules\user\authclient\AuthAction;
use humhub\modules\user\events\UserEvent;
use humhub\modules\user\models\Invite;
use humhub\modules\user\models\forms\Login;
use humhub\modules\user\authclient\interfaces\ApprovalBypass;
use humhub\modules\user\authclient\BaseFormAuth;
use humhub\modules\user\models\Session;
use humhub\modules\user\services\AuthClientService;
use humhub\modules\user\services\AuthClientUserService;
use humhub\modules\user\Module;
use humhub\modules\user\services\InviteRegistrationService;
use humhub\modules\user\services\LinkRegistrationService;
use Yii;
use yii\captcha\CaptchaAction;
use yii\web\Cookie;
use yii\authclient\BaseClient;
use yii\web\HttpException;
@ -71,7 +73,7 @@ class AuthController extends Controller
{
return [
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
'class' => CaptchaAction::class,
'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
],
'external' => [
@ -146,8 +148,6 @@ class AuthController extends Controller
*/
public function onAuthSuccess(BaseClient $authClient)
{
$attributes = $authClient->getUserAttributes();
// User already logged in - Add new authclient to existing user
if (!Yii::$app->user->isGuest) {
Yii::$app->user->getAuthClientUserService()->add($authClient);
@ -162,45 +162,69 @@ class AuthController extends Controller
return $this->redirect(['/user/auth/login']);
}
// Check if e-mail is already in use with another auth method
if ($user === null && isset($attributes['email'])) {
$user = User::findOne(['email' => $attributes['email']]);
if ($user !== null) {
// Map current auth method to user with same e-mail address
(new AuthClientUserService($user))->add($authClient);
}
}
$authClientService->autoMapToExistingUser();
if ($user !== null) {
return $this->login($user, $authClient);
}
if (!$authClient instanceof ApprovalBypass && !Yii::$app->getModule('user')->settings->get('auth.anonymousRegistration')) {
Yii::warning('Could not register user automatically: Anonymous registration disabled. AuthClient: ' . get_class($authClient), 'user');
Yii::$app->session->setFlash('error', Yii::t('UserModule.base', "You're not registered."));
return $this->redirect(['/user/auth/login']);
}
return $this->register($authClient);
}
// Check if E-Mail is given
if (!isset($attributes['email']) && Yii::$app->getModule('user')->emailRequired) {
/**
* Try to register (automatic user creation or start the registration process) after successful authentication
* without found related user account
*
* @param BaseClient $authClient
* @return Response|\yii\console\Response|\yii\web\Response
* @throws HttpException
*/
private function register(BaseClient $authClient)
{
$attributes = $authClient->getUserAttributes();
// Check if E-Mail is given by the AuthClient
if (!isset($attributes['email']) && $this->module->emailRequired) {
Yii::warning('Could not register user automatically: AuthClient ' . get_class($authClient) . ' provided no E-Mail attribute.', 'user');
Yii::$app->session->setFlash('error', Yii::t('UserModule.base', 'Missing E-Mail Attribute from AuthClient.'));
return $this->redirect(['/user/auth/login']);
}
// Check if AuthClient provide a ID for the user (mandatory)
if (!isset($attributes['id'])) {
Yii::warning('Could not register user automatically: AuthClient ' . get_class($authClient) . ' provided no ID attribute.', 'user');
Yii::$app->session->setFlash('error', Yii::t('UserModule.base', 'Missing ID AuthClient Attribute from AuthClient.'));
return $this->redirect(['/user/auth/login']);
}
// Try automatically create user & login user
$user = $authClientService->createUser();
$authClientService = new AuthClientService($authClient);
$tokenRegistrationService = new InviteRegistrationService((string) Yii::$app->request->get('token'));
$linkRegistrationService = LinkRegistrationService::createFromRequest();
if (!$tokenRegistrationService->isValid() && !$linkRegistrationService->isValid() && !$authClientService->allowSelfRegistration()) {
Yii::warning('Could not register user automatically: Anonymous registration disabled. AuthClient: ' . get_class($authClient), 'user');
Yii::$app->session->setFlash('error', Yii::t('UserModule.base', "You're not registered."));
return $this->redirect(['/user/auth/login']);
}
if ($linkRegistrationService->isValid() && !empty($attributes['email'])) {
$linkRegistrationService->convertToInvite($attributes['email']);
}
// Try automatic user creation
$user = $authClientService->createUser();
if ($user !== null) {
return $this->login($user, $authClient);
}
// Start Registration
return $this->redirectToRegistration($authClient);
}
private function redirectToRegistration(BaseClient $authClient)
{
if ($authClient instanceof \humhub\modules\user\authclient\BaseClient) {
/** @var \humhub\modules\user\authclient\BaseClient $authClient */
$authClient->beforeSerialize();
@ -209,10 +233,10 @@ class AuthController extends Controller
// Store authclient in session - for registration controller
Yii::$app->session->set('authClient', $authClient);
// Start registration process
return $this->redirect(['/user/registration']);
}
/**
* Login user
*

View File

@ -9,10 +9,13 @@
namespace humhub\modules\user\controllers;
use humhub\components\access\ControllerAccess;
use humhub\modules\space\models\forms\InviteForm;
use humhub\modules\space\models\Space;
use humhub\modules\user\Module;
use humhub\modules\user\services\LinkRegistrationService;
use humhub\modules\user\services\InviteRegistrationService;
use humhub\modules\user\widgets\AuthChoice;
use Yii;
use yii\authclient\BaseClient;
use yii\base\Exception;
use yii\db\StaleObjectException;
use yii\web\HttpException;
@ -67,16 +70,21 @@ class RegistrationController extends Controller
$registration = new Registration();
/**
* @var \yii\authclient\BaseClient
* @var BaseClient
*/
$authClient = null;
$inviteToken = Yii::$app->request->get('token', '');
$showAuthClients = AuthChoice::hasClients();
if ($inviteToken != '') {
$this->handleInviteRegistration($inviteToken, $registration);
if (Yii::$app->request->get('token')) {
$inviteRegistrationService = new InviteRegistrationService(Yii::$app->request->get('token'));
if (!$inviteRegistrationService->isValid()) {
throw new HttpException(404, 'Invalid registration token!');
}
$inviteRegistrationService->populateRegistration($registration);
} elseif (Yii::$app->session->has('authClient')) {
$authClient = Yii::$app->session->get('authClient');
$this->handleAuthClientRegistration($authClient, $registration);
$showAuthClients = false;
} else {
Yii::warning('Registration failed: No token (query) or authclient (session) found!', 'user');
Yii::$app->session->setFlash('error', 'Registration failed.');
@ -102,7 +110,10 @@ class RegistrationController extends Controller
]);
}
return $this->render('index', ['hForm' => $registration]);
return $this->render('index', [
'hForm' => $registration,
'showAuthClients' => $showAuthClients,
]);
}
@ -115,85 +126,37 @@ class RegistrationController extends Controller
* @throws \Throwable
* @throws StaleObjectException
*/
public function actionByLink($token = null, $spaceId = null)
public function actionByLink(?string $token = null, $spaceId = null)
{
if (empty($this->module->settings->get('auth.internalUsersCanInviteByLink'))) {
throw new HttpException(400, 'Invite by link is disabled!');
$linkRegistrationService = new LinkRegistrationService($token, Space::findOne(['id' => (int)$spaceId]));
if (!$linkRegistrationService->isEnabled()) {
throw new HttpException(404);
}
if ($spaceId !== null) {
// If invited by link from a space
$space = Space::findOne(['id' => (int)$spaceId]);
if ($space === null || $space->settings->get('inviteToken') !== $token) {
throw new HttpException(404, 'Invalid registration token!');
}
Yii::$app->setLanguage($space->ownerUser->language);
} else {
// If invited by link globally
if ($this->module->settings->get('registration.inviteToken') !== $token) {
throw new HttpException(404, 'Invalid registration token!');
}
if ($token === null || !$linkRegistrationService->isValid()) {
throw new HttpException(400, 'Invalid token provided!');
}
$invite = new Invite([
'source' => Invite::SOURCE_INVITE_BY_LINK,
'space_invite_id' => $spaceId,
'scenario' => 'invite',
'language' => Yii::$app->language,
]);
$linkRegistrationService->storeInSession();
if ($invite->load(Yii::$app->request->post())) {
// Deleting any previous email invitation or abandoned link invitation
$oldInvite = Invite::findOne(['email' => $invite->email]);
if ($oldInvite !== null) {
$oldInvite->delete();
}
if ($invite->save()) {
$invite->sendInviteMail();
return $this->render('@user/views/auth/register_success', ['model' => $invite]);
}
$form = new Invite(['source' => Invite::SOURCE_INVITE_BY_LINK]);
if ($form->load(Yii::$app->request->post()) && $form->validate()) {
$invite = $linkRegistrationService->convertToInvite($form->email);
$invite->sendInviteMail();
return $this->render('@user/views/auth/register_success', ['model' => $invite]);
}
return $this->render('byLink', [
'invite' => $invite,
'invite' => $form,
'showAuthClients' => true,
]);
}
/**
* @param $inviteToken
* @param Registration $form
* @throws HttpException
*/
protected function handleInviteByEmailRegistration($inviteToken, Registration $form)
{
$userInvite = Invite::findOne(['token' => $inviteToken]);
if (!$userInvite) {
throw new HttpException(404, 'Invalid registration token!');
}
Yii::$app->setLanguage($userInvite->language);
$form->getUser()->email = $userInvite->email;
}
/**
* @param $inviteToken
* @param Registration $form
* @throws HttpException
*/
protected function handleInviteRegistration($inviteToken, Registration $form)
{
$userInvite = Invite::findOne(['token' => $inviteToken]);
if (!$userInvite) {
throw new HttpException(404, 'Invalid registration token!');
}
Yii::$app->setLanguage($userInvite->language);
$form->getUser()->email = $userInvite->email;
}
/**
* Already all registration data gathered
*
* @param \yii\authclient\BaseClient $authClient
* @param BaseClient $authClient
* @param Registration $registration
* @throws Exception
*/

View File

@ -10,9 +10,13 @@
namespace humhub\modules\user\helpers;
use humhub\modules\space\models\Space;
use humhub\modules\user\models\forms\Registration;
use humhub\modules\user\models\Invite;
use humhub\modules\user\models\User;
use humhub\modules\user\Module;
use Yii;
use yii\web\HttpException;
/**
* Class AuthHelper
@ -88,4 +92,5 @@ class AuthHelper
return $username . $usernameRandomSuffix;
}
}

View File

@ -46,6 +46,11 @@ class Invite extends ActiveRecord
public $captcha;
/**
* @var bool
*/
public $skipCaptchaValidation = false;
/**
* @inheritdoc
*/
@ -238,8 +243,13 @@ class Invite extends ActiveRecord
return (!Yii::$app->settings->get('maintenanceMode') && Yii::$app->getModule('user')->settings->get('auth.anonymousRegistration'));
}
/**
* @return bool
*/
public function showCaptureInRegisterForm()
{
return (Yii::$app->getModule('user')->settings->get('auth.showCaptureInRegisterForm'));
return
!$this->skipCaptchaValidation
&& (Yii::$app->getModule('user')->settings->get('auth.showCaptureInRegisterForm'));
}
}

View File

@ -11,6 +11,7 @@ namespace humhub\modules\user\models\forms;
use humhub\modules\admin\permissions\ManageGroups;
use humhub\modules\admin\permissions\ManageUsers;
use humhub\modules\user\Module;
use humhub\modules\user\services\LinkRegistrationService;
use Yii;
use yii\base\Exception;
use yii\base\InvalidConfigException;
@ -123,15 +124,12 @@ class Invite extends Model
*/
public function getInviteLink($forceResetToken = false)
{
/* @var $module Module */
$module = Yii::$app->getModule('user');
$settings = $module->settings;
$token = $settings->get('registration.inviteToken');
$linkRegistrationService = new LinkRegistrationService();
$token = $linkRegistrationService->getStoredToken();
if ($forceResetToken || !$token) {
$token = Yii::$app->security->generateRandomString(\humhub\modules\user\models\Invite::LINK_TOKEN_LENGTH);
$settings->set('registration.inviteToken', $token);
$token = $linkRegistrationService->setNewToken();
}
return Url::to(['/user/registration/by-link', 'token' => $token], true);
}
}

View File

@ -18,6 +18,7 @@ use humhub\modules\user\helpers\AuthHelper;
use humhub\modules\user\models\Auth;
use humhub\modules\user\models\forms\Registration;
use humhub\modules\user\models\User;
use humhub\modules\user\Module;
use Yii;
use yii\authclient\ClientInterface;
use yii\helpers\VarDumper;
@ -187,4 +188,40 @@ class AuthClientService
return $authClientCollection;
}
public function autoMapToExistingUser(): void
{
$attributes = $this->authClient->getUserAttributes();
// Check if e-mail is already in use with another auth method
if ($this->getUser() === null && isset($attributes['email'])) {
$user = User::findOne(['email' => $attributes['email']]);
if ($user !== null) {
// Map current auth method to user with same e-mail address
(new AuthClientUserService($user))->add($this->authClient);
}
}
}
/**
* @return bool
* @since 1.15
*/
public function allowSelfRegistration(): bool
{
// Always also AuthClients like LDAP to automatic registration
if ($this->authClient instanceof ApprovalBypass) {
return true;
}
/** @var Module $module */
$module = Yii::$app->getModule('user');
// Anonymous Registration is enabled
if ($module->settings->get('auth.anonymousRegistration')) {
return true;
}
return false;
}
}

View File

@ -0,0 +1,48 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2023 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\user\services;
use humhub\modules\user\models\forms\Registration;
use humhub\modules\user\models\Invite;
use Yii;
/**
* InviteRegistrationService is responsible for registrations (Global or by Space) using a mail invite.
*
* @since 1.15
*/
final class InviteRegistrationService
{
private ?string $token;
public function __construct(?string $token)
{
$this->token = $token;
}
public function isValid(): bool
{
return ($this->getInvite() !== null);
}
private function getInvite(): ?Invite
{
return Invite::findOne(['token' => $this->token]);
}
public function populateRegistration(Registration $registration): void
{
$invite = $this->getInvite();
if ($invite !== null) {
Yii::$app->setLanguage($invite->language);
$registration->getUser()->email = $invite->email;
}
}
}

View File

@ -0,0 +1,125 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2023 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\user\services;
use humhub\modules\space\models\Space;
use humhub\modules\user\models\Invite;
use humhub\modules\user\Module;
use Yii;
use yii\base\Exception;
/**
* LinkRegistrationService is responsible for registrations (Global or per Space) using an Invite Link.
*
* @since 1.15
*/
final class LinkRegistrationService
{
const SETTING_VAR_ENABLED = 'auth.internalUsersCanInviteByLink';
const SETTING_VAR_SPACE_TOKEN = 'inviteToken';
const SETTING_VAR_TOKEN = 'registration.inviteToken';
private ?Space $space;
private ?string $token;
public static function createFromRequest(): LinkRegistrationService
{
$token = (string)Yii::$app->request->get('token', null);
$spaceId = (int)Yii::$app->request->get('spaceId');
if (!$token && Yii::$app->session->has(LinkRegistrationService::class . '::token')) {
$token = Yii::$app->session->get(LinkRegistrationService::class . '::token');
$spaceId = Yii::$app->session->get(LinkRegistrationService::class . '::spaceId', null);
}
return new LinkRegistrationService($token, Space::findOne(['id' => $spaceId]));
}
public function __construct(?string $token = null, ?Space $space = null)
{
$this->token = $token;
$this->space = $space;
}
public function isValid(): bool
{
return ($this->isEnabled() && $this->getStoredToken() === $this->token);
}
public function isEnabled(): bool
{
/** @var Module $module */
$module = Yii::$app->getModule('user');
return (!empty($module->settings->get(self::SETTING_VAR_ENABLED)));
}
public function getStoredToken(): ?string
{
if ($this->space) {
// TODO: Find better solution
Yii::$app->setLanguage($this->space->ownerUser->language);
return $this->space->settings->get(self::SETTING_VAR_SPACE_TOKEN);
}
/** @var Module $module */
$module = Yii::$app->getModule('user');
return $module->settings->get(self::SETTING_VAR_TOKEN);
}
public function setNewToken(): string
{
$newToken = Yii::$app->security->generateRandomString(Invite::LINK_TOKEN_LENGTH);
if ($this->space) {
$this->space->settings->set(self::SETTING_VAR_SPACE_TOKEN, $newToken);
} else {
/** @var Module $module */
$module = Yii::$app->getModule('user');
$module->settings->set(self::SETTING_VAR_TOKEN, $newToken);
}
return $newToken;
}
public function convertToInvite(string $email): Invite
{
// Deleting any previous email invitation or abandoned link invitation
$oldInvite = Invite::findOne(['email' => $email]);
if ($oldInvite !== null) {
$oldInvite->delete();
}
$invite = new Invite([
'email' => $email,
'scenario' => 'invite',
'language' => Yii::$app->language,
]);
$invite->skipCaptchaValidation = true;
$invite->source = Invite::SOURCE_INVITE_BY_LINK;
if ($this->space) {
$invite->space_invite_id = $this->space->id;
}
if (!$invite->save()) {
throw new Exception('Could not create invite!');
}
return $invite;
}
public function storeInSession()
{
Yii::$app->session->set(get_class($this) . '::token', $this->token);
Yii::$app->session->set(get_class($this) . '::spaceId', $this->space->id ?? null);
}
}

View File

@ -15,7 +15,7 @@ class LinkInviteCest
$inviteUrl = $inviteForm->getInviteLink();
$I->amOnPage($inviteUrl);
$I->seeResponseCodeIs(400);
$I->seeResponseCodeIs(404);
}
public function testInvalidToken(FunctionalTester $I)
@ -25,7 +25,7 @@ class LinkInviteCest
Yii::$app->getModule('user')->settings->set('auth.internalUsersCanInviteByLink', 1);
$I->amOnRoute('/user/registration/by-link', ['token' => 'abcd', 'spaceId' => 1]);
$I->seeResponseCodeIs(404);
$I->seeResponseCodeIs(400);
}
public function testValidTokenDifferentSpaceId(FunctionalTester $I)
@ -34,17 +34,25 @@ class LinkInviteCest
Yii::$app->getModule('user')->settings->set('auth.internalUsersCanInviteByLink', 1);
// Generate Token
$space = \humhub\modules\space\models\Space::findOne(['name' => 'Space 2']);
$inviteForm = new \humhub\modules\space\models\forms\InviteForm();
$inviteForm->space = $space;
$inviteUrl = $inviteForm->getInviteLink();
$I->amOnRoute('/user/registration/by-link', ['token' => $space->settings->get('inviteToken'), 'spaceId' => $space->id]);
$linkRegistrationService = new \humhub\modules\user\services\LinkRegistrationService(null, $space);
$I->amOnRoute('/user/registration/by-link', ['token' => $linkRegistrationService->getStoredToken(), 'spaceId' => $space->id]);
$I->seeResponseCodeIs(200);
$I->amOnRoute('/user/registration/by-link', ['token' => $space->settings->get('inviteToken'), 'spaceId' => 1]);
$I->amOnRoute('/user/registration/by-link', ['token' => $linkRegistrationService->getStoredToken(), 'spaceId' => 1]);
$I->seeResponseCodeIs(400);
Yii::$app->getModule('user')->settings->set('auth.internalUsersCanInviteByLink', 0);
$I->amOnRoute('/user/registration/by-link', ['token' => 'abc', 'spaceId' => 1]);
$I->seeResponseCodeIs(404);
}

View File

@ -7,7 +7,10 @@ use humhub\libs\Html;
use humhub\modules\user\models\Invite;
use yii\captcha\Captcha;
/* @var $invite Invite */
/**
* @var $invite Invite
* @var $showAuthClients bool
*/
$this->pageTitle = Yii::t('UserModule.auth', 'Create Account');
?>
@ -22,6 +25,10 @@ $this->pageTitle = Yii::t('UserModule.auth', 'Create Account');
<?= Yii::t('UserModule.auth', '<strong>Account</strong> registration') ?>
</div>
<div class="panel-body">
<?php if ($showAuthClients && AuthChoice::hasClients()): ?>
<?= AuthChoice::widget() ?>
<?php endif; ?>
<?php if (Yii::$app->session->hasFlash('error')): ?>
<div class="alert alert-danger" role="alert">
<?= Yii::$app->session->getFlash('error') ?>

View File

@ -1,10 +1,16 @@
<?php
use humhub\modules\user\models\forms\Registration;
use humhub\widgets\SiteLogo;
use yii\bootstrap\ActiveForm;
use humhub\modules\user\widgets\AuthChoice;
use humhub\libs\Html;
/**
* @var $hForm Registration
* @var $showAuthClients bool
*/
$this->pageTitle = Yii::t('UserModule.auth', 'Create Account');
?>
@ -18,7 +24,7 @@ $this->pageTitle = Yii::t('UserModule.auth', 'Create Account');
<?= Yii::t('UserModule.auth', '<strong>Account</strong> registration') ?>
</div>
<div class="panel-body">
<?php if (AuthChoice::hasClients()): ?>
<?php if ($showAuthClients): ?>
<?= AuthChoice::widget() ?>
<?php endif; ?>