mirror of
https://github.com/kuaifan/dootask.git
synced 2026-09-10 14:08:57 +00:00
fix(auth): hide registration when disabled
This commit is contained in:
parent
826058b842
commit
cb60728711
@ -339,21 +339,25 @@ class UsersController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/users/reg/needinvite 是否需要邀请码
|
||||
* @api {get} api/users/reg/needinvite 注册状态
|
||||
*
|
||||
* @apiDescription 用于判断注册是否需要邀请码
|
||||
* @apiDescription 用于判断是否允许注册及是否需要邀请码
|
||||
* @apiVersion 1.0.0
|
||||
* @apiGroup users
|
||||
* @apiName reg__needinvite
|
||||
*
|
||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||
* @apiSuccess {Object} data 返回数据
|
||||
* @apiSuccess {Object} data 返回数据
|
||||
* @apiSuccess {Boolean} data.enabled 是否允许注册
|
||||
* @apiSuccess {Boolean} data.need 是否需要邀请码
|
||||
*/
|
||||
public function reg__needinvite()
|
||||
{
|
||||
$reg = Base::settingFind('system', 'reg', 'open');
|
||||
return Base::retSuccess('success', [
|
||||
'need' => Base::settingFind('system', 'reg') == 'invite'
|
||||
'enabled' => $reg !== 'close',
|
||||
'need' => $reg === 'invite',
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ negative:
|
||||
- 邀请码与「邀请同事加入项目」是两回事;这里指的是系统级开放注册的密钥
|
||||
- 邀请码只有一个全局值,不区分用户、不限次数、不过期
|
||||
- 验证不通过会直接拒绝,没有「邀请码错了几次锁定」的限制
|
||||
last_verified: v1.7.90
|
||||
last_verified: v1.8.89
|
||||
---
|
||||
|
||||
# 注册是否需要邀请码
|
||||
@ -39,9 +39,11 @@ DooTask 的注册方式由系统设置 `system.reg` 控制,共三档:
|
||||
- 注册时把这个字符串填到「邀请码」字段提交,后端比对 `Request.invite == setting.reg_invite`
|
||||
|
||||
## 接口判定
|
||||
前端可调 `api/users/reg/needinvite` 拿到 `{ need: true/false }`,据此决定登录页注册 tab 是否展示「邀请码」输入框:
|
||||
前端可调 `api/users/reg/needinvite` 拿到 `{ enabled: true/false, need: true/false }`,据此决定是否显示注册入口,以及注册表单是否展示「邀请码」输入框:
|
||||
- `enabled=false` → reg=close,隐藏注册入口;即使通过 `/login?type=reg` 直达也停留在登录表单
|
||||
- `enabled=true` → reg=open 或 reg=invite,显示注册入口
|
||||
- `need=true` → reg=invite,显示邀请码输入框
|
||||
- `need=false` → reg=open(reg=close 时注册入口本身就该隐藏)
|
||||
- `need=false` → reg=open 或 reg=close,以 `enabled` 为准
|
||||
|
||||
## 与「项目邀请加入」的区别
|
||||
- **本概念**:决定能否成为 DooTask 用户(账号级别)
|
||||
|
||||
@ -21,7 +21,7 @@ negative:
|
||||
- 注册方式为「邀请码」时必须填正确邀请码,否则报「请输入正确的邀请码」
|
||||
- 邮箱长度和密码长度都不能超过 32 个字符
|
||||
- 开启「注册需邮箱验证」时,注册后必须先验证邮箱才能登录
|
||||
last_verified: v1.7.90
|
||||
last_verified: v1.8.89
|
||||
---
|
||||
|
||||
# 注册账号
|
||||
@ -35,7 +35,7 @@ last_verified: v1.7.90
|
||||
|
||||
- **open(开放)**:直接填邮箱+密码即可注册
|
||||
- **invite(邀请码)**:除邮箱+密码外,还需填邀请码;可调 `api/users/reg/needinvite` 提前判断(详见 [[user-account.reg-need-invite.concept]])
|
||||
- **close(关闭)**:注册入口不可用,提示「未开放注册」
|
||||
- **close(关闭)**:登录页隐藏注册入口,直达 `/login?type=reg` 也停留在登录表单;直接提交注册接口时提示「未开放注册」
|
||||
|
||||
## 操作步骤
|
||||
1. 进入登录页,切到「注册」tab
|
||||
|
||||
@ -100,7 +100,7 @@
|
||||
<Button type="primary" :loading="loadIng > 0 || loginJump" size="large" long @click="onLogin">{{$L(loginText)}}</Button>
|
||||
|
||||
<div v-if="loginType=='reg'" class="login-switch">{{$L('已经有帐号?')}} <a href="javascript:void(0)" @click="loginType='login'">{{$L('登录帐号')}}</a></div>
|
||||
<div v-else class="login-switch">{{$L('还没有帐号?')}} <a href="javascript:void(0)" @click="loginType='reg'">{{$L('注册帐号')}}</a></div>
|
||||
<div v-else-if="registrationAvailable" class="login-switch">{{$L('还没有帐号?')}} <a href="javascript:void(0)" @click="loginType='reg'">{{$L('注册帐号')}}</a></div>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
@ -199,6 +199,7 @@ export default {
|
||||
invite: '',
|
||||
|
||||
needInvite: false,
|
||||
registrationAvailable: false,
|
||||
|
||||
privacyShow: false,
|
||||
}
|
||||
@ -225,7 +226,7 @@ export default {
|
||||
},
|
||||
|
||||
activated() {
|
||||
this.loginType = this.$route.query.type === 'reg' ? 'reg' : 'login'
|
||||
this.refreshRegistrationSetting();
|
||||
//
|
||||
this.getDemoAccount();
|
||||
},
|
||||
@ -284,20 +285,14 @@ export default {
|
||||
|
||||
watch: {
|
||||
'$route' ({query}) {
|
||||
if (query.type=='reg'){
|
||||
this.$nextTick(()=>{
|
||||
this.loginType = "reg"
|
||||
})
|
||||
if (this.routeName !== 'login') {
|
||||
return;
|
||||
}
|
||||
this.refreshRegistrationSetting(query.type === 'reg');
|
||||
},
|
||||
loginMode() {
|
||||
this.qrcodeRefresh()
|
||||
},
|
||||
loginType(val) {
|
||||
if (val == 'reg') {
|
||||
this.getNeedInvite();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
@ -321,13 +316,23 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
getNeedInvite() {
|
||||
this.$store.dispatch("call", {
|
||||
refreshRegistrationSetting(requestRegistration = this.$route.query.type === 'reg') {
|
||||
if (this.isNotServer()) {
|
||||
this.registrationAvailable = false;
|
||||
this.loginType = 'login';
|
||||
return Promise.resolve();
|
||||
}
|
||||
return this.$store.dispatch("call", {
|
||||
url: 'users/reg/needinvite',
|
||||
}).then(({data}) => {
|
||||
this.needInvite = !!data.need;
|
||||
// Older servers only return `need`; preserve their original registration behavior.
|
||||
this.registrationAvailable = typeof data.enabled === 'undefined' || !!data.enabled;
|
||||
this.loginType = requestRegistration && this.registrationAvailable ? 'reg' : 'login';
|
||||
}).catch(_ => {
|
||||
this.needInvite = false;
|
||||
this.registrationAvailable = false;
|
||||
this.loginType = 'login';
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ API 使用动态路由(见 `routes/web.php`),URL 段映射为控制器方
|
||||
| api/users/login/codejson | login__codejson() | get | 验证码json |
|
||||
| api/users/logout | logout() | get | 退出登录 |
|
||||
| api/users/token/expire | token__expire() | get | 查询 token 过期时间 |
|
||||
| api/users/reg/needinvite | reg__needinvite() | get | 是否需要邀请码 |
|
||||
| api/users/reg/needinvite | reg__needinvite() | get | 注册状态 |
|
||||
| api/users/info | info() | get | 获取我的信息 |
|
||||
| api/users/info/managed_departments | info__managed_departments() | get | 获取我可切换负责人视角的部门列表 |
|
||||
| api/users/info/departments | info__departments() | get | 获取我的部门列表 |
|
||||
|
||||
34
tests/Feature/RegistrationAvailabilityTest.php
Normal file
34
tests/Feature/RegistrationAvailabilityTest.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Module\Base;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Tests\TestCase;
|
||||
|
||||
class RegistrationAvailabilityTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
public function test_registration_status_reports_closed_registration(): void
|
||||
{
|
||||
Base::setting('system', ['reg' => 'close'], true);
|
||||
|
||||
$this->getJson('/api/users/reg/needinvite')
|
||||
->assertOk()
|
||||
->assertJsonPath('ret', 1)
|
||||
->assertJsonPath('data.enabled', false)
|
||||
->assertJsonPath('data.need', false);
|
||||
}
|
||||
|
||||
public function test_registration_status_reports_invite_registration(): void
|
||||
{
|
||||
Base::setting('system', ['reg' => 'invite'], true);
|
||||
|
||||
$this->getJson('/api/users/reg/needinvite')
|
||||
->assertOk()
|
||||
->assertJsonPath('ret', 1)
|
||||
->assertJsonPath('data.enabled', true)
|
||||
->assertJsonPath('data.need', true);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user