[admin] remove two-step authentication

This commit is contained in:
xiaomlove
2022-05-13 17:55:49 +08:00
parent 155d4ddcb6
commit a7d9a68db4
12 changed files with 70 additions and 38 deletions

View File

@@ -208,7 +208,9 @@ const api = {
pardonHrBulk: (params = {}) => {
return axios.put('hr-pardon', params);
},
removeTwoStepAuthentication: (params = {}) => {
return axios.put('user-remove-two-step', params);
},
}
export default api

View File

@@ -68,31 +68,24 @@
<td><el-button size="small" @click="handleViewInviteInfo">View</el-button></td>
</tr>
<tr>
<td>Seed points</td>
<td>{{baseInfo.seed_points}}</td>
</tr>
<tr>
<td>H&R inspecting</td>
<td>{{baseInfo.invites}}</td>
<td>Two-step authentication</td>
<td>{{baseInfo.two_step_secret ? 'Enabled' : 'Disabled'}}</td>
<td>
<el-popconfirm
title="Confirm Remove ?"
@confirm="handleRemoveHitAndRun"
v-if="baseInfo.two_step_secret"
title="Confirm Disable Two-step authentication ?"
@confirm="handleRemoveTwoStepAuthentication"
>
<template #reference>
<el-button size="small">Remove</el-button>
</template>
</el-popconfirm>
<el-popconfirm
title="Confirm Pardon ?"
@confirm="handlePardonHitAndRun"
>
<template #reference>
<el-button size="small">Pardon</el-button>
<el-button type="default" size="small">Disable</el-button>
</template>
</el-popconfirm>
</td>
</tr>
<tr>
<td>Seed points</td>
<td>{{baseInfo.seed_points}}</td>
</tr>
<tr>
<td>Invites</td>
<td>{{baseInfo.invites}}</td>
@@ -356,12 +349,12 @@ export default {
ElMessage.success(res.msg)
await fetchPageData()
}
const handleRemoveHitAndRun = async (id) => {
let res = await api.removeUserMedal(id)
const handleRemoveTwoStepAuthentication = async () => {
let res = await api.removeTwoStepAuthentication({uid: id})
ElMessage.success(res.msg)
await fetchPageData()
}
return {
...toRefs(state),
handleRemoveExam,
@@ -377,6 +370,7 @@ export default {
fetchPageData,
handleRemoveUserMedal,
handleIncrementDecrement,
handleRemoveTwoStepAuthentication,
assignExam,
grantMedal,
viewInviteInfo,

View File

@@ -7,13 +7,13 @@
:close-on-click-modal="false"
>
<el-table :data="inviteInfo" v-loading="loading">
<el-table-column prop="id" label="ID" width="55"></el-table-column>
<el-table-column prop="id" label="ID" width="80"></el-table-column>
<el-table-column prop="inviter_user.username" label="Inviter" width="150"></el-table-column>
<el-table-column prop="invitee" label="Receive email"></el-table-column>
<el-table-column prop="hash" label="Hash"></el-table-column>
<el-table-column prop="hash" label="Hash" width="300"></el-table-column>
<el-table-column prop="valid_text" label="Hash valid" width="100"></el-table-column>
<el-table-column prop="invitee_register_email" label="Register email"></el-table-column>
<el-table-column prop="time_invited" label="Time invited" width="160"></el-table-column>
<el-table-column prop="time_invited" label="Time invited" width="180"></el-table-column>
</el-table>
</el-dialog>

View File

@@ -287,4 +287,14 @@ class UserController extends Controller
return $this->success(['success' => $result]);
}
public function removeTwoStepAuthentication(Request $request): array
{
$user = Auth::user();
$request->validate([
'uid' => 'required',
]);
$result = $this->repository->removeTwoStepAuthentication($user, $request->uid, );
return $this->success(['success' => $result]);
}
}

View File

@@ -53,6 +53,11 @@ class UserResource extends JsonResource
$out['completed_torrents_count'] = $this->completed_torrents_count;
$out['incomplete_torrents_count'] = $this->incomplete_torrents_count;
}
if (nexus()->isPlatformAdmin() && $request->routeIs('users.show')) {
$out['two_step_secret'] = $this->two_step_secret;
}
return $out;
}
}

View File

@@ -48,7 +48,7 @@ class UserRepository extends BaseRepository
'inviter' => function ($query) {return $query->select(User::$commonFields);},
'valid_medals'
];
$user = User::query()->with($with)->findOrFail($id, User::$commonFields);
$user = User::query()->with($with)->findOrFail($id);
$userResource = new UserResource($user);
$baseInfo = $userResource->response()->getData(true)['data'];
@@ -60,9 +60,6 @@ class UserRepository extends BaseRepository
} else {
$examInfo = null;
}
return [
'base_info' => $baseInfo,
'exam_info' => $examInfo,
@@ -284,9 +281,7 @@ class UserRepository extends BaseRepository
public function removeLeechWarn($operator, $uid): bool
{
if (!$operator instanceof User) {
$operator = User::query()->findOrFail(intval($operator), User::$commonFields);
}
$operator = $this->getOperator($operator);
$classRequire = Setting::get('authority.prfmanage');
if ($operator->class < $classRequire) {
throw new \RuntimeException("No permission.");
@@ -298,6 +293,25 @@ class UserRepository extends BaseRepository
return $user->save();
}
public function removeTwoStepAuthentication($operator, $uid): bool
{
$operator = $this->getOperator($operator);
if (!$operator->canAccessAdmin()) {
throw new \RuntimeException("No permission.");
}
$user = User::query()->findOrFail($uid, User::$commonFields);
$user->two_step_secret = '';
return $user->save();
}
private function getOperator($operator)
{
if (!$operator instanceof User) {
$operator = User::query()->findOrFail(intval($operator), User::$commonFields);
}
return $operator;
}
}

View File

@@ -1503,10 +1503,10 @@ function sent_mail($to,$fromname,$fromemail,$subject,$body,$type = "confirmation
@mail($to,"=?".$hdr_encoding."?B?".base64_encode($subject)."?=",$body,$headers) or stderr($lang_functions['std_error'], $lang_functions['text_unable_to_send_mail']);
ini_restore(SMTP);
ini_restore(smtp_port);
ini_restore('SMTP');
ini_restore('smtp_port');
if ($windows)
ini_restore(sendmail_from);
ini_restore('sendmail_from');
}
elseif ($smtptype == 'external') {
/*

View File

@@ -6,6 +6,8 @@ $lang_takelogin = array
'std_login_fail' => "登錄失敗!",
'std_account_disabled' => "該帳號已被禁用。",
'std_user_account_unconfirmed' => "該賬戶還未通過驗證。如果你沒有收到驗證郵件,試試<a href='confirm_resend.php'><b>重新發送驗證郵件</b></a>。",
'std_require_two_step_code' => '需要兩步驗證 code',
'std_invalid_two_step_code' => '兩步驗證 code 無效',
);
?>

View File

@@ -69,7 +69,7 @@ $lang_index = array
'text_peers_active_now' => " users are seeding or leeching. ",
'text_disclaimer' => "Disclaimer",
'text_disclaimer_content' => "None of the files shown here are actually hosted on this server. The tracker only manages connections, it does not have any knowledge of the contents of the files being distributed. The links are provided solely by this site's users. The administrator of this site ".$SITENAME." cannot be held responsible for what its users post, or any other actions of its users. You may not use this site ".$SITENAME." to distribute or download any material when you do not have the legal rights to do so. It is your own responsibility to adhere to these terms.",
'text_browser_note' => "This site is best viewed with <a href=\"https://www.google.com/chrome/\" target=\"_blank\"><img class=\"img-browser\" src=\"/pic/misc/chrome-logo.svg\" alt=\"Google Chrome\" title=\"Get Google Chrome\" /></a>or<a href=\"https://www.mozilla.org/en-US/firefox/new/\" target=\"_blank\"><img class=\"firefox\" src=\"/pic/misc/firefox-logo.svg\" alt=\"Firefox\" title=\"Get Firefox\" border=\"0\" /></a> and with resolution above 1024*768. Recommended BitTorrent clients: <a href=\"https://www.qbittorrent.org/download.php\" target=\"_blank\"><img class=\"img-browser\" src=\"/pic/misc/qBittorrent.ico\" alt=\"qBittorrent\" title=\"Get qBittorrent\" /></a>or<a href=\"https://transmissionbt.com/download/\" target=\"_blank\"><img class=\"utorrent\" src=\"/pic/misc/transmission.png\" alt=\"Transmission\" title=\"Get Transmission\" /></a>",
'text_browser_note' => "This site is best viewed with <a href=\"https://www.google.com/chrome/\" target=\"_blank\"><img class=\"img-browser\" src=\"/pic/misc/chrome-logo.svg\" alt=\"Google Chrome\" title=\"Get Google Chrome\" /></a>or<a href=\"https://www.mozilla.org/en-US/firefox/new/\" target=\"_blank\"><img class=\"img-browser\" src=\"/pic/misc/firefox-logo.svg\" alt=\"Firefox\" title=\"Get Firefox\" border=\"0\" /></a> and with resolution above 1024*768. Recommended BitTorrent clients: <a href=\"https://www.qbittorrent.org/download.php\" target=\"_blank\"><img class=\"img-browser\" src=\"/pic/misc/qBittorrent.ico\" alt=\"qBittorrent\" title=\"Get qBittorrent\" /></a>or<a href=\"https://transmissionbt.com/download/\" target=\"_blank\"><img class=\"img-browser\" src=\"/pic/misc/transmission.png\" alt=\"Transmission\" title=\"Get Transmission\" /></a>",
'title_show_or_hide' => "Show/Hide",
'text_links' => "Links",
'text_manage_links' => "Manage Links",

View File

@@ -6,6 +6,8 @@ $lang_takelogin = array
'std_login_fail' => "Login failed!",
'std_account_disabled' => "This account has been disabled.",
'std_user_account_unconfirmed' => "The account has not been verified yet. If you didn't receive the confirmation email, try to <a href='confirm_resend.php'><b>reseed it</b></a>.",
'std_require_two_step_code' => 'Require two-step authentication code.',
'std_invalid_two_step_code' => 'Invalid two-step authentication code.',
);
?>

View File

@@ -47,8 +47,6 @@ $hash = md5(mt_rand(1,10000).$CURUSER['username'].TIMENOW.$CURUSER['passhash'])
$title = $SITENAME.$lang_takeinvite['mail_tilte'];
sql_query("INSERT INTO invites (inviter, invitee, hash, time_invited) VALUES ('".mysql_real_escape_string($id)."', '".mysql_real_escape_string($email)."', '".mysql_real_escape_string($hash)."', " . sqlesc(date("Y-m-d H:i:s")) . ")");
sql_query("UPDATE users SET invites = invites - 1 WHERE id = ".mysql_real_escape_string($id)) or sqlerr(__FILE__, __LINE__);
$signupUrl = getSchemeAndHttpHost() . "/signup.php?type=invite&invitenumber=$hash";
$message = <<<EOD
{$lang_takeinvite['mail_one']}{$arr['username']}{$lang_takeinvite['mail_two']}
@@ -59,8 +57,12 @@ $body
<br /><br />{$lang_takeinvite['mail_six']}
EOD;
sent_mail($email,$SITENAME,$SITEEMAIL,$title,$message,"invitesignup",false,false,'');
$sendResult = sent_mail($email,$SITENAME,$SITEEMAIL,$title,$message,"invitesignup",false,false,'');
//this email is sent only when someone give out an invitation
if ($sendResult === true) {
sql_query("INSERT INTO invites (inviter, invitee, hash, time_invited) VALUES ('".mysql_real_escape_string($id)."', '".mysql_real_escape_string($email)."', '".mysql_real_escape_string($hash)."', " . sqlesc(date("Y-m-d H:i:s")) . ")");
sql_query("UPDATE users SET invites = invites - 1 WHERE id = ".mysql_real_escape_string($id)) or sqlerr(__FILE__, __LINE__);
}
header("Refresh: 0; url=invite.php?id=".htmlspecialchars($id)."&sent=1");
?>

View File

@@ -62,6 +62,7 @@ Route::group(['middleware' => ['auth:sanctum', 'locale']], function () {
Route::post('user-enable', [\App\Http\Controllers\UserController::class, 'enable']);
Route::post('user-reset-password', [\App\Http\Controllers\UserController::class, 'resetPassword']);
Route::put('user-increment-decrement', [\App\Http\Controllers\UserController::class, 'incrementDecrement']);
Route::put('user-remove-two-step', [\App\Http\Controllers\UserController::class, 'removeTwoStepAuthentication']);
Route::resource('exams', \App\Http\Controllers\ExamController::class);
Route::get('exams-all', [\App\Http\Controllers\ExamController::class, 'all']);