mirror of
https://github.com/Bubka/2FAuth.git
synced 2025-04-10 18:48:17 +02:00
Add an email registration policy feature - Closes #250
This commit is contained in:
parent
fd5520c1cf
commit
3eed7c8f5b
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Api\v1\Requests;
|
namespace App\Api\v1\Requests;
|
||||||
|
|
||||||
|
use App\Rules\IsValideEmailList;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
@ -24,8 +25,16 @@ public function authorize()
|
|||||||
*/
|
*/
|
||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
return [
|
$rule = [
|
||||||
'value' => 'required',
|
'value' => [
|
||||||
|
'required',
|
||||||
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if ($this->route()->parameter('settingName') == 'restrictList') {
|
||||||
|
$rule['value'][] = new IsValideEmailList;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $rule;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Requests;
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use App\Rules\ComplyWithEmailRestrictionPolicy;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
class UserStoreRequest extends FormRequest
|
class UserStoreRequest extends FormRequest
|
||||||
@ -25,7 +26,14 @@ public function rules()
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'name' => 'unique:App\Models\User,name|required|string|max:191',
|
'name' => 'unique:App\Models\User,name|required|string|max:191',
|
||||||
'email' => 'unique:App\Models\User,email|required|string|email|max:191',
|
'email' => [
|
||||||
|
'unique:App\Models\User,email',
|
||||||
|
'required',
|
||||||
|
'string',
|
||||||
|
'email',
|
||||||
|
'max:191',
|
||||||
|
new ComplyWithEmailRestrictionPolicy,
|
||||||
|
],
|
||||||
'password' => 'required|string|min:8|confirmed',
|
'password' => 'required|string|min:8|confirmed',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Requests;
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use App\Rules\ComplyWithEmailRestrictionPolicy;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
@ -37,6 +38,7 @@ public function rules()
|
|||||||
'email',
|
'email',
|
||||||
'max:191',
|
'max:191',
|
||||||
Rule::unique('users')->ignore($this->user()->id),
|
Rule::unique('users')->ignore($this->user()->id),
|
||||||
|
new ComplyWithEmailRestrictionPolicy,
|
||||||
],
|
],
|
||||||
'password' => 'required',
|
'password' => 'required',
|
||||||
];
|
];
|
||||||
|
42
app/Rules/ComplyWithEmailRestrictionPolicy.php
Normal file
42
app/Rules/ComplyWithEmailRestrictionPolicy.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Rules;
|
||||||
|
|
||||||
|
use App\Facades\Settings;
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Contracts\Validation\ValidationRule;
|
||||||
|
|
||||||
|
class ComplyWithEmailRestrictionPolicy implements ValidationRule
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the validation rule.
|
||||||
|
*/
|
||||||
|
public function validate(string $attribute, mixed $value, Closure $fail): void
|
||||||
|
{
|
||||||
|
$list = Settings::get('restrictList');
|
||||||
|
$regex = Settings::get('restrictRule');
|
||||||
|
|
||||||
|
$validatesFilter = true;
|
||||||
|
$validatesRegex = true;
|
||||||
|
|
||||||
|
if (Settings::get('restrictRegistration') == true) {
|
||||||
|
if ($list && ! in_array($value, explode('|', $list))) {
|
||||||
|
$validatesFilter = false;
|
||||||
|
}
|
||||||
|
if ($regex && ! preg_match('/' . $regex . '/', $value)) {
|
||||||
|
$validatesRegex = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($list && $regex) {
|
||||||
|
if (! $validatesFilter && ! $validatesRegex) {
|
||||||
|
$fail('validation.custom.email.ComplyWithEmailRestrictionPolicy')->translate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (! $validatesFilter || ! $validatesRegex) {
|
||||||
|
$fail('validation.custom.email.ComplyWithEmailRestrictionPolicy')->translate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
29
app/Rules/IsValideEmailList.php
Normal file
29
app/Rules/IsValideEmailList.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Rules;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Contracts\Validation\ValidationRule;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
|
class IsValideEmailList implements ValidationRule
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the validation rule.
|
||||||
|
*/
|
||||||
|
public function validate(string $attribute, mixed $value, Closure $fail): void
|
||||||
|
{
|
||||||
|
$emails = explode('|', $value);
|
||||||
|
|
||||||
|
$pass = Validator::make(
|
||||||
|
$emails,
|
||||||
|
[
|
||||||
|
'*' => 'email',
|
||||||
|
]
|
||||||
|
)->passes();
|
||||||
|
|
||||||
|
if (! $pass) {
|
||||||
|
$fail('validation.custom.email.IsValidEmailList')->translate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -74,6 +74,7 @@
|
|||||||
'latestRelease' => false,
|
'latestRelease' => false,
|
||||||
'disableRegistration' => false,
|
'disableRegistration' => false,
|
||||||
'enableSso' => true,
|
'enableSso' => true,
|
||||||
|
'restrictRegistration' => false,
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -46,6 +46,7 @@ import {
|
|||||||
faFileLines,
|
faFileLines,
|
||||||
faVideoSlash,
|
faVideoSlash,
|
||||||
faChevronRight,
|
faChevronRight,
|
||||||
|
faSlash,
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -107,6 +108,7 @@ library.add(
|
|||||||
faChevronRight,
|
faChevronRight,
|
||||||
faOpenid,
|
faOpenid,
|
||||||
faPaperPlane,
|
faPaperPlane,
|
||||||
|
faSlash,
|
||||||
);
|
);
|
||||||
|
|
||||||
export default FontAwesomeIcon
|
export default FontAwesomeIcon
|
@ -3,6 +3,14 @@ import { httpClientFactory } from '@/services/httpClientFactory'
|
|||||||
const apiClient = httpClientFactory('api')
|
const apiClient = httpClientFactory('api')
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
get(config = {}) {
|
||||||
|
return apiClient.get('/settings', { ...config })
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @returns
|
* @returns
|
||||||
@ -11,4 +19,11 @@ export default {
|
|||||||
return apiClient.put('/settings/' + name, { value: value })
|
return apiClient.put('/settings/' + name, { value: value })
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
delete(name, config = {}) {
|
||||||
|
return apiClient.delete('/settings/' + name, { ...config })
|
||||||
|
},
|
||||||
}
|
}
|
@ -17,6 +17,19 @@
|
|||||||
const infos = ref()
|
const infos = ref()
|
||||||
const listInfos = ref(null)
|
const listInfos = ref(null)
|
||||||
const isSendingTestEmail = ref(false)
|
const isSendingTestEmail = ref(false)
|
||||||
|
const fieldErrors = ref({
|
||||||
|
restrictList: null,
|
||||||
|
restrictRule: null,
|
||||||
|
})
|
||||||
|
const _settings = ref({
|
||||||
|
checkForUpdate: appSettings.checkForUpdate,
|
||||||
|
useEncryption: appSettings.useEncryption,
|
||||||
|
restrictRegistration: appSettings.restrictRegistration,
|
||||||
|
restrictList: appSettings.restrictList,
|
||||||
|
restrictRule: appSettings.restrictRule,
|
||||||
|
disableRegistration: appSettings.disableRegistration,
|
||||||
|
enableSso: appSettings.enableSso,
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves a setting on the backend
|
* Saves a setting on the backend
|
||||||
@ -24,9 +37,46 @@
|
|||||||
* @param {any} value
|
* @param {any} value
|
||||||
*/
|
*/
|
||||||
function saveSetting(setting, value) {
|
function saveSetting(setting, value) {
|
||||||
|
fieldErrors.value[setting] = null
|
||||||
|
|
||||||
appSettingService.update(setting, value).then(response => {
|
appSettingService.update(setting, value).then(response => {
|
||||||
|
appSettings[setting] = value
|
||||||
useNotifyStore().success({ type: 'is-success', text: trans('settings.forms.setting_saved') })
|
useNotifyStore().success({ type: 'is-success', text: trans('settings.forms.setting_saved') })
|
||||||
})
|
})
|
||||||
|
.catch(error => {
|
||||||
|
if( error.response.status === 422 ) {
|
||||||
|
fieldErrors.value[setting] = error.response.data.message
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
notify.error(error);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a setting on the backend
|
||||||
|
* @param {string} preference
|
||||||
|
* @param {any} value
|
||||||
|
*/
|
||||||
|
function saveOrDeleteSetting(setting, value) {
|
||||||
|
if (value == '') {
|
||||||
|
fieldErrors.value[setting] = null
|
||||||
|
|
||||||
|
appSettingService.delete(setting, { returnError: true }).then(response => {
|
||||||
|
appSettings[setting] = ''
|
||||||
|
useNotifyStore().success({ type: 'is-success', text: trans('settings.forms.setting_saved') })
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
// appSettings[setting] = oldValue
|
||||||
|
|
||||||
|
if( error.response.status !== 404 ) {
|
||||||
|
notify.error(error);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
saveSetting(setting, value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,7 +97,23 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(async () => {
|
||||||
|
appSettingService.get({ returnError: true })
|
||||||
|
.then(response => {
|
||||||
|
// we reset those two because they are not registered on server side
|
||||||
|
// in order to be able to set them to blank
|
||||||
|
_settings.value.restrictList = ''
|
||||||
|
_settings.value.restrictRule = ''
|
||||||
|
|
||||||
|
response.data.forEach(setting => {
|
||||||
|
appSettings[setting.key] = setting.value
|
||||||
|
_settings.value[setting.key] = setting.value
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
notify.alert({ text: trans('errors.data_cannot_be_refreshed_from_server') })
|
||||||
|
})
|
||||||
|
|
||||||
systemService.getSystemInfos({returnError: true}).then(response => {
|
systemService.getSystemInfos({returnError: true}).then(response => {
|
||||||
infos.value = response.data.common
|
infos.value = response.data.common
|
||||||
})
|
})
|
||||||
@ -66,7 +132,7 @@
|
|||||||
<form>
|
<form>
|
||||||
<h4 class="title is-4 pt-4 has-text-grey-light">{{ $t('settings.general') }}</h4>
|
<h4 class="title is-4 pt-4 has-text-grey-light">{{ $t('settings.general') }}</h4>
|
||||||
<!-- Check for update -->
|
<!-- Check for update -->
|
||||||
<FormCheckbox v-model="appSettings.checkForUpdate" @update:model-value="val => saveSetting('checkForUpdate', val)" fieldName="checkForUpdate" label="commons.check_for_update" help="commons.check_for_update_help" />
|
<FormCheckbox v-model="_settings.checkForUpdate" @update:model-value="val => saveSetting('checkForUpdate', val)" fieldName="checkForUpdate" label="commons.check_for_update" help="commons.check_for_update_help" />
|
||||||
<VersionChecker />
|
<VersionChecker />
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<!-- <h5 class="title is-5">{{ $t('settings.security') }}</h5> -->
|
<!-- <h5 class="title is-5">{{ $t('settings.security') }}</h5> -->
|
||||||
@ -86,12 +152,18 @@
|
|||||||
</div>
|
</div>
|
||||||
<h4 class="title is-4 pt-4 has-text-grey-light">{{ $t('settings.security') }}</h4>
|
<h4 class="title is-4 pt-4 has-text-grey-light">{{ $t('settings.security') }}</h4>
|
||||||
<!-- protect db -->
|
<!-- protect db -->
|
||||||
<FormCheckbox v-model="appSettings.useEncryption" @update:model-value="val => saveSetting('useEncryption', val)" fieldName="useEncryption" label="admin.forms.use_encryption.label" help="admin.forms.use_encryption.help" />
|
<FormCheckbox v-model="_settings.useEncryption" @update:model-value="val => saveSetting('useEncryption', val)" fieldName="useEncryption" label="admin.forms.use_encryption.label" help="admin.forms.use_encryption.help" />
|
||||||
<h4 class="title is-4 pt-4 has-text-grey-light">{{ $t('admin.registrations') }}</h4>
|
<h4 class="title is-4 pt-4 has-text-grey-light">{{ $t('admin.registrations') }}</h4>
|
||||||
|
<!-- restrict registration -->
|
||||||
|
<FormCheckbox v-model="_settings.restrictRegistration" @update:model-value="val => saveSetting('restrictRegistration', val)" fieldName="restrictRegistration" :isDisabled="appSettings.disableRegistration" label="admin.forms.restrict_registration.label" help="admin.forms.restrict_registration.help" />
|
||||||
|
<!-- restrict list -->
|
||||||
|
<FormField v-model="_settings.restrictList" @change:model-value="val => saveOrDeleteSetting('restrictList', val)" :fieldError="fieldErrors.restrictList" fieldName="restrictList" :isDisabled="!appSettings.restrictRegistration || appSettings.disableRegistration" label="admin.forms.restrict_list.label" help="admin.forms.restrict_list.help" :isIndented="true" />
|
||||||
|
<!-- restrict rule -->
|
||||||
|
<FormField v-model="_settings.restrictRule" @change:model-value="val => saveOrDeleteSetting('restrictRule', val)" :fieldError="fieldErrors.restrictRule" fieldName="restrictRule" :isDisabled="!appSettings.restrictRegistration || appSettings.disableRegistration" label="admin.forms.restrict_rule.label" help="admin.forms.restrict_rule.help" :isIndented="true" leftIcon="slash" rightIcon="slash" />
|
||||||
<!-- disable registration -->
|
<!-- disable registration -->
|
||||||
<FormCheckbox v-model="appSettings.disableRegistration" @update:model-value="val => saveSetting('disableRegistration', val)" fieldName="disableRegistration" label="admin.forms.disable_registration.label" help="admin.forms.disable_registration.help" />
|
<FormCheckbox v-model="_settings.disableRegistration" @update:model-value="val => saveSetting('disableRegistration', val)" fieldName="disableRegistration" label="admin.forms.disable_registration.label" help="admin.forms.disable_registration.help" />
|
||||||
<!-- disable SSO registration -->
|
<!-- disable SSO registration -->
|
||||||
<FormCheckbox v-model="appSettings.enableSso" @update:model-value="val => saveSetting('enableSso', val)" fieldName="enableSso" label="admin.forms.enable_sso.label" help="admin.forms.enable_sso.help" />
|
<FormCheckbox v-model="_settings.enableSso" @update:model-value="val => saveSetting('enableSso', val)" fieldName="enableSso" label="admin.forms.enable_sso.label" help="admin.forms.enable_sso.help" />
|
||||||
</form>
|
</form>
|
||||||
<h4 class="title is-4 pt-5 has-text-grey-light">{{ $t('commons.environment') }}</h4>
|
<h4 class="title is-4 pt-5 has-text-grey-light">{{ $t('commons.environment') }}</h4>
|
||||||
<div v-if="infos" class="about-debug box is-family-monospace is-size-7">
|
<div v-if="infos" class="about-debug box is-family-monospace is-size-7">
|
||||||
|
@ -65,9 +65,21 @@
|
|||||||
'security_devices_succesfully_revoked' => 'User\'s security devices successfully revoked',
|
'security_devices_succesfully_revoked' => 'User\'s security devices successfully revoked',
|
||||||
'forms' => [
|
'forms' => [
|
||||||
'use_encryption' => [
|
'use_encryption' => [
|
||||||
'label' => 'Protect sensible data',
|
'label' => 'Protect sensitive data',
|
||||||
'help' => 'Sensitive data, the 2FA secrets and emails, are stored encrypted in database. Be sure to backup the APP_KEY value of your .env file (or the whole file) as it serves as key encryption. There is no way to decypher encrypted data without this key.',
|
'help' => 'Sensitive data, the 2FA secrets and emails, are stored encrypted in database. Be sure to backup the APP_KEY value of your .env file (or the whole file) as it serves as key encryption. There is no way to decypher encrypted data without this key.',
|
||||||
],
|
],
|
||||||
|
'restrict_registration' => [
|
||||||
|
'label' => 'Restrict registration',
|
||||||
|
'help' => 'Make registration only available to a limited range of email addresses. Both rules can be used simultaneously.',
|
||||||
|
],
|
||||||
|
'restrict_list' => [
|
||||||
|
'label' => 'Filtering list',
|
||||||
|
'help' => 'Emails in this list will be allowed to register. Separate addresses with a pipe ("|")',
|
||||||
|
],
|
||||||
|
'restrict_rule' => [
|
||||||
|
'label' => 'Filtering rule',
|
||||||
|
'help' => 'Emails matching this regular expression will be allowed to register',
|
||||||
|
],
|
||||||
'disable_registration' => [
|
'disable_registration' => [
|
||||||
'label' => 'Disable registration',
|
'label' => 'Disable registration',
|
||||||
'help' => 'Prevent new user registration. This affects SSO as well, so new SSO users won\'t be able to sign on',
|
'help' => 'Prevent new user registration. This affects SSO as well, so new SSO users won\'t be able to sign on',
|
||||||
|
@ -170,6 +170,8 @@
|
|||||||
],
|
],
|
||||||
'email' => [
|
'email' => [
|
||||||
'exists' => 'No account found using this email.',
|
'exists' => 'No account found using this email.',
|
||||||
|
'ComplyWithEmailRestrictionPolicy' => 'This email address does not comply with the registration policy',
|
||||||
|
'IsValidEmailList' => 'All emails must be valid and separated with a pipe'
|
||||||
],
|
],
|
||||||
'secret' => [
|
'secret' => [
|
||||||
'isBase32Encoded' => 'The :attribute must be a base32 encoded string.',
|
'isBase32Encoded' => 'The :attribute must be a base32 encoded string.',
|
||||||
|
@ -21,8 +21,16 @@ class RegisterControllerTest extends FeatureTestCase
|
|||||||
|
|
||||||
private const EMAIL = 'johndoe@example.org';
|
private const EMAIL = 'johndoe@example.org';
|
||||||
|
|
||||||
|
private const EMAIL_NOT_IN_FILTERING_LIST = 'jane@example.org';
|
||||||
|
|
||||||
|
private const EMAIL_EXCLUDED_BY_FILTERING_RULE = 'johndoe@anywhere.org';
|
||||||
|
|
||||||
private const PASSWORD = 'password';
|
private const PASSWORD = 'password';
|
||||||
|
|
||||||
|
private const EMAIL_FILTERING_LIST = 'johndoe@example.org|johndoe@test.org|johndoe@anywhere.org';
|
||||||
|
|
||||||
|
private const EMAIL_FILTERING_RULE = '^[A-Za-z0-9._%+-]+@example\.org';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
*/
|
*/
|
||||||
@ -147,4 +155,112 @@ public function test_register_is_forbidden_when_registration_is_disabled()
|
|||||||
])
|
])
|
||||||
->assertStatus(403);
|
->assertStatus(403);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function test_register_succeeds_when_email_is_in_restricted_list()
|
||||||
|
{
|
||||||
|
Settings::set('restrictRegistration', true);
|
||||||
|
Settings::set('restrictList', self::EMAIL_FILTERING_LIST);
|
||||||
|
Settings::set('restrictRule', '');
|
||||||
|
|
||||||
|
$this->json('POST', '/user', [
|
||||||
|
'name' => self::USERNAME,
|
||||||
|
'email' => self::EMAIL,
|
||||||
|
'password' => self::PASSWORD,
|
||||||
|
'password_confirmation' => self::PASSWORD,
|
||||||
|
])
|
||||||
|
->assertStatus(201);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function test_register_fails_when_email_is_not_in_restricted_list()
|
||||||
|
{
|
||||||
|
Settings::set('restrictRegistration', true);
|
||||||
|
Settings::set('restrictList', self::EMAIL_FILTERING_LIST);
|
||||||
|
Settings::set('restrictRule', '');
|
||||||
|
|
||||||
|
$this->json('POST', '/user', [
|
||||||
|
'name' => self::USERNAME,
|
||||||
|
'email' => self::EMAIL_NOT_IN_FILTERING_LIST,
|
||||||
|
'password' => self::PASSWORD,
|
||||||
|
'password_confirmation' => self::PASSWORD,
|
||||||
|
])
|
||||||
|
->assertStatus(422);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function test_register_succeeds_when_email_matchs_filtering_rule()
|
||||||
|
{
|
||||||
|
Settings::set('restrictRegistration', true);
|
||||||
|
Settings::set('restrictList', '');
|
||||||
|
Settings::set('restrictRule', self::EMAIL_FILTERING_RULE);
|
||||||
|
|
||||||
|
$this->json('POST', '/user', [
|
||||||
|
'name' => self::USERNAME,
|
||||||
|
'email' => self::EMAIL,
|
||||||
|
'password' => self::PASSWORD,
|
||||||
|
'password_confirmation' => self::PASSWORD,
|
||||||
|
])
|
||||||
|
->assertStatus(201);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function test_register_fails_when_email_does_not_match_filtering_rule()
|
||||||
|
{
|
||||||
|
Settings::set('restrictRegistration', true);
|
||||||
|
Settings::set('restrictList', '');
|
||||||
|
Settings::set('restrictRule', self::EMAIL_FILTERING_RULE);
|
||||||
|
|
||||||
|
$this->json('POST', '/user', [
|
||||||
|
'name' => self::USERNAME,
|
||||||
|
'email' => self::EMAIL_EXCLUDED_BY_FILTERING_RULE,
|
||||||
|
'password' => self::PASSWORD,
|
||||||
|
'password_confirmation' => self::PASSWORD,
|
||||||
|
])
|
||||||
|
->assertStatus(422);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function test_register_succeeds_when_email_is_allowed_by_list_over_regex()
|
||||||
|
{
|
||||||
|
Settings::set('restrictRegistration', true);
|
||||||
|
Settings::set('restrictList', self::EMAIL_FILTERING_LIST);
|
||||||
|
Settings::set('restrictRule', self::EMAIL_FILTERING_RULE);
|
||||||
|
|
||||||
|
$this->json('POST', '/user', [
|
||||||
|
'name' => self::USERNAME,
|
||||||
|
'email' => self::EMAIL_EXCLUDED_BY_FILTERING_RULE,
|
||||||
|
'password' => self::PASSWORD,
|
||||||
|
'password_confirmation' => self::PASSWORD,
|
||||||
|
])
|
||||||
|
->assertStatus(201);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function test_register_succeeds_when_email_is_allowed_by_regex_over_list()
|
||||||
|
{
|
||||||
|
Settings::set('restrictRegistration', true);
|
||||||
|
Settings::set('restrictList', self::EMAIL_FILTERING_LIST);
|
||||||
|
Settings::set('restrictRule', self::EMAIL_FILTERING_RULE);
|
||||||
|
|
||||||
|
$this->json('POST', '/user', [
|
||||||
|
'name' => self::USERNAME,
|
||||||
|
'email' => self::EMAIL_NOT_IN_FILTERING_LIST,
|
||||||
|
'password' => self::PASSWORD,
|
||||||
|
'password_confirmation' => self::PASSWORD,
|
||||||
|
])
|
||||||
|
->assertStatus(201);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user