diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php
index 346332b5..3d2f9c05 100644
--- a/app/Http/Controllers/AdminController.php
+++ b/app/Http/Controllers/AdminController.php
@@ -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');
diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php
index 6e1ac4ed..ae568978 100644
--- a/app/Http/Controllers/AuthController.php
+++ b/app/Http/Controllers/AuthController.php
@@ -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 {
diff --git a/config/options.php b/config/options.php
index dccfc3b6..72ea224a 100644
--- a/config/options.php
+++ b/config/options.php
@@ -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',
diff --git a/resources/assets/src/components/auth/Register.vue b/resources/assets/src/components/auth/Register.vue
index e35394b2..75a7e2c8 100644
--- a/resources/assets/src/components/auth/Register.vue
+++ b/resources/assets/src/components/auth/Register.vue
@@ -32,6 +32,23 @@
+
+
+
+ {
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'
+ }
+ );
+});
diff --git a/resources/lang/en/front-end.yml b/resources/lang/en/front-end.yml
index bad54087..aabfd20a 100644
--- a/resources/lang/en/front-end.yml
+++ b/resources/lang/en/front-end.yml
@@ -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
diff --git a/resources/lang/en/options.yml b/resources/lang/en/options.yml
index e797b0eb..faa63bc0 100644
--- a/resources/lang/en/options.yml
+++ b/resources/lang/en/options.yml
@@ -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.
diff --git a/resources/lang/zh_CN/front-end.yml b/resources/lang/zh_CN/front-end.yml
index 551d8bf7..fc54efdf 100644
--- a/resources/lang/zh_CN/front-end.yml
+++ b/resources/lang/zh_CN/front-end.yml
@@ -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: 我又想起来了
diff --git a/resources/lang/zh_CN/options.yml b/resources/lang/zh_CN/options.yml
index ea62b69c..d5050405 100644
--- a/resources/lang/zh_CN/options.yml
+++ b/resources/lang/zh_CN/options.yml
@@ -75,6 +75,9 @@ general:
user_can_register:
title: 开放注册
label: 任何人都可以注册
+ register_with_player_name:
+ title: 使用角色名注册
+ label: 注册时要求填写游戏内角色名
require_verification:
title: 邮箱验证
label: 用户必须验证邮箱后才能使用皮肤托管等功能
diff --git a/resources/views/auth/register.tpl b/resources/views/auth/register.tpl
index a0dae36d..a5ab95eb 100644
--- a/resources/views/auth/register.tpl
+++ b/resources/views/auth/register.tpl
@@ -18,4 +18,14 @@
+
@endsection
diff --git a/tests/AuthControllerTest.php b/tests/AuthControllerTest.php
index 16593d64..f7cd5712 100644
--- a/tests/AuthControllerTest.php
+++ b/tests/AuthControllerTest.php
@@ -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()