216 lines
7.6 KiB
PHP
216 lines
7.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace app\api\controller;
|
|
|
|
use app\common\facade\Token;
|
|
use app\common\library\Auth as UserAuth;
|
|
use app\common\model\User;
|
|
use app\common\service\MobileAuthDeviceService;
|
|
use ba\Random;
|
|
use support\think\Db;
|
|
use Webman\Http\Request;
|
|
use support\Response;
|
|
|
|
class Auth extends MobileBase
|
|
{
|
|
protected array $noNeedLogin = ['register', 'login', 'refreshToken', 'userRegister', 'userLogin', 'tokenRefresh'];
|
|
protected array $noNeedAuthToken = ['register', 'refreshToken', 'userRegister', 'tokenRefresh'];
|
|
|
|
public function userRegister(Request $request): Response
|
|
{
|
|
$response = $this->initializeMobile($request);
|
|
if ($response !== null) {
|
|
return $response;
|
|
}
|
|
|
|
$username = trim((string) $request->post('username', ''));
|
|
if ($username === '') {
|
|
$username = trim((string) $request->post('account', ''));
|
|
}
|
|
$password = (string) $request->post('password', '');
|
|
$inviteCode = trim((string) $request->post('invite_code', ''));
|
|
|
|
if ($username === '' || $password === '') {
|
|
return $this->mobileError(1001, 'Missing parameters');
|
|
}
|
|
if ($inviteCode === '') {
|
|
return $this->mobileError(1001, 'Invite code required');
|
|
}
|
|
if (!preg_match('/^1[3-9]\d{9}$/', $username)) {
|
|
return $this->mobileError(1003, 'Please enter the correct mobile number');
|
|
}
|
|
|
|
$phone = $username;
|
|
$email = '';
|
|
|
|
if (User::where('username', $username)->find() || User::where('phone', $username)->find()) {
|
|
return $this->mobileError(2003, 'Account already registered', [
|
|
'already_registered' => true,
|
|
]);
|
|
}
|
|
|
|
$extend = [];
|
|
$inviterAdmin = Db::name('admin')->field(['id', 'channel_id'])->where('invite_code', $inviteCode)->find();
|
|
if (!$inviterAdmin) {
|
|
return $this->mobileError(2002, 'Invite code does not exist');
|
|
}
|
|
$extend['register_invite_code'] = $inviteCode;
|
|
$extend['admin_id'] = $inviterAdmin['id'];
|
|
$channelId = $inviterAdmin['channel_id'] ?? null;
|
|
if ($channelId === null || $channelId === '' || (int) $channelId <= 0) {
|
|
return $this->mobileError(2002, 'Invite code not bound to channel');
|
|
}
|
|
$extend['channel_id'] = (int) $channelId;
|
|
$channelStatus = Db::name('channel')->where('id', (int) $channelId)->value('status');
|
|
if (intval($channelStatus) !== 1) {
|
|
return $this->mobileError(2002, 'Channel disabled');
|
|
}
|
|
|
|
$registered = $this->auth->register($username, $password, $phone, $email, 1, $extend);
|
|
if (!$registered) {
|
|
$dup = $this->auth->getRegisterDuplicateKind();
|
|
if ($dup === 'username' || $dup === 'email' || $dup === 'phone') {
|
|
return $this->mobileError(2003, 'Account already registered', [
|
|
'already_registered' => true,
|
|
]);
|
|
}
|
|
return $this->mobileError(2000, (string) $this->auth->getError());
|
|
}
|
|
|
|
$loggedIn = $this->auth->login($username, $password, true);
|
|
if (!$loggedIn) {
|
|
return $this->mobileError(2000, 'Registered successfully but login failed');
|
|
}
|
|
|
|
$this->bindMobileDeviceSession($request);
|
|
|
|
return $this->mobileSuccess($this->buildLoginPayload());
|
|
}
|
|
|
|
public function userLogin(Request $request): Response
|
|
{
|
|
$response = $this->initializeMobile($request);
|
|
if ($response !== null) {
|
|
return $response;
|
|
}
|
|
|
|
$username = trim((string) $request->post('username', ''));
|
|
if ($username === '') {
|
|
$username = trim((string) $request->post('account', ''));
|
|
}
|
|
$password = (string) $request->post('password', '');
|
|
if ($username === '' || $password === '') {
|
|
return $this->mobileError(1001, 'Missing parameters');
|
|
}
|
|
|
|
$ok = $this->auth->login($username, $password, true);
|
|
if (!$ok) {
|
|
return $this->mobileError(1101, 'Incorrect account or password');
|
|
}
|
|
|
|
$this->bindMobileDeviceSession($request);
|
|
|
|
return $this->mobileSuccess($this->buildLoginPayload());
|
|
}
|
|
|
|
public function userLogout(Request $request): Response
|
|
{
|
|
$response = $this->initializeMobile($request);
|
|
if ($response !== null) {
|
|
return $response;
|
|
}
|
|
|
|
$refreshToken = trim((string) $request->post('refresh_token', ''));
|
|
if ($refreshToken === '') {
|
|
$refreshToken = trim((string) $request->post('refreshToken', ''));
|
|
}
|
|
|
|
if ($this->auth->isLogin()) {
|
|
$userId = (int) $this->auth->id;
|
|
if ($refreshToken === '') {
|
|
$refreshToken = $this->auth->getRefreshToken();
|
|
}
|
|
$this->auth->logout();
|
|
MobileAuthDeviceService::onUserLogout($userId);
|
|
}
|
|
|
|
if ($refreshToken !== '') {
|
|
Token::delete($refreshToken);
|
|
}
|
|
|
|
return $this->mobileSuccess();
|
|
}
|
|
|
|
public function tokenRefresh(Request $request): Response
|
|
{
|
|
$response = $this->initializeMobile($request);
|
|
if ($response !== null) {
|
|
return $response;
|
|
}
|
|
|
|
$refreshToken = trim((string) $request->post('refresh_token', ''));
|
|
if ($refreshToken === '') {
|
|
return $this->mobileError(1001, 'Missing parameters');
|
|
}
|
|
|
|
$tokenData = Token::get($refreshToken);
|
|
if (!$tokenData || $tokenData['type'] !== UserAuth::TOKEN_TYPE . '-refresh' || $tokenData['expire_time'] < time()) {
|
|
return $this->mobileError(1101, 'Login status has expired');
|
|
}
|
|
|
|
$authToken = trim((string) $request->header('auth-token', ''));
|
|
$userId = filter_var($tokenData['user_id'] ?? 0, FILTER_VALIDATE_INT);
|
|
if ($userId === false || $userId <= 0) {
|
|
return $this->mobileError(1101, 'Login status has expired');
|
|
}
|
|
$deviceError = MobileAuthDeviceService::validateUserDeviceSession($authToken, (int) $userId);
|
|
if ($deviceError !== null) {
|
|
return $this->mobileError(1101, $deviceError);
|
|
}
|
|
|
|
$newToken = Random::uuid();
|
|
Token::set($newToken, UserAuth::TOKEN_TYPE, (int) $userId, config('buildadmin.user_token_keep_time', 259200));
|
|
return $this->mobileSuccess([
|
|
'user-token' => $newToken,
|
|
'expires_in' => config('buildadmin.user_token_keep_time', 259200),
|
|
]);
|
|
}
|
|
|
|
private function bindMobileDeviceSession(Request $request): void
|
|
{
|
|
if (!$this->auth->isLogin()) {
|
|
return;
|
|
}
|
|
$authToken = trim((string) $request->header('auth-token', ''));
|
|
if ($authToken === '') {
|
|
return;
|
|
}
|
|
MobileAuthDeviceService::onUserLogin(
|
|
(int) $this->auth->id,
|
|
$authToken,
|
|
$this->auth->getToken(),
|
|
$this->auth->getRefreshToken()
|
|
);
|
|
}
|
|
|
|
private function buildLoginPayload(): array
|
|
{
|
|
$userInfo = $this->auth->getUserInfo();
|
|
return [
|
|
'user-token' => $userInfo['token'] ?? '',
|
|
'refresh_token' => $userInfo['refresh_token'] ?? '',
|
|
'expires_in' => config('buildadmin.user_token_keep_time', 259200),
|
|
'user' => [
|
|
'username' => $userInfo['username'] ?? '',
|
|
'uuid' => $userInfo['uuid'] ?? '',
|
|
'coin' => $userInfo['coin'] ?? '0.00',
|
|
'channel_id' => $userInfo['channel_id'] ?? null,
|
|
'risk_flags' => $userInfo['risk_flags'] ?? 0,
|
|
],
|
|
];
|
|
}
|
|
}
|
|
|