Add a option for requiring player name when register
This commit is contained in:
parent
939d71923b
commit
4a72442fdb
|
|
@ -172,6 +172,7 @@ class AdminController extends Controller
|
|||
});
|
||||
|
||||
$form->checkbox('user_can_register')->label();
|
||||
$form->checkbox('register_with_player_name')->label();
|
||||
$form->checkbox('require_verification')->label();
|
||||
|
||||
$form->text('regs_per_ip');
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use Cache;
|
|||
use Session;
|
||||
use App\Events;
|
||||
use App\Models\User;
|
||||
use App\Models\Player;
|
||||
use App\Mail\ForgotPassword;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
|
@ -91,23 +92,33 @@ class AuthController extends Controller
|
|||
|
||||
public function handleRegister(Request $request)
|
||||
{
|
||||
$data = $this->validate($request, [
|
||||
'email' => 'required|email|unique:users',
|
||||
'password' => 'required|min:8|max:32',
|
||||
'nickname' => 'required|no_special_chars|max:255',
|
||||
'captcha' => 'required'.(app()->environment('testing') ? '' : '|captcha')
|
||||
]);
|
||||
|
||||
if (! option('user_can_register')) {
|
||||
return json(trans('auth.register.close'), 7);
|
||||
}
|
||||
|
||||
$rule = option('register_with_player_name') ?
|
||||
['player_name' => 'required|player_name|min:'.option('player_name_length_min').'|max:'.option('player_name_length_max')] :
|
||||
['nickname' => 'required|no_special_chars|max:255'];
|
||||
$data = $this->validate($request, array_merge([
|
||||
'email' => 'required|email|unique:users',
|
||||
'password' => 'required|min:8|max:32',
|
||||
'captcha' => 'required'.(app()->environment('testing') ? '' : '|captcha')
|
||||
], $rule));
|
||||
|
||||
if (option('register_with_player_name')) {
|
||||
event(new Events\CheckPlayerExists($request->get('player_name')));
|
||||
|
||||
if (Player::where('player_name', $request->get('player_name'))->first()) {
|
||||
return json(trans('user.player.add.repeated'), 2);
|
||||
}
|
||||
}
|
||||
|
||||
// If amount of registered accounts of IP is more than allowed amounts,
|
||||
// reject the registration.
|
||||
if (User::where('ip', Utils::getClientIp())->count() < option('regs_per_ip')) {
|
||||
$user = new User;
|
||||
$user->email = $data['email'];
|
||||
$user->nickname = $data['nickname'];
|
||||
$user->nickname = $data[option('register_with_player_name') ? 'player_name' : 'nickname'];
|
||||
$user->score = option('user_initial_score');
|
||||
$user->avatar = 0;
|
||||
$user->password = User::getEncryptedPwdFromEvent($data['password'], $user)
|
||||
|
|
@ -121,11 +132,22 @@ class AuthController extends Controller
|
|||
|
||||
event(new Events\UserRegistered($user));
|
||||
|
||||
if (option('register_with_player_name')) {
|
||||
$player = new Player;
|
||||
$player->uid = $user->uid;
|
||||
$player->player_name = $request->get('player_name');
|
||||
$player->preference = 'default';
|
||||
$player->last_modified = Utils::getTimeFormatted();
|
||||
$player->save();
|
||||
|
||||
event(new Events\PlayerWasAdded($player));
|
||||
}
|
||||
|
||||
Auth::login($user);
|
||||
|
||||
return json([
|
||||
'errno' => 0,
|
||||
'msg' => trans('auth.register.success')
|
||||
'errno' => 0,
|
||||
'msg' => trans('auth.register.success')
|
||||
]);
|
||||
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ return [
|
|||
'site_name' => 'Blessing Skin',
|
||||
'site_description' => 'Open-source PHP Minecraft Skin Hosting Service',
|
||||
'user_can_register' => 'true',
|
||||
'register_with_player_name' => 'true',
|
||||
'require_verification' => 'false',
|
||||
'regs_per_ip' => '3',
|
||||
'ip_get_method' => '0',
|
||||
|
|
|
|||
|
|
@ -32,6 +32,23 @@
|
|||
</div>
|
||||
|
||||
<div
|
||||
v-if="requirePlayer"
|
||||
class="form-group has-feedback"
|
||||
:title="$t('auth.player-name-intro')"
|
||||
data-placement="top"
|
||||
data-toggle="tooltip"
|
||||
>
|
||||
<input
|
||||
v-model="playerName"
|
||||
type="text"
|
||||
class="form-control"
|
||||
:placeholder="$t('auth.player-name')"
|
||||
ref="playerName"
|
||||
>
|
||||
<span class="glyphicon glyphicon-pencil form-control-feedback"></span>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="form-group has-feedback"
|
||||
:title="$t('auth.nickname-intro')"
|
||||
data-placement="top"
|
||||
|
|
@ -108,16 +125,18 @@ export default {
|
|||
password: '',
|
||||
confirm: '',
|
||||
nickname: '',
|
||||
playerName: '',
|
||||
captcha: '',
|
||||
time: Date.now(),
|
||||
infoMsg: '',
|
||||
warningMsg: '',
|
||||
pending: false
|
||||
pending: false,
|
||||
requirePlayer: __bs_data__.player
|
||||
}),
|
||||
methods: {
|
||||
async submit() {
|
||||
const {
|
||||
email, password, confirm, nickname, captcha
|
||||
email, password, confirm, playerName, nickname, captcha
|
||||
} = this;
|
||||
|
||||
if (!email) {
|
||||
|
|
@ -150,7 +169,13 @@ export default {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!nickname) {
|
||||
if (this.requirePlayer && !playerName) {
|
||||
this.infoMsg = this.$t('auth.emptyPlayerName');
|
||||
this.$refs.playerName.focus();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.requirePlayer && !nickname) {
|
||||
this.infoMsg = this.$t('auth.emptyNickname');
|
||||
this.$refs.nickname.focus();
|
||||
return;
|
||||
|
|
@ -165,7 +190,11 @@ export default {
|
|||
this.pending = true;
|
||||
const { errno, msg } = await this.$http.post(
|
||||
'/auth/register',
|
||||
{ email, password, nickname, captcha }
|
||||
Object.assign(
|
||||
{},
|
||||
{ email, password, captcha },
|
||||
this.requirePlayer ? { player_name: playerName } : { nickname }
|
||||
)
|
||||
);
|
||||
if (errno === 0) {
|
||||
swal({ type: 'success', text: msg });
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/* eslint-disable no-var */
|
||||
import 'core-js/fn/array/includes';
|
||||
import 'core-js/fn/array/find';
|
||||
import 'core-js/fn/object/assign';
|
||||
import 'core-js/fn/object/values';
|
||||
import 'core-js/fn/string/starts-with';
|
||||
import 'es6-promise/auto';
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import { swal } from '@/js/notify';
|
|||
|
||||
jest.mock('@/js/notify');
|
||||
|
||||
window.__bs_data__ = { player: false };
|
||||
|
||||
test('click to refresh captcha', () => {
|
||||
jest.spyOn(Date, 'now');
|
||||
const wrapper = mount(Register);
|
||||
|
|
@ -12,6 +14,16 @@ test('click to refresh captcha', () => {
|
|||
expect(Date.now).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
test('require player name', () => {
|
||||
window.__bs_data__ = { player: true };
|
||||
|
||||
const wrapper = mount(Register);
|
||||
expect(wrapper.findAll('[type="text"]').at(0).attributes())
|
||||
.toHaveProperty('placeholder', 'auth.player-name');
|
||||
|
||||
window.__bs_data__ = { player: false };
|
||||
});
|
||||
|
||||
test('register', async () => {
|
||||
jest.spyOn(Date, 'now');
|
||||
Vue.prototype.$http.post
|
||||
|
|
@ -81,3 +93,32 @@ test('register', async () => {
|
|||
jest.runAllTimers();
|
||||
expect(swal).toBeCalledWith({ type: 'success', text: 'ok' });
|
||||
});
|
||||
|
||||
test('register with player name', async () => {
|
||||
window.__bs_data__ = { player: true };
|
||||
Vue.prototype.$http.post.mockResolvedValue({ errno: 0, msg: 'ok' });
|
||||
const wrapper = mount(Register);
|
||||
const button = wrapper.find('button');
|
||||
const info = wrapper.find('.callout-info');
|
||||
wrapper.find('[type="email"]').setValue('a@b.c');
|
||||
wrapper.findAll('[type="password"]').at(0).setValue('12345678');
|
||||
wrapper.findAll('[type="password"]').at(1).setValue('12345678');
|
||||
wrapper.findAll('[type="text"]').at(1).setValue('captcha');
|
||||
|
||||
button.trigger('click');
|
||||
expect(Vue.prototype.$http.post).not.toBeCalled();
|
||||
expect(info.text()).toBe('auth.emptyPlayerName');
|
||||
|
||||
wrapper.findAll('[type="text"]').at(0).setValue('abc');
|
||||
button.trigger('click');
|
||||
await wrapper.vm.$nextTick();
|
||||
expect(Vue.prototype.$http.post).toBeCalledWith(
|
||||
'/auth/register',
|
||||
{
|
||||
email: 'a@b.c',
|
||||
password: '12345678',
|
||||
player_name: 'abc',
|
||||
captcha: 'captcha'
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ auth:
|
|||
emptyConfirmPwd: Empty confirming password.
|
||||
invalidConfirmPwd: Confirming password is not equal with password.
|
||||
emptyNickname: Empty nickname.
|
||||
emptyPlayerName: Empty player name.
|
||||
register: Register
|
||||
registering: Registering
|
||||
send: Send
|
||||
|
|
@ -18,6 +19,7 @@ auth:
|
|||
reset: Reset
|
||||
resetting: Resetting
|
||||
nickname: Nickname
|
||||
player-name: Minecraft player name
|
||||
email: Email
|
||||
identification: Email or player name
|
||||
password: Password
|
||||
|
|
@ -28,6 +30,7 @@ auth:
|
|||
keep: Remember me
|
||||
repeat-pwd: Repeat your password
|
||||
nickname-intro: Whatever you like expect special characters
|
||||
player-name-intro: Player name in Minecraft, can be changed later
|
||||
register-button: Register
|
||||
forgot:
|
||||
login-link: I do remember it
|
||||
|
|
|
|||
|
|
@ -75,6 +75,9 @@ general:
|
|||
user_can_register:
|
||||
title: Open Registration
|
||||
label: Everyone is allowed to register.
|
||||
register_with_player_name:
|
||||
title: Register with Player Name
|
||||
label: Require Minecraft's player name when user register
|
||||
require_verification:
|
||||
title: Account Verification
|
||||
label: Users must verify their email address first.
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ auth:
|
|||
emptyConfirmPwd: 确认密码不能为空
|
||||
invalidConfirmPwd: 密码和确认的密码不一样诶?
|
||||
emptyNickname: 你还没有填写昵称哦
|
||||
emptyPlayerName: 你还没有填写角色名哦
|
||||
register: 注册
|
||||
registering: 注册中
|
||||
send: 发送
|
||||
|
|
@ -19,6 +20,7 @@ auth:
|
|||
resetting: 重置中
|
||||
nickname: 昵称
|
||||
email: Email
|
||||
player-name: 游戏内角色名
|
||||
identification: Email 或角色名
|
||||
password: 密码
|
||||
captcha: 请输入验证码
|
||||
|
|
@ -28,6 +30,7 @@ auth:
|
|||
keep: 记住我
|
||||
repeat-pwd: 重复密码
|
||||
nickname-intro: 昵称可使用汉字,不可包含特殊字符
|
||||
player-name-intro: 游戏内的角色名,注册后可修改
|
||||
register-button: 注册
|
||||
forgot:
|
||||
login-link: 我又想起来了
|
||||
|
|
|
|||
|
|
@ -75,6 +75,9 @@ general:
|
|||
user_can_register:
|
||||
title: 开放注册
|
||||
label: 任何人都可以注册
|
||||
register_with_player_name:
|
||||
title: 使用角色名注册
|
||||
label: 注册时要求填写游戏内角色名
|
||||
require_verification:
|
||||
title: 邮箱验证
|
||||
label: 用户必须验证邮箱后才能使用皮肤托管等功能
|
||||
|
|
|
|||
|
|
@ -18,4 +18,14 @@
|
|||
</div>
|
||||
<!-- /.register-box -->
|
||||
|
||||
<script>
|
||||
Object.defineProperty(window, '__bs_data__', {
|
||||
get: function () {
|
||||
return Object.freeze({
|
||||
player: {{ option('register_with_player_name') ? 'true' : 'false' }},
|
||||
})
|
||||
},
|
||||
configurable: false
|
||||
})
|
||||
</script>
|
||||
@endsection
|
||||
|
|
|
|||
|
|
@ -247,19 +247,82 @@ class AuthControllerTest extends TestCase
|
|||
[
|
||||
'email' => 'a@b.c',
|
||||
'password' => str_random(33)
|
||||
],
|
||||
['X-Requested-With' => 'XMLHttpRequest']
|
||||
]
|
||||
)->assertJson([
|
||||
'errno' => 1,
|
||||
'msg' => trans('validation.max.string', ['attribute' => 'password', 'max' => 32])
|
||||
]);
|
||||
|
||||
// The register_with_player_name option is set to true by default.
|
||||
// Should return a warning if `player_name` is empty
|
||||
$this->postJson(
|
||||
'/auth/register',
|
||||
[
|
||||
'email' => 'a@b.c',
|
||||
'password' => '12345678',
|
||||
'captcha' => 'a'
|
||||
]
|
||||
)->assertJson([
|
||||
'errno' => 1,
|
||||
'msg' => trans('validation.required', ['attribute' => 'Player Name'])
|
||||
]);
|
||||
|
||||
// Should return a warning if `player_name` is invalid
|
||||
option(['player_name_rule' => 'official']);
|
||||
$this->postJson(
|
||||
'/auth/register',
|
||||
[
|
||||
'email' => 'a@b.c',
|
||||
'password' => '12345678',
|
||||
'player_name' => '角色名',
|
||||
'captcha' => 'a'
|
||||
]
|
||||
)->assertJson([
|
||||
'errno' => 1,
|
||||
'msg' => trans('validation.player_name', ['attribute' => 'Player Name'])
|
||||
]);
|
||||
|
||||
// Should return a warning if `player_name` is too long
|
||||
$this->postJson(
|
||||
'/auth/register',
|
||||
[
|
||||
'email' => 'a@b.c',
|
||||
'password' => '12345678',
|
||||
'player_name' => str_random(option('player_name_length_max') + 10),
|
||||
'captcha' => 'a'
|
||||
]
|
||||
)->assertJson([
|
||||
'errno' => 1,
|
||||
'msg' => trans('validation.max.string', [
|
||||
'attribute' => 'Player Name',
|
||||
'max' => option('player_name_length_max')
|
||||
])
|
||||
]);
|
||||
|
||||
// Existed player
|
||||
$player = factory(Player::class)->create();
|
||||
$this->postJson(
|
||||
'/auth/register',
|
||||
[
|
||||
'email' => 'a@b.c',
|
||||
'password' => '12345678',
|
||||
'player_name' => $player->player_name,
|
||||
'captcha' => 'a'
|
||||
]
|
||||
)->assertJson([
|
||||
'errno' => 2,
|
||||
'msg' => trans('user.player.add.repeated')
|
||||
]);
|
||||
|
||||
option(['register_with_player_name' => false]);
|
||||
|
||||
// Should return a warning if `nickname` is empty
|
||||
$this->postJson(
|
||||
'/auth/register',
|
||||
[
|
||||
'email' => 'a@b.c',
|
||||
'password' => '12345678'
|
||||
'password' => '12345678',
|
||||
'captcha' => 'a'
|
||||
],
|
||||
['X-Requested-With' => 'XMLHttpRequest']
|
||||
)->assertJson([
|
||||
|
|
@ -273,7 +336,8 @@ class AuthControllerTest extends TestCase
|
|||
[
|
||||
'email' => 'a@b.c',
|
||||
'password' => '12345678',
|
||||
'nickname' => '\\'
|
||||
'nickname' => '\\',
|
||||
'captcha' => 'a'
|
||||
],
|
||||
['X-Requested-With' => 'XMLHttpRequest']
|
||||
)->assertJson([
|
||||
|
|
@ -287,7 +351,8 @@ class AuthControllerTest extends TestCase
|
|||
[
|
||||
'email' => 'a@b.c',
|
||||
'password' => '12345678',
|
||||
'nickname' => str_random(256)
|
||||
'nickname' => str_random(256),
|
||||
'captcha' => 'a'
|
||||
],
|
||||
['X-Requested-With' => 'XMLHttpRequest']
|
||||
)->assertJson([
|
||||
|
|
@ -370,6 +435,19 @@ class AuthControllerTest extends TestCase
|
|||
'permission' => User::NORMAL
|
||||
]);
|
||||
$this->assertAuthenticated();
|
||||
|
||||
// Require player name
|
||||
option(['register_with_player_name' => false]);
|
||||
$this->postJson(
|
||||
'/auth/register',
|
||||
[
|
||||
'email' => 'a@b.c',
|
||||
'password' => '12345678',
|
||||
'player_name' => 'name',
|
||||
'captcha' => 'a'
|
||||
]
|
||||
);
|
||||
$this->assertNotNull(Player::where('player_name', 'name'));
|
||||
}
|
||||
|
||||
public function testForgot()
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user