mirror of
https://github.com/lkddi/nexusphp.git
synced 2026-04-05 07:20:58 +08:00
Challenge-Response Authentication
This commit is contained in:
@@ -46,9 +46,11 @@ class NexusWebGuard implements StatefulGuard
|
||||
}
|
||||
$credentials = $this->request->cookie();
|
||||
if ($this->validate($credentials)) {
|
||||
$user = $this->user;
|
||||
$user = $this->provider->retrieveByCredentials($credentials);
|
||||
if ($this->provider->validateCredentials($user, $credentials)) {
|
||||
return $user;
|
||||
if ($user->checkIsNormal()) {
|
||||
return $this->user = $user;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,29 +64,13 @@ class NexusWebGuard implements StatefulGuard
|
||||
*/
|
||||
public function validate(array $credentials = [])
|
||||
{
|
||||
$required = ['c_secure_pass', 'c_secure_uid', 'c_secure_login'];
|
||||
$required = ['c_secure_pass'];
|
||||
foreach ($required as $value) {
|
||||
if (empty($credentials[$value])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$b_id = base64($credentials["c_secure_uid"],false);
|
||||
$id = intval($b_id ?? 0);
|
||||
if (!$id || !is_valid_id($id) || strlen($credentials["c_secure_pass"]) != 32) {
|
||||
return false;
|
||||
}
|
||||
$user = $this->provider->retrieveById($id);
|
||||
if (!$user) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
$user->checkIsNormal();
|
||||
$this->user = $user;
|
||||
return true;
|
||||
} catch (\Throwable $e) {
|
||||
do_log($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function logout()
|
||||
|
||||
@@ -61,10 +61,15 @@ class NexusWebUserProvider implements UserProvider
|
||||
*/
|
||||
public function retrieveByCredentials(array $credentials)
|
||||
{
|
||||
if (!empty($credentials['c_secure_uid'])) {
|
||||
$b_id = base64($credentials["c_secure_uid"],false);
|
||||
return $this->query->find($b_id);
|
||||
list($tokenJson, $signature) = explode('.', base64_decode($credentials["c_secure_pass"]));
|
||||
if (empty($tokenJson) || empty($signature)) {
|
||||
return null;
|
||||
}
|
||||
$tokenData = json_decode($tokenJson, true);
|
||||
if (!isset($tokenData['user_id'])) {
|
||||
return null;
|
||||
}
|
||||
return $this->retrieveById($tokenData['user_id']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,20 +81,9 @@ class NexusWebUserProvider implements UserProvider
|
||||
*/
|
||||
public function validateCredentials(Authenticatable $user, array $credentials)
|
||||
{
|
||||
if ($credentials["c_secure_login"] == base64("yeah")) {
|
||||
/**
|
||||
* Not IP related
|
||||
* @since 1.8.0
|
||||
*/
|
||||
if ($credentials["c_secure_pass"] != md5($user->passhash)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if ($credentials["c_secure_pass"] !== md5($user->passhash)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
list($tokenJson, $signature) = explode('.', base64_decode($credentials["c_secure_pass"]));
|
||||
$expectedSignature = hash_hmac('sha256', $tokenJson, $user->auth_key);
|
||||
return hash_equals($expectedSignature, $signature);
|
||||
}
|
||||
|
||||
public function rehashPasswordIfRequired(Authenticatable $user, #[\SensitiveParameter] array $credentials, bool $force = false)
|
||||
|
||||
@@ -49,9 +49,8 @@ class Test extends Command
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$r = config('nexus.ammds_secret');
|
||||
// $r = SearchBox::query()->find(4)->ss()->orWhere("mode", 0)->get();
|
||||
dd($r);
|
||||
$result = getLogFile();
|
||||
dd($result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Cookie;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Nexus\Database\NexusDB;
|
||||
|
||||
class AuthenticateController extends Controller
|
||||
{
|
||||
@@ -53,7 +54,7 @@ class AuthenticateController extends Controller
|
||||
{
|
||||
$deadline = Setting::get('security.login_secret_deadline');
|
||||
if ($deadline && $deadline > now()->toDateTimeString()) {
|
||||
$user = User::query()->where('passkey', $passkey)->first(['id', 'passhash']);
|
||||
$user = User::query()->where('passkey', $passkey)->first(['id', 'passhash', 'secret', 'auth_key']);
|
||||
if ($user) {
|
||||
$ip = getip();
|
||||
/**
|
||||
@@ -61,9 +62,10 @@ class AuthenticateController extends Controller
|
||||
* @since 1.8.0
|
||||
*/
|
||||
// $passhash = md5($user->passhash . $ip);
|
||||
$passhash = md5($user->passhash);
|
||||
do_log(sprintf('passhash: %s, ip: %s, md5: %s', $user->passhash, $ip, $passhash));
|
||||
logincookie($user->id, $passhash,false, get_setting('system.cookie_valid_days', 365) * 86400, true, true, true);
|
||||
// $passhash = md5($user->passhash);
|
||||
// do_log(sprintf('passhash: %s, ip: %s, md5: %s', $user->passhash, $ip, $passhash));
|
||||
// logincookie($user->id, $passhash,false, get_setting('system.cookie_valid_days', 365) * 86400, true, true, true);
|
||||
logincookie($user->id, $user->auth_key);
|
||||
$user->last_login = now();
|
||||
$user->save();
|
||||
$userRep = new UserRepository();
|
||||
@@ -126,6 +128,29 @@ class AuthenticateController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
public function challenge(Request $request)
|
||||
{
|
||||
try {
|
||||
$request->validate([
|
||||
'username' => 'required|string',
|
||||
]);
|
||||
$username = $request->username;
|
||||
$challenge = mksecret();
|
||||
NexusDB::cache_put(get_challenge_key($username), $challenge,300);
|
||||
$user = User::query()->where("username", $username)->first(['secret']);
|
||||
return $this->success([
|
||||
"challenge" => $challenge,
|
||||
'secret' => $user->secret ?? mksecret(),
|
||||
]);
|
||||
} catch (\Exception $exception) {
|
||||
$msg = $exception->getMessage();
|
||||
$params = $request->all();
|
||||
do_log(sprintf("challenge fail: %s, params: %s", $msg, nexus_json_encode($params)));
|
||||
return $this->fail($params, $msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -105,4 +105,9 @@ class Setting extends NexusModel
|
||||
return self::get("main.defaultlang");
|
||||
}
|
||||
|
||||
public static function getIsUseChallengeResponseAuthentication(): bool
|
||||
{
|
||||
return self::get("security.use_challenge_response_authentication") == "yes";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ class User extends Authenticatable implements FilamentUser, HasName
|
||||
* @var array
|
||||
*/
|
||||
protected $hidden = [
|
||||
'secret', 'passhash', 'passkey'
|
||||
'secret', 'passhash', 'passkey', 'auth_key'
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -53,8 +53,9 @@ class AuthServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
//some plugin use this guard
|
||||
Auth::viaRequest('nexus-cookie', function (Request $request) {
|
||||
return $this->getUserByCookie($request->cookie());
|
||||
return get_user_from_cookie($request->cookie(), false);
|
||||
});
|
||||
|
||||
Auth::extend('nexus-web', function ($app, $name, array $config) {
|
||||
@@ -72,33 +73,4 @@ class AuthServiceProvider extends ServiceProvider
|
||||
|
||||
}
|
||||
|
||||
private function getUserByCookie($cookie)
|
||||
{
|
||||
if (empty($cookie["c_secure_pass"]) || empty($cookie["c_secure_uid"]) || empty($cookie["c_secure_login"])) {
|
||||
return null;
|
||||
}
|
||||
$b_id = base64($cookie["c_secure_uid"],false);
|
||||
$id = intval($b_id ?? 0);
|
||||
if (!$id || !is_valid_id($id) || strlen($cookie["c_secure_pass"]) != 32) {
|
||||
return null;
|
||||
}
|
||||
$user = User::query()->find($id);
|
||||
if (!$user) {
|
||||
return null;
|
||||
}
|
||||
if ($cookie["c_secure_login"] == base64("yeah")) {
|
||||
/**
|
||||
* Not IP related
|
||||
* @since 1.8.0
|
||||
*/
|
||||
if ($cookie["c_secure_pass"] != md5($user->passhash)) {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
if ($cookie["c_secure_pass"] !== md5($user->passhash)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->string("passhash", 255)->default("")->nullable(false)->change();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->string("auth_key", 255)->default("")->nullable(false)->after("secret");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropColumn("auth_key");
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1954,7 +1954,6 @@ function dbconn($autoclean = false, $doLogin = true)
|
||||
}
|
||||
|
||||
function userlogin() {
|
||||
// do_log("COOKIE:" . json_encode($_COOKIE) . ", uid: " . (isset($_COOKIE['c_secure_uid']) ? base64($_COOKIE["c_secure_uid"],false) : ''));
|
||||
static $loginResult;
|
||||
if (!is_null($loginResult)) {
|
||||
return $loginResult;
|
||||
@@ -1964,7 +1963,6 @@ function userlogin() {
|
||||
global $SITE_ONLINE, $oldip;
|
||||
global $enablesqldebug_tweak, $sqldebug_tweak;
|
||||
unset($GLOBALS["CURUSER"]);
|
||||
$log = "cookie: " . json_encode($_COOKIE);
|
||||
|
||||
$ip = getip();
|
||||
$nip = ip2long($ip);
|
||||
@@ -1979,68 +1977,11 @@ function userlogin() {
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($_COOKIE["c_secure_pass"]) || empty($_COOKIE["c_secure_uid"]) || empty($_COOKIE["c_secure_login"])) {
|
||||
do_log("$log, param not enough");
|
||||
return $loginResult = false;
|
||||
}
|
||||
if ($_COOKIE["c_secure_login"] == base64("yeah"))
|
||||
{
|
||||
//if (empty($_SESSION["s_secure_uid"]) || empty($_SESSION["s_secure_pass"]))
|
||||
//return;
|
||||
}
|
||||
$b_id = base64($_COOKIE["c_secure_uid"],false);
|
||||
$id = intval($b_id ?? 0);
|
||||
if (!$id || !is_valid_id($id) || strlen($_COOKIE["c_secure_pass"]) != 32) {
|
||||
do_log("$log, invalid c_secure_uid");
|
||||
$row = get_user_from_cookie($_COOKIE);
|
||||
if (empty($row)) {
|
||||
return $loginResult = false;
|
||||
}
|
||||
|
||||
if ($_COOKIE["c_secure_login"] == base64("yeah"))
|
||||
{
|
||||
//if (strlen($_SESSION["s_secure_pass"]) != 32)
|
||||
//return;
|
||||
}
|
||||
|
||||
$res = sql_query("SELECT * FROM users WHERE users.id = ".sqlesc($id)." AND users.enabled='yes' AND users.status = 'confirmed' LIMIT 1");
|
||||
$row = mysql_fetch_array($res);
|
||||
if (!$row) {
|
||||
do_log("$log, c_secure_uid not exists");
|
||||
return $loginResult = false;
|
||||
}
|
||||
|
||||
$sec = hash_pad($row["secret"]);
|
||||
|
||||
//die(base64_decode($_COOKIE["c_secure_login"]));
|
||||
|
||||
if ($_COOKIE["c_secure_login"] == base64("yeah"))
|
||||
{
|
||||
/**
|
||||
* Not IP related
|
||||
* @since 1.8.0
|
||||
*/
|
||||
// $md5 = md5($row["passhash"].$ip);
|
||||
$md5 = md5($row["passhash"]);
|
||||
$log .= ", secure login == yeah, passhash: {$row['passhash']}, ip: $ip, md5: $md5";
|
||||
if ($_COOKIE["c_secure_pass"] != $md5) {
|
||||
do_log("$log, c_secure_pass != md5");
|
||||
return $loginResult = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$md5 = md5($row["passhash"]);
|
||||
$log .= "$log, passhash: {$row['passhash']}, md5: $md5";
|
||||
if ($_COOKIE["c_secure_pass"] !== $md5) {
|
||||
do_log("$log, c_secure_pass != md5");
|
||||
return $loginResult = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($_COOKIE["c_secure_login"] == base64("yeah"))
|
||||
{
|
||||
//if ($_SESSION["s_secure_pass"] !== md5($row["passhash"].$_SERVER["REMOTE_ADDR"]))
|
||||
//return;
|
||||
}
|
||||
if (!$row["passkey"]){
|
||||
$passkey = md5($row['username'].date("Y-m-d H:i:s").$row['passhash']);
|
||||
sql_query("UPDATE users SET passkey = ".sqlesc($passkey)." WHERE id=" . sqlesc($row["id"]));
|
||||
@@ -3001,10 +2942,11 @@ function genbark($x,$y) {
|
||||
}
|
||||
|
||||
function mksecret($len = 20) {
|
||||
$ret = "";
|
||||
for ($i = 0; $i < $len; $i++)
|
||||
$ret .= chr(mt_rand(100, 120));
|
||||
return $ret;
|
||||
// $ret = "";
|
||||
// for ($i = 0; $i < $len; $i++)
|
||||
// $ret .= chr(mt_rand(100, 120));
|
||||
// return $ret;
|
||||
return bin2hex(random_bytes($len));
|
||||
}
|
||||
|
||||
function httperr($code = 404) {
|
||||
@@ -3013,30 +2955,23 @@ function httperr($code = 404) {
|
||||
exit();
|
||||
}
|
||||
|
||||
function logincookie($id, $passhash, $updatedb = 1, $expires = 0x7fffffff, $securelogin=false, $ssl=false, $trackerssl=false)
|
||||
function logincookie($id, $authKey, $duration = 0)
|
||||
{
|
||||
if ($expires != 0x7fffffff)
|
||||
$expires = time()+$expires;
|
||||
|
||||
setcookie("c_secure_uid", base64($id), $expires, "/", "", false, true);
|
||||
setcookie("c_secure_pass", $passhash, $expires, "/", "", false, true);
|
||||
if($ssl)
|
||||
setcookie("c_secure_ssl", base64("yeah"), $expires, "/", "", false, true);
|
||||
else
|
||||
setcookie("c_secure_ssl", base64("nope"), $expires, "/", "", false, true);
|
||||
|
||||
if($trackerssl)
|
||||
setcookie("c_secure_tracker_ssl", base64("yeah"), $expires, "/", "", false, true);
|
||||
else
|
||||
setcookie("c_secure_tracker_ssl", base64("nope"), $expires, "/", "", false, true);
|
||||
|
||||
if ($securelogin)
|
||||
setcookie("c_secure_login", base64("yeah"), $expires, "/", "", false, true);
|
||||
else
|
||||
setcookie("c_secure_login", base64("nope"), $expires, "/", "", false, true);
|
||||
|
||||
|
||||
if ($updatedb)
|
||||
if (empty($authKey)) {
|
||||
throw new \RuntimeException("user secret or auth_key is empty");
|
||||
}
|
||||
if ($duration <= 0) {
|
||||
$duration = get_setting('system.cookie_valid_days', 365) * 86400;
|
||||
}
|
||||
$expires = time() + $duration;
|
||||
$tokenData = [
|
||||
'user_id' => $id,
|
||||
'expires' => $expires,
|
||||
];
|
||||
$tokenJson = json_encode($tokenData);
|
||||
$signature = hash_hmac('sha256', $tokenJson, $authKey);
|
||||
$authToken = base64_encode($tokenJson . '.' . $signature);
|
||||
setcookie("c_secure_pass", $authToken, $expires, "/", "", true, true);
|
||||
sql_query("UPDATE users SET last_login = NOW(), lang=" . sqlesc(get_langid_from_langcookie()) . " WHERE id = ".sqlesc($id));
|
||||
}
|
||||
|
||||
@@ -3089,11 +3024,11 @@ function make_folder($pre, $folder_name)
|
||||
}
|
||||
|
||||
function logoutcookie() {
|
||||
setcookie("c_secure_uid", "", 0x7fffffff, "/", "", false, true);
|
||||
setcookie("c_secure_pass", "", 0x7fffffff, "/", "", false, true);
|
||||
// setcookie("c_secure_uid", "", 0x7fffffff, "/", "", false, true);
|
||||
setcookie("c_secure_pass", "", 0x7fffffff, "/", "", true, true);
|
||||
// setcookie("c_secure_ssl", "", 0x7fffffff, "/", "", false, true);
|
||||
setcookie("c_secure_tracker_ssl", "", 0x7fffffff, "/", "", false, true);
|
||||
setcookie("c_secure_login", "", 0x7fffffff, "/", "", false, true);
|
||||
// setcookie("c_secure_tracker_ssl", "", 0x7fffffff, "/", "", false, true);
|
||||
// setcookie("c_secure_login", "", 0x7fffffff, "/", "", false, true);
|
||||
// setcookie("c_lang_folder", "", 0x7fffffff, "/", "", false, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -1370,3 +1370,159 @@ function send_admin_fail_notification(string $msg = ""): void {
|
||||
function ability(\App\Enums\Permission\PermissionEnum $permission): string {
|
||||
return sprintf("ability:%s", $permission->value);
|
||||
}
|
||||
|
||||
function get_challenge_key(string $challenge): string {
|
||||
return "challenge:".$challenge;
|
||||
}
|
||||
|
||||
function get_user_from_cookie(array $cookie, $isArray = true): array|\App\Models\User|null {
|
||||
$log = "cookie: " . json_encode($cookie);
|
||||
if (empty($_COOKIE["c_secure_pass"])) {
|
||||
do_log("$log, param not enough");
|
||||
return null;
|
||||
}
|
||||
list($tokenJson, $signature) = explode('.', base64_decode($_COOKIE["c_secure_pass"]));
|
||||
if (empty($tokenJson) || empty($signature)) {
|
||||
do_log("$log, no tokenJson or signature");
|
||||
return null;
|
||||
}
|
||||
$tokenData = json_decode($tokenJson, true);
|
||||
if (!isset($tokenData['user_id'])) {
|
||||
do_log("$log, no user_id");
|
||||
return null;
|
||||
}
|
||||
if (!isset($tokenData['expires']) || $tokenData['expires'] < time()) {
|
||||
do_log("$log, signature expired");
|
||||
return null;
|
||||
}
|
||||
$id = $tokenData['user_id'];
|
||||
$log .= ", uid = $id";
|
||||
|
||||
if ($isArray) {
|
||||
$res = sql_query("SELECT * FROM users WHERE users.id = ".sqlesc($id)." AND users.enabled='yes' AND users.status = 'confirmed' LIMIT 1");
|
||||
$row = mysql_fetch_array($res);
|
||||
if (!$row) {
|
||||
do_log("$log, user not exists");
|
||||
return null;
|
||||
}
|
||||
$authKey = $row["auth_key"];
|
||||
unset($row['auth_key'], $row['passhash']);
|
||||
} else {
|
||||
$row = \App\Models\User::query()->find($id);
|
||||
if (!$row) {
|
||||
do_log("$log, user not exists");
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
$row->checkIsNormal();
|
||||
} catch (\Exception $e) {
|
||||
do_log("$log, " . $e->getMessage());
|
||||
return null;
|
||||
}
|
||||
$authKey = $row->auth_key;
|
||||
}
|
||||
$expectedSignature = hash_hmac('sha256', $tokenJson, $authKey);
|
||||
if (!hash_equals($expectedSignature, $signature)) {
|
||||
do_log("$log, !hash_equals, expectedSignature: $expectedSignature, actualSignature: $signature");
|
||||
return null;
|
||||
}
|
||||
return $row;
|
||||
}
|
||||
|
||||
function render_password_hash_js(string $formId, string $passwordOriginalClass, string $passwordHashedName, bool $passwordRequired, string $passwordConfirmClass = "password_confirmation", string $usernameName = "username"): void {
|
||||
$tipTooShort = nexus_trans('signup.password_too_short');
|
||||
$tipTooLong = nexus_trans('signup.password_too_long');
|
||||
$tipEqualUsername = nexus_trans('signup.password_equals_username');
|
||||
$tipNotMatch = nexus_trans('signup.passwords_unmatched');
|
||||
$passwordValidateJS = "";
|
||||
if ($passwordRequired) {
|
||||
$passwordValidateJS = <<<JS
|
||||
if (password.length < 6) {
|
||||
layer.alert("$tipTooShort")
|
||||
return
|
||||
}
|
||||
if (password.length > 40) {
|
||||
layer.alert("$tipTooLong")
|
||||
return
|
||||
}
|
||||
JS;
|
||||
}
|
||||
$formVar = "jqForm" . md5($formId);
|
||||
$js = <<<JS
|
||||
var $formVar = jQuery("#{$formId}");
|
||||
$formVar.on("click", "input[type=button]", function() {
|
||||
let jqUsername = $formVar.find("[name={$usernameName}]")
|
||||
let jqPassword = $formVar.find(".{$passwordOriginalClass}")
|
||||
let jqPasswordConfirm = $formVar.find(".{$passwordConfirmClass}")
|
||||
let password = jqPassword.val()
|
||||
$passwordValidateJS
|
||||
if (jqUsername.length > 0 && jqUsername.val() === password) {
|
||||
layer.alert("$tipEqualUsername")
|
||||
return
|
||||
}
|
||||
if (jqPasswordConfirm.length > 0 && password !== jqPasswordConfirm.val()) {
|
||||
layer.alert("$tipNotMatch")
|
||||
return
|
||||
}
|
||||
if (password !== "") {
|
||||
sha256(password).then((passwordHashed) => {
|
||||
$formVar.find("input[name={$passwordHashedName}]").val(passwordHashed)
|
||||
$formVar.submit()
|
||||
})
|
||||
} else {
|
||||
$formVar.submit()
|
||||
}
|
||||
})
|
||||
JS;
|
||||
\Nexus\Nexus::js($js, 'footer', false);
|
||||
}
|
||||
|
||||
function render_password_challenge_js(string $formId, string $usernameName, string $passwordOriginalClass): void {
|
||||
$formVar = "jqForm" . md5($formId);
|
||||
$js = <<<JS
|
||||
var $formVar = jQuery("#{$formId}");
|
||||
$formVar.on("click", "input[type=button]", function() {
|
||||
let useChallengeResponseAuthentication = $formVar.find("input[name=response]").length > 0
|
||||
if (!useChallengeResponseAuthentication) {
|
||||
return $formVar.submit()
|
||||
}
|
||||
let jqUsername = $formVar.find("[name={$usernameName}]")
|
||||
let jqPassword = $formVar.find(".{$passwordOriginalClass}")
|
||||
let username = jqUsername.val()
|
||||
let password = jqPassword.val()
|
||||
login(username, password, $formVar)
|
||||
})
|
||||
async function login(username, password, jqForm) {
|
||||
try {
|
||||
jQuery('body').loading({stoppable: false});
|
||||
const challengeResponse = await fetch('/api/challenge', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ username: username })
|
||||
});
|
||||
jQuery('body').loading('stop');
|
||||
|
||||
const challengeData = await challengeResponse.json();
|
||||
if (challengeData.ret !== 0) {
|
||||
layer.alert(challengeData.msg)
|
||||
return
|
||||
}
|
||||
|
||||
const clientHashedPassword = await sha256(password);
|
||||
|
||||
const serverSideHash = await sha256(challengeData.data.secret + clientHashedPassword);
|
||||
|
||||
const clientResponse = await hmacSha256(challengeData.data.challenge, serverSideHash);
|
||||
jqForm.find("input[name=response]").val(clientResponse)
|
||||
jqForm.submit()
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
layer.alert(error.toString())
|
||||
}
|
||||
}
|
||||
JS;
|
||||
\Nexus\Nexus::js("vendor/jquery-loading/jquery.loading.min.js", 'footer', true);
|
||||
\Nexus\Nexus::js($js, 'footer', false);
|
||||
}
|
||||
|
||||
@@ -813,6 +813,8 @@ $lang_settings = array
|
||||
'text_max_price_note' => '默认:1,000,000,设置为 0 无限制',
|
||||
'row_paid_torrent_enabled' => '是否启用收费种子',
|
||||
'text_paid_torrent_enabled_note' => '启用后,有权限的用户可以在发种时设置向下载种子的用户收取一定的魔力,默认:否',
|
||||
'row_use_challenge_response_authentication' => '挑战-响应认证',
|
||||
'text_use_challenge_response_authentication_note' => '如果启用,登录时将不传输明文密码,建议启用。未来版本会删除此配置且启用此功能。',
|
||||
);
|
||||
|
||||
?>
|
||||
|
||||
@@ -813,6 +813,8 @@ $lang_settings = array
|
||||
'text_max_price_note' => '默認:1,000,000,設置為 0 無限製',
|
||||
'row_paid_torrent_enabled' => '是否啟用收費種子',
|
||||
'text_paid_torrent_enabled_note' => '啟用後,有權限的用戶可以在發種時設置向下載種子的用戶收取一定的魔力,默認:否',
|
||||
'row_use_challenge_response_authentication' => '挑戰-響應認證',
|
||||
'text_use_challenge_response_authentication_note' => '如果啟用,登錄時將不傳輸明文密碼,建議啟用。未來版本會刪除此配置且啟用此功能。',
|
||||
);
|
||||
|
||||
?>
|
||||
|
||||
@@ -813,6 +813,8 @@ $lang_settings = array
|
||||
'text_max_price_note' => 'default: 1,000,000, set to 0 no limit',
|
||||
'row_paid_torrent_enabled' => 'Whether to enable paid torrents',
|
||||
'text_paid_torrent_enabled_note' => 'When enabled, users with permission can set a certain amount of bonus to be charged to users who download the torrents when they are sent, default: no',
|
||||
'row_use_challenge_response_authentication' => 'Challenge-Response Authentication',
|
||||
'text_use_challenge_response_authentication_note' => 'If enabled, no plaintext passwords will be transmitted at login, recommended. Future releases will remove this configuration and enable this feature.' ,
|
||||
);
|
||||
|
||||
?>
|
||||
|
||||
@@ -291,7 +291,7 @@ final class Nexus
|
||||
public static function trans($key, $replace = [], $locale = null)
|
||||
{
|
||||
if (!IN_NEXUS) {
|
||||
return trans($key, $replace, $locale ?? Locale::getDefault());
|
||||
return trans($key, $replace, $locale ?? get_langfolder_cookie(true));
|
||||
}
|
||||
if (empty(self::$translations)) {
|
||||
//load from default lang dir
|
||||
@@ -302,7 +302,7 @@ final class Nexus
|
||||
self::loadTranslations($path, $namespace);
|
||||
}
|
||||
}
|
||||
return self::getTranslation($key, $replace, $locale ?? Locale::getDefault());
|
||||
return self::getTranslation($key, $replace, $locale ?? get_langfolder_cookie(true));
|
||||
}
|
||||
|
||||
private static function loadTranslations($path, $namespace = null)
|
||||
|
||||
@@ -9,7 +9,7 @@ if (!$id)
|
||||
|
||||
dbconn();
|
||||
|
||||
$res = sql_query("SELECT passhash, secret, editsecret, status FROM users WHERE id = ".sqlesc($id)) or sqlerr(__FILE__, __LINE__);
|
||||
$res = sql_query("SELECT passhash, secret, auth_key, editsecret, status FROM users WHERE id = ".sqlesc($id)) or sqlerr(__FILE__, __LINE__);
|
||||
$row = mysql_fetch_assoc($res);
|
||||
|
||||
if (!$row)
|
||||
@@ -30,17 +30,18 @@ if (!mysql_affected_rows())
|
||||
httperr();
|
||||
|
||||
|
||||
if ($securelogin == "yes")
|
||||
{
|
||||
$securelogin_indentity_cookie = true;
|
||||
$passh = md5($row["passhash"].$_SERVER["REMOTE_ADDR"]);
|
||||
}
|
||||
else // when it's op, default is not use secure login
|
||||
{
|
||||
$securelogin_indentity_cookie = false;
|
||||
$passh = md5($row["passhash"]);
|
||||
}
|
||||
logincookie($id, $passh,1,get_setting('system.cookie_valid_days', 365) * 86400,$securelogin_indentity_cookie);
|
||||
//if ($securelogin == "yes")
|
||||
//{
|
||||
// $securelogin_indentity_cookie = true;
|
||||
// $passh = md5($row["passhash"].$_SERVER["REMOTE_ADDR"]);
|
||||
//}
|
||||
//else // when it's op, default is not use secure login
|
||||
//{
|
||||
// $securelogin_indentity_cookie = false;
|
||||
// $passh = md5($row["passhash"]);
|
||||
//}
|
||||
//logincookie($id, $passh,1,get_setting('system.cookie_valid_days', 365) * 86400,$securelogin_indentity_cookie);
|
||||
logincookie($id, $row["auth_key"]);
|
||||
//sessioncookie($row["id"], $passh,false);
|
||||
|
||||
header("Location: ok.php?type=confirm");
|
||||
|
||||
23
public/js/common.js
vendored
23
public/js/common.js
vendored
@@ -404,3 +404,26 @@ function NewRow(anchor,up){
|
||||
function DelRow(anchor){
|
||||
anchor.parentNode.parentNode.parentNode.parentNode.deleteRow(anchor.parentNode.parentNode.rowIndex);
|
||||
}
|
||||
|
||||
// 工具函数:SHA-256哈希
|
||||
async function sha256(message) {
|
||||
const msgBuffer = new TextEncoder().encode(message);
|
||||
const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);
|
||||
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
||||
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
|
||||
}
|
||||
|
||||
// 工具函数:HMAC-SHA256
|
||||
async function hmacSha256(key, message) {
|
||||
const encoder = new TextEncoder();
|
||||
const keyData = encoder.encode(key);
|
||||
const messageData = encoder.encode(message);
|
||||
|
||||
const cryptoKey = await crypto.subtle.importKey(
|
||||
'raw', keyData, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']
|
||||
);
|
||||
|
||||
const signature = await crypto.subtle.sign('HMAC', cryptoKey, messageData);
|
||||
const hashArray = Array.from(new Uint8Array(signature));
|
||||
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
|
||||
}
|
||||
|
||||
@@ -48,14 +48,19 @@ if (!empty($_GET["returnto"])) {
|
||||
print("<p><b>" . $lang_login['p_error']. "</b> " . $lang_login['p_after_logged_in']. "</p>\n");
|
||||
}
|
||||
}
|
||||
$useChallengeResponseAuthentication = \App\Models\Setting::getIsUseChallengeResponseAuthentication();
|
||||
$passwordName = 'class="password"';
|
||||
if (!$useChallengeResponseAuthentication) {
|
||||
$passwordName .= ' name="password"';
|
||||
}
|
||||
?>
|
||||
<form method="post" action="takelogin.php">
|
||||
<form id="login-form" method="post" action="takelogin.php">
|
||||
<input type="hidden" name="secret" value="<?php echo $secret?>">
|
||||
<p><?php echo $lang_login['p_need_cookies_enables']?><br /> [<b><?php echo $maxloginattempts;?></b>] <?php echo $lang_login['p_fail_ban']?></p>
|
||||
<p><?php echo $lang_login['p_you_have']?> <b><?php echo remaining ();?></b> <?php echo $lang_login['p_remaining_tries']?></p>
|
||||
<table border="0" cellpadding="5">
|
||||
<tr><td class="rowhead"><?php echo $lang_login['rowhead_username']?></td><td class="rowfollow" align="left"><input type="text" name="username" style="width: 180px; border: 1px solid gray" /></td></tr>
|
||||
<tr><td class="rowhead"><?php echo $lang_login['rowhead_password']?></td><td class="rowfollow" align="left"><input type="password" name="password" style="width: 180px; border: 1px solid gray"/></td></tr>
|
||||
<tr><td class="rowhead"><?php echo $lang_login['rowhead_username']?></td><td class="rowfollow" align="left"><input type="text" class="username" name="username" style="width: 180px; border: 1px solid gray" /></td></tr>
|
||||
<tr><td class="rowhead"><?php echo $lang_login['rowhead_password']?></td><td class="rowfollow" align="left"><input type="password" <?php echo $passwordName ?> style="width: 180px; border: 1px solid gray"/></td></tr>
|
||||
<tr><td class="rowhead"><?php echo $lang_login['rowhead_two_step_code']?></td><td class="rowfollow" align="left"><input type="text" name="two_step_code" placeholder="<?php echo $lang_login['two_step_code_tooltip'] ?>" style="width: 180px; border: 1px solid gray"/></td></tr>
|
||||
<?php
|
||||
show_image_code ();
|
||||
@@ -75,16 +80,20 @@ elseif ($securetracker == "op")
|
||||
?>
|
||||
<tr><td class="toolbox" colspan="2" align="left"><?php echo $lang_login['text_advanced_options']?></td></tr>
|
||||
<tr><td class="rowhead"><?php echo $lang_login['text_auto_logout']?></td><td class="rowfollow" align="left"><input class="checkbox" type="checkbox" name="logout" value="yes" /><?php echo $lang_login['checkbox_auto_logout']?></td></tr>
|
||||
<tr><td class="rowhead"><?php echo $lang_login['text_restrict_ip']?></td><td class="rowfollow" align="left"><input class="checkbox" type="checkbox" name="securelogin" value="yes" /><?php echo $lang_login['checkbox_restrict_ip']?></td></tr>
|
||||
<tr><td class="rowhead"><?php echo $lang_login['text_ssl']?></td><td class="rowfollow" align="left"><input class="checkbox" type="checkbox" name="ssl" value="yes" <?php echo $sec?> /><?php echo $lang_login['checkbox_ssl']?><br /><input class="checkbox" type="checkbox" name="trackerssl" value="yes" <?php echo $sectra?> /><?php echo $lang_login['checkbox_ssl_tracker']?></td></tr>
|
||||
<tr><td class="toolbox" colspan="2" align="right"><input type="submit" value="<?php echo $lang_login['button_login']?>" class="btn" /> <input type="reset" value="<?php echo $lang_login['button_reset']?>" class="btn" /></td></tr>
|
||||
<!--<tr><td class="rowhead">--><?php //echo $lang_login['text_restrict_ip']?><!--</td><td class="rowfollow" align="left"><input class="checkbox" type="checkbox" name="securelogin" value="yes" />--><?php //echo $lang_login['checkbox_restrict_ip']?><!--</td></tr>-->
|
||||
<!--<tr><td class="rowhead">--><?php //echo $lang_login['text_ssl']?><!--</td><td class="rowfollow" align="left"><input class="checkbox" type="checkbox" name="ssl" value="yes" --><?php //echo $sec?><!-- />--><?php //echo $lang_login['checkbox_ssl']?><!--<br /><input class="checkbox" type="checkbox" name="trackerssl" value="yes" --><?php //echo $sectra?><!-- />--><?php //echo $lang_login['checkbox_ssl_tracker']?><!--</td></tr>-->
|
||||
<tr><td class="toolbox" colspan="2" align="right"><input id="submit-btn" type="button" value="<?php echo $lang_login['button_login']?>" class="btn" /> <input type="reset" value="<?php echo $lang_login['button_reset']?>" class="btn" /></td></tr>
|
||||
</table>
|
||||
<?php
|
||||
|
||||
if (isset($returnto))
|
||||
print("<input type=\"hidden\" name=\"returnto\" value=\"" . htmlspecialchars($returnto) . "\" />\n");
|
||||
|
||||
if (isset($returnto)) {
|
||||
print("<input type=\"hidden\" name=\"returnto\" value=\"" . htmlspecialchars($returnto) . "\" />\n");
|
||||
}
|
||||
if ($useChallengeResponseAuthentication) {
|
||||
print('<input type="hidden" name="response" />');
|
||||
}
|
||||
?>
|
||||
|
||||
</form>
|
||||
<p>[<b><a href="complains.php"><?= $lang_login['text_complain'] ?></a></b>]</p>
|
||||
<p><?php echo $lang_login['p_no_account_signup']?></p>
|
||||
@@ -108,4 +117,7 @@ print("<div id=sbword style=\"display: none\">".$lang_login['sumbit_shout']."</d
|
||||
print(smile_row("shbox","shbox_text"));
|
||||
print("</td></tr></table></form></td></tr></table>");
|
||||
}
|
||||
?>
|
||||
<?php
|
||||
render_password_challenge_js("login-form", "username", "password");
|
||||
stdfoot();
|
||||
|
||||
@@ -85,7 +85,9 @@ elseif($_SERVER["REQUEST_METHOD"] == "GET" && $take_recover && isset($_GET["id"]
|
||||
|
||||
$sec = mksecret();
|
||||
|
||||
$newpasshash = md5($sec . $newpassword . $sec);
|
||||
// $newpasshash = md5($sec . $newpassword . $sec);
|
||||
$newpasshash = hash('sha256', $newpassword);
|
||||
$newpasshash = hash('sha256', $sec.$newpasshash);
|
||||
|
||||
sql_query("UPDATE users SET secret=" . sqlesc($sec) . ", editsecret='', passhash=" . sqlesc($newpasshash) . " WHERE id=" . sqlesc($id)." AND editsecret=" . sqlesc($arr["editsecret"])) or sqlerr(__FILE__, __LINE__);
|
||||
|
||||
|
||||
@@ -199,7 +199,7 @@ elseif ($action == 'savesettings_security') // save security
|
||||
$validConfig = array(
|
||||
'securelogin', 'securetracker', 'https_announce_url','iv','maxip','maxloginattempts','changeemail','cheaterdet','nodetect',
|
||||
'guest_visit_type', 'guest_visit_value_static_page', 'guest_visit_value_custom_content', 'guest_visit_value_redirect',
|
||||
'login_type', 'login_secret_lifetime',
|
||||
'login_type', 'login_secret_lifetime', 'use_challenge_response_authentication'
|
||||
);
|
||||
GetVar($validConfig);
|
||||
$SECURITY = [];
|
||||
@@ -376,6 +376,7 @@ elseif ($action == 'securitysettings') //security settings
|
||||
tr($lang_settings['row_max_ips'],"<input type='text' style=\"width: 300px\" name=maxip value='" . ($SECURITY["maxip"] ? $SECURITY["maxip"] : "1")."'> ".$lang_settings['text_max_ips_note'], 1);
|
||||
tr($lang_settings['row_max_login_attemps'],"<input type='text' style=\"width: 300px\" name=maxloginattempts value='" . ($SECURITY["maxloginattempts"] ? $SECURITY["maxloginattempts"] : "7")."'> ".$lang_settings['text_max_login_attemps_note'], 1);
|
||||
|
||||
yesorno($lang_settings['row_use_challenge_response_authentication'], 'use_challenge_response_authentication', $SECURITY["use_challenge_response_authentication"], $lang_settings['text_use_challenge_response_authentication_note']);
|
||||
$guestVisitTypeRadio = '<label><input type="radio" name="guest_visit_type" value="normal"' . (empty($SECURITY['guest_visit_type']) || $SECURITY['guest_visit_type'] == 'normal' ? ' checked' : '') . ' onclick="document.getElementById(\'tbody_static_page\').style.display=\'none\';document.getElementById(\'tbody_custom_content\').style.display=\'none\';document.getElementById(\'tbody_redirect\').style.display=\'none\';">' . $lang_settings['text_guest_visit_type_normal'] . '</label>';
|
||||
$guestVisitTypeRadio .= '<br/><label><input type="radio" name="guest_visit_type" value="static_page"' . ($SECURITY['guest_visit_type'] == 'static_page' ? ' checked' : '') . ' onclick="document.getElementById(\'tbody_static_page\').style.display=\'table-row-group\';document.getElementById(\'tbody_custom_content\').style.display=\'none\';document.getElementById(\'tbody_redirect\').style.display=\'none\';">' . $lang_settings['text_guest_visit_type_static_page'] . '</label>';
|
||||
$guestVisitTypeRadio .= '<br/><label><input type="radio" name="guest_visit_type" value="custom_content"' . ($SECURITY['guest_visit_type'] == 'custom_content' ? ' checked' : '') . ' onclick="document.getElementById(\'tbody_static_page\').style.display=\'none\';document.getElementById(\'tbody_custom_content\').style.display=\'table-row-group\';document.getElementById(\'tbody_redirect\').style.display=\'none\';">' . $lang_settings['text_guest_visit_type_custom_content'] . '</label>';
|
||||
|
||||
@@ -17,6 +17,7 @@ if ($langid)
|
||||
}
|
||||
}
|
||||
require_once(get_langfile_path("", false, $CURLANGDIR));
|
||||
require_once(get_langfile_path("takesignup.php", false, $CURLANGDIR));
|
||||
cur_user_check ();
|
||||
$type = $_GET['type'] ?? '';
|
||||
$isPreRegisterEmailAndUsername = get_setting("system.is_invite_pre_email_and_username") == "yes";
|
||||
@@ -73,7 +74,7 @@ print("<div align=right valign=top>".$lang_signup['text_select_lang']. $s . "</d
|
||||
?>
|
||||
</form>
|
||||
<p>
|
||||
<form method="post" action="takesignup.php">
|
||||
<form method="post" action="takesignup.php" id="signup-form">
|
||||
<?php if ($type == 'invite') print("<input type=\"hidden\" name=\"inviter\" value=\"".$inviter."\"><input type=hidden name=type value='invite'>");?>
|
||||
<table border="1" cellspacing="0" cellpadding="10">
|
||||
<?php
|
||||
@@ -93,9 +94,9 @@ if ($isPreRegisterEmailAndUsername && !empty($inv["pre_register_email"])) {
|
||||
?>
|
||||
<tr><td class=rowhead><?php echo $lang_signup['row_desired_username'] ?></td><td class=rowfollow align=left><?php echo $usernameInput?><br />
|
||||
<font class=small><?php echo $lang_signup['text_allowed_characters'] ?></font></td></tr>
|
||||
<tr><td class=rowhead><?php echo $lang_signup['row_pick_a_password'] ?></td><td class=rowfollow align=left><input type="password" style="width: 200px" name="wantpassword" /><br />
|
||||
<tr><td class=rowhead><?php echo $lang_signup['row_pick_a_password'] ?></td><td class=rowfollow align=left><input type="password" style="width: 200px" class="wantpassword" data-too-short="<?php echo $lang_takesignup['std_password_too_short']?>" data-too-long="<?php echo $lang_takesignup['std_password_too_long']?>" data-equals-username="<?php echo $lang_takesignup['std_password_equals_username']?>"/><br />
|
||||
<font class=small><?php echo $lang_signup['text_minimum_six_characters'] ?></font></td></tr>
|
||||
<tr><td class=rowhead><?php echo $lang_signup['row_enter_password_again'] ?></td><td class=rowfollow align=left><input type="password" style="width: 200px" name="passagain" /></td></tr>
|
||||
<tr><td class=rowhead><?php echo $lang_signup['row_enter_password_again'] ?></td><td class=rowfollow align=left><input type="password" style="width: 200px" class="passagain" data-tip="<?php echo $lang_takesignup['std_passwords_unmatched']?>"/></td></tr>
|
||||
<?php
|
||||
show_image_code ();
|
||||
?>
|
||||
@@ -123,8 +124,11 @@ tr($lang_signup['row_school'], "<select name=school>$schools</select>", 1);
|
||||
<input type=checkbox name=faqverify value=yes><?php echo $lang_signup['checkbox_read_faq'] ?> <br />
|
||||
<input type=checkbox name=ageverify value=yes><?php echo $lang_signup['checkbox_age'] ?></td></tr>
|
||||
<input type=hidden name=hash value=<?php echo $code?>>
|
||||
<tr><td class=toolbox colspan="2" align="center"><font color=red><b><?php echo $lang_signup['text_all_fields_required'] ?></b><p></font><input type=submit value=<?php echo $lang_signup['submit_sign_up'] ?> style='height: 25px'></td></tr>
|
||||
<input type="hidden" name="wantpassword" />
|
||||
<tr><td class=toolbox colspan="2" align="center"><font color=red><b><?php echo $lang_signup['text_all_fields_required'] ?></b><p></font><input id="submit-btn" type=button value=<?php echo $lang_signup['submit_sign_up'] ?> style='height: 25px'></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
render_password_hash_js("signup-form", "wantpassword", "wantpassword", true,"passagain", "wantusername");
|
||||
stdfoot();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
require_once("../include/bittorrent.php");
|
||||
header("Content-Type: text/html; charset=utf-8");
|
||||
if (!mkglobal("username:password"))
|
||||
if (!mkglobal("username"))
|
||||
die();
|
||||
dbconn();
|
||||
require_once(get_langfile_path("", false, get_langfolder_cookie()));
|
||||
@@ -14,15 +14,30 @@ function bark($text = "")
|
||||
$text = ($text == "" ? $lang_takelogin['std_login_fail_note'] : $text);
|
||||
stderr($lang_takelogin['std_login_fail'], $text,false);
|
||||
}
|
||||
if ($iv == "yes")
|
||||
check_code ($_POST['imagehash'], $_POST['imagestring'],'login.php',true);
|
||||
$res = sql_query("SELECT id, passhash, secret, enabled, status, two_step_secret, lang FROM users WHERE username = " . sqlesc($username));
|
||||
if ($iv == "yes") {
|
||||
check_code ($_POST['imagehash'], $_POST['imagestring'],'login.php',true);
|
||||
}
|
||||
//同时支持新旧两种登录方式
|
||||
$useChallengeResponse = \App\Models\Setting::getIsUseChallengeResponseAuthentication();
|
||||
if ($useChallengeResponse) {
|
||||
if (empty($_POST['response'])) {
|
||||
failedlogins("Require response parameter.");
|
||||
}
|
||||
} else {
|
||||
if (empty($_POST['password'])) {
|
||||
failedlogins("Require password parameter.");
|
||||
}
|
||||
}
|
||||
|
||||
$res = sql_query("SELECT id, passhash, secret, auth_key, enabled, status, two_step_secret, lang FROM users WHERE username = " . sqlesc($username));
|
||||
$row = mysql_fetch_array($res);
|
||||
|
||||
if (!$row)
|
||||
failedlogins();
|
||||
if ($row['status'] == 'pending')
|
||||
failedlogins($lang_takelogin['std_user_account_unconfirmed']);
|
||||
if ($row["enabled"] == "no")
|
||||
bark($lang_takelogin['std_account_disabled']);
|
||||
|
||||
if (!empty($row['two_step_secret'])) {
|
||||
if (empty($_POST['two_step_code'])) {
|
||||
@@ -34,72 +49,64 @@ if (!empty($row['two_step_secret'])) {
|
||||
}
|
||||
}
|
||||
$log = "user: {$row['id']}, ip: $ip";
|
||||
if ($row["passhash"] != md5($row["secret"] . $password . $row["secret"])) {
|
||||
$update = [];
|
||||
if ($useChallengeResponse) {
|
||||
$challenge = \Nexus\Database\NexusDB::cache_get(get_challenge_key($username));
|
||||
if (empty($challenge)) {
|
||||
failedlogins("expired");
|
||||
}
|
||||
$log .= ", useChallengeResponse, client response: " . $_POST['response'];
|
||||
} else {
|
||||
$passwordHash = hash('sha256', $row['secret'] . hash('sha256', $_POST['password']));
|
||||
$log .= ", !useChallengeResponse, passwordHash: $passwordHash";
|
||||
if (empty($row['auth_key'])) {
|
||||
//先使用旧的验证方式验证
|
||||
if ($row["passhash"] != md5($row["secret"] . $_POST['password'] . $row["secret"])) {
|
||||
do_log("$log, md5 not equal");
|
||||
login_failedlogins();
|
||||
}
|
||||
$log .= ", no auth_key, upgrade to challenge response";
|
||||
//自动升级为新的验证方式
|
||||
$update['passhash'] = $row['passhash'] = $passwordHash;
|
||||
}
|
||||
//后端自动生成挑战响应
|
||||
$challenge = mksecret();
|
||||
$_POST['response'] = hash_hmac('sha256', $passwordHash, $challenge);
|
||||
$log .= ", server generate response: " . $_POST['response'];
|
||||
}
|
||||
$expectedResponse = hash_hmac('sha256', $row['passhash'], $challenge);
|
||||
$log .= ", expectedResponse: $expectedResponse";
|
||||
if (!hash_equals($expectedResponse, $_POST["response"])) {
|
||||
do_log("$log, !hash_equals");
|
||||
login_failedlogins();
|
||||
}
|
||||
|
||||
\Nexus\Database\NexusDB::cache_del(get_challenge_key($username));
|
||||
do_log("$log, login successful");
|
||||
$userRep = new \App\Repositories\UserRepository();
|
||||
$userRep->saveLoginLog($row['id'], $ip, 'Web', true);
|
||||
|
||||
if ($row["enabled"] == "no")
|
||||
bark($lang_takelogin['std_account_disabled']);
|
||||
|
||||
if (isset($_POST["securelogin"]) && $_POST["securelogin"] == "yes")
|
||||
{
|
||||
$securelogin_indentity_cookie = true;
|
||||
/**
|
||||
* Not IP related
|
||||
* @since 1.8.0
|
||||
*/
|
||||
// $passh = md5($row["passhash"].$ip);
|
||||
$passh = md5($row["passhash"]);
|
||||
$log .= ", secure login == yeah, passhash: {$row['passhash']}, ip: $ip, md5: $passh";
|
||||
}
|
||||
else
|
||||
{
|
||||
$securelogin_indentity_cookie = false;
|
||||
$passh = md5($row["passhash"]);
|
||||
$log .= ", passhash: {$row['passhash']}, md5: $passh";
|
||||
}
|
||||
|
||||
if ($securelogin=='yes' || (isset($_POST["ssl"]) && $_POST["ssl"] == "yes"))
|
||||
{
|
||||
$pprefix = "https://";
|
||||
$ssl = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$pprefix = "http://";
|
||||
$ssl = false;
|
||||
}
|
||||
if ($securetracker=='yes' || (isset($_POST["trackerssl"] ) && $_POST["trackerssl"] == "yes"))
|
||||
{
|
||||
$trackerssl = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$trackerssl = false;
|
||||
}
|
||||
|
||||
do_log($log);
|
||||
|
||||
//update user lang
|
||||
$language = \App\Models\Language::query()->where("site_lang_folder", get_langfolder_cookie())->first();
|
||||
|
||||
if ($language && $language->id != $row["lang"]) {
|
||||
do_log(sprintf("update user: %s lang: %s => %s", $row["id"], $row["lang"], $language->id));
|
||||
\App\Models\User::query()->where("id", $row["id"])->update(["lang" => $language->id]);
|
||||
$update["lang"] = $language->id;
|
||||
}
|
||||
if (empty($row['auth_key'])) {
|
||||
$row['auth_key'] = $update['auth_key'] = hash('sha256', mksecret(32));
|
||||
}
|
||||
if (!empty($update)) {
|
||||
\App\Models\User::query()->where("id", $row["id"])->update($update);
|
||||
clear_user_cache($row["id"]);
|
||||
}
|
||||
|
||||
if (isset($_POST["logout"]) && $_POST["logout"] == "yes")
|
||||
{
|
||||
logincookie($row["id"], $passh,1,900,$securelogin_indentity_cookie, $ssl, $trackerssl);
|
||||
//sessioncookie($row["id"], $passh,true);
|
||||
logincookie($row["id"], $row['auth_key'],900);
|
||||
}
|
||||
else
|
||||
{
|
||||
logincookie($row["id"], $passh,1,get_setting('system.cookie_valid_days', 365) * 86400,$securelogin_indentity_cookie, $ssl, $trackerssl);
|
||||
//sessioncookie($row["id"], $passh,false);
|
||||
logincookie($row["id"], $row['auth_key']);
|
||||
}
|
||||
|
||||
if (!empty($_POST["returnto"]))
|
||||
|
||||
@@ -73,7 +73,7 @@ $res = sql_query("SELECT username FROM users WHERE id = $inviter") or sqlerr(__F
|
||||
$arr = mysql_fetch_assoc($res);
|
||||
$invusername = $arr['username'];
|
||||
}
|
||||
if (!mkglobal("wantusername:wantpassword:passagain:email")) {
|
||||
if (!mkglobal("wantusername:wantpassword:email")) {
|
||||
die();
|
||||
}
|
||||
if ($isPreRegisterEmailAndUsername && $type == 'invite' && !empty($inv["pre_register_username"]) && !empty($inv["pre_register_email"])) {
|
||||
@@ -111,17 +111,17 @@ if (empty($wantusername) || empty($wantpassword) || empty($email) || empty($coun
|
||||
if (strlen($wantusername) > 12)
|
||||
bark($lang_takesignup['std_username_too_long']);
|
||||
|
||||
if ($wantpassword != $passagain)
|
||||
bark($lang_takesignup['std_passwords_unmatched']);
|
||||
//if ($wantpassword != $passagain)
|
||||
// bark($lang_takesignup['std_passwords_unmatched']);
|
||||
|
||||
if (strlen($wantpassword) < 6)
|
||||
bark($lang_takesignup['std_password_too_short']);
|
||||
|
||||
if (strlen($wantpassword) > 40)
|
||||
bark($lang_takesignup['std_password_too_long']);
|
||||
|
||||
if ($wantpassword == $wantusername)
|
||||
bark($lang_takesignup['std_password_equals_username']);
|
||||
//if (strlen($wantpassword) < 6)
|
||||
// bark($lang_takesignup['std_password_too_short']);
|
||||
//
|
||||
//if (strlen($wantpassword) > 40)
|
||||
// bark($lang_takesignup['std_password_too_long']);
|
||||
//
|
||||
//if ($wantpassword == $wantusername)
|
||||
// bark($lang_takesignup['std_password_equals_username']);
|
||||
|
||||
if (!validemail($email))
|
||||
bark($lang_takesignup['std_wrong_email_address_format']);
|
||||
@@ -148,7 +148,8 @@ $arr = mysql_fetch_row($res);
|
||||
*/
|
||||
|
||||
$secret = mksecret();
|
||||
$wantpasshash = md5($secret . $wantpassword . $secret);
|
||||
//$wantpasshash = md5($secret . $wantpassword . $secret);
|
||||
$wantpasshash = hash('sha256', $secret . $wantpassword);
|
||||
$editsecret = ($verification == 'admin' ? '' : $secret);
|
||||
$invite_count = (int) $invite_count;
|
||||
$passkey = md5($wantusername.date("Y-m-d H:i:s").$wantpasshash);
|
||||
@@ -162,13 +163,13 @@ $email = sqlesc($email);
|
||||
$country = sqlesc($country);
|
||||
$gender = sqlesc($gender);
|
||||
$sitelangid = sqlesc(get_langid_from_langcookie());
|
||||
|
||||
$authKey = sqlesc(mksecret());
|
||||
$res_check_user = sql_query("SELECT * FROM users WHERE username = " . $wantusername);
|
||||
|
||||
if(mysql_num_rows($res_check_user) == 1)
|
||||
bark($lang_takesignup['std_username_exists']);
|
||||
|
||||
$ret = sql_query("INSERT INTO users (username, passhash, passkey, secret, editsecret, email, country, gender, status, class, invites, ".($type == 'invite' ? "invited_by," : "")." added, last_access, lang, stylesheet".($showschool == 'yes' ? ", school" : "").", uploaded) VALUES (" . $wantusername . "," . $wantpasshash . "," . sqlesc($passkey) . "," . $secret . "," . $editsecret . "," . $email . "," . $country . "," . $gender . ", 'pending', ".$defaultclass_class.",". $invite_count .", ".($type == 'invite' ? "'$inviter'," : "") ." '". date("Y-m-d H:i:s") ."' , " . " '". date("Y-m-d H:i:s") ."' , ".$sitelangid . ",".$defcss.($showschool == 'yes' ? ",".$school : "").",".($iniupload_main > 0 ? $iniupload_main : 0).")") or sqlerr(__FILE__, __LINE__);
|
||||
$ret = sql_query("INSERT INTO users (username, passhash, passkey, secret, auth_key, editsecret, email, country, gender, status, class, invites, ".($type == 'invite' ? "invited_by," : "")." added, last_access, lang, stylesheet".($showschool == 'yes' ? ", school" : "").", uploaded) VALUES (" . $wantusername . "," . $wantpasshash . "," . sqlesc($passkey) . "," . $secret . "," . $authKey. "," . $editsecret . "," . $email . "," . $country . "," . $gender . ", 'pending', ".$defaultclass_class.",". $invite_count .", ".($type == 'invite' ? "'$inviter'," : "") ." '". date("Y-m-d H:i:s") ."' , " . " '". date("Y-m-d H:i:s") ."' , ".$sitelangid . ",".$defcss.($showschool == 'yes' ? ",".$school : "").",".($iniupload_main > 0 ? $iniupload_main : 0).")") or sqlerr(__FILE__, __LINE__);
|
||||
$id = mysql_insert_id();
|
||||
fire_event("user_created", \App\Models\User::query()->find($id, \App\Models\User::$commonFields));
|
||||
$tmpInviteCount = get_setting('main.tmp_invite_count');
|
||||
|
||||
@@ -3,7 +3,7 @@ require "../include/bittorrent.php";
|
||||
dbconn();
|
||||
require_once(get_langfile_path());
|
||||
loggedinorreturn();
|
||||
$userInfo = \App\Models\User::query()->findOrFail($CURUSER["id"], \App\Models\User::$commonFields);
|
||||
$userInfo = \App\Models\User::query()->findOrFail($CURUSER["id"]);
|
||||
function bark($msg) {
|
||||
stdhead();
|
||||
global $lang_usercp;
|
||||
@@ -41,12 +41,15 @@ function getimageheight ($imagewidth, $imageheight)
|
||||
}
|
||||
return $imageheight;
|
||||
}
|
||||
function form($name) {
|
||||
return print("<form method=post action=usercp.php><input type=hidden name=action value=".htmlspecialchars($name)."><input type=hidden name=type value=save>");
|
||||
function form($name, $type = "save", $id = "") {
|
||||
if ($id == "") {
|
||||
$id = "form" . random_str();
|
||||
}
|
||||
return print("<form method=post action=usercp.php id=\"".$id."\"><input type=hidden name=action value=".htmlspecialchars($name)."><input type=hidden name=type value={$type}>");
|
||||
}
|
||||
function submit() {
|
||||
function submit($type = "submit") {
|
||||
global $lang_usercp;
|
||||
print("<tr><td class=\"rowhead\" valign=\"top\" align=\"right\">".$lang_usercp['row_save_settings']."</td><td class=\"rowfollow\" valign=\"top\" align=left><input type=submit value=\"".$lang_usercp['submit_save_settings']."\"></td></tr>"."</form>");
|
||||
print("<tr><td class=\"rowhead\" valign=\"top\" align=\"right\">".$lang_usercp['row_save_settings']."</td><td class=\"rowfollow\" valign=\"top\" align=left><input type=".$type." value=\"".$lang_usercp['submit_save_settings']."\"></td></tr>");
|
||||
}
|
||||
function format_tz($a)
|
||||
{
|
||||
@@ -174,11 +177,11 @@ if ($action){
|
||||
}
|
||||
|
||||
usercpmenu ("personal");
|
||||
form ("personal");
|
||||
print ("<table border=0 cellspacing=0 cellpadding=5 width=".CONTENT_WIDTH.">");
|
||||
if ($type == 'saved')
|
||||
print("<tr><td colspan=2 class=\"heading\" valign=\"top\" align=\"center\"><font color=red>".$lang_usercp['text_saved']."</font></td></tr>\n");
|
||||
|
||||
form ("personal");
|
||||
tr_small($lang_usercp['row_account_parked'],
|
||||
"<input type=checkbox name=parked" . ($CURUSER["parked"] == "yes" ? " checked" : "") . " value=yes>".$lang_usercp['checkbox_pack_my_account']."<br /><font class=small size=1>".$lang_usercp['text_account_pack_note']."</font>"
|
||||
,1);
|
||||
@@ -214,7 +217,7 @@ tr($lang_usercp['row_school'], "<select name=school>$schools</select>", 1);
|
||||
"\"><br />\n".$lang_usercp['text_avatar_note'].($enablebitbucket_main == 'yes' ? $lang_usercp['text_bitbucket_note'] : ""),1);
|
||||
tr($lang_usercp['row_info'], "<textarea name=\"info\" style=\"width:700px\" rows=\"10\" >" . htmlspecialchars($CURUSER["info"]) . "</textarea><br />".$lang_usercp['text_info_note'], 1);
|
||||
submit();
|
||||
print("</table>");
|
||||
print("</table></form>");
|
||||
stdfoot();
|
||||
die;
|
||||
break;
|
||||
@@ -398,6 +401,7 @@ tr($lang_usercp['row_school'], "<select name=school>$schools</select>", 1);
|
||||
}
|
||||
stdhead($lang_usercp['head_control_panel'].$lang_usercp['head_tracker_settings']);
|
||||
usercpmenu ("tracker");
|
||||
form ("tracker");
|
||||
$brsectiontype = $browsecatmode;
|
||||
$spsectiontype = $specialcatmode;
|
||||
if ($enablespecial == 'yes' && get_user_class() >= get_setting('authority.view_special_torrent'))
|
||||
@@ -451,7 +455,6 @@ if ($showaudiocodec) $audiocodecs = searchbox_item_list("audiocodecs");
|
||||
}
|
||||
*/
|
||||
print ("<table border=0 cellspacing=0 cellpadding=5 width=".CONTENT_WIDTH.">");
|
||||
form ("tracker");
|
||||
if ($type == 'saved')
|
||||
print("<tr><td colspan=2 class=\"heading\" valign=\"top\" align=\"center\"><font color=red>".$lang_usercp['text_saved']."</font></td></tr>\n");
|
||||
if ($emailnotify_smtp=='yes' && $smtptype != 'none')
|
||||
@@ -654,7 +657,7 @@ tr_small($lang_usercp['row_funbox'],"<input type=checkbox name=showfb".($CURUSER
|
||||
<b>".$lang_usercp['text_comments_reviews'].": </b><br /><input type=checkbox name=showcomnum ".($CURUSER['showcomnum'] == 'yes' ? " checked" : "")." value=yes>".$lang_usercp['text_show_comment_number'].($showtooltipsetting ? "<select name=\"showlastcom\" style=\"width: 70px;\"><option value=\"yes\" ".($CURUSER['showlastcom'] != 'no' ? " selected" : "").">".$lang_usercp['select_with']."</option><option value=\"no\" ".($CURUSER['showlastcom'] == 'no' ? " selected" : "").">".$lang_usercp['select_without']."</option></select>".$lang_usercp['text_last_comment_on_tooltip'] : ""), 1);
|
||||
|
||||
submit();
|
||||
print("</table>");
|
||||
print("</table></form>");
|
||||
stdfoot();
|
||||
die;
|
||||
break;
|
||||
@@ -689,8 +692,8 @@ tr_small($lang_usercp['row_funbox'],"<input type=checkbox name=showfb".($CURUSER
|
||||
}
|
||||
stdhead($lang_usercp['head_control_panel'].$lang_usercp['head_forum_settings'],true);
|
||||
usercpmenu ("forum");
|
||||
form ("forum");
|
||||
print ("<table border=0 cellspacing=0 cellpadding=5 width=".CONTENT_WIDTH.">");
|
||||
form ("forum");
|
||||
if ($type == 'saved')
|
||||
print("<tr><td colspan=2 class=\"heading\" valign=\"top\" align=\"center\"><font color=red>".$lang_usercp['text_saved']."</font></td></tr>\n");
|
||||
|
||||
@@ -703,20 +706,26 @@ tr_small($lang_usercp['row_funbox'],"<input type=checkbox name=showfb".($CURUSER
|
||||
tr_small($lang_usercp['row_click_on_topic'], "<input type=radio name=clicktopic" . ($CURUSER["clicktopic"] == "firstpage" ? " checked" : "") . " value=\"firstpage\">".$lang_usercp['text_go_to_first_page']."<input type=radio name=clicktopic" . ($CURUSER["clicktopic"] == "lastpage" ? " checked" : "") . " value=\"lastpage\">".$lang_usercp['text_go_to_last_page'],1);
|
||||
tr_small($lang_usercp['row_forum_signature'], "<textarea name=signature style=\"width:700px\" rows=10>" . $CURUSER['signature'] . "</textarea><br />".$lang_usercp['text_signature_note'],1);
|
||||
submit();
|
||||
print("</table>");
|
||||
print("</table></form>");
|
||||
stdfoot();
|
||||
die;
|
||||
break;
|
||||
case "security":
|
||||
if ($type == 'confirm') {
|
||||
$oldpassword = $_POST['oldpassword'];
|
||||
if (!$oldpassword){
|
||||
$response = $_POST['response'];
|
||||
if (!$response){
|
||||
stderr($lang_usercp['std_error'], $lang_usercp['std_enter_old_password'].goback(), 0);
|
||||
die;
|
||||
}elseif ($CURUSER["passhash"] != md5($CURUSER["secret"] . $oldpassword . $CURUSER["secret"])){
|
||||
stderr($lang_usercp['std_error'], $lang_usercp['std_wrong_password_note'].goback(), 0);
|
||||
die;
|
||||
}else
|
||||
}
|
||||
//验证旧密码
|
||||
$challenge = \Nexus\Database\NexusDB::cache_get(get_challenge_key($userInfo->username));
|
||||
if (empty($challenge)) {
|
||||
stderr($lang_usercp['std_error'], "expired!".goback(), 0);
|
||||
}
|
||||
$expectedResponse = hash_hmac('sha256', $userInfo->passhash, $challenge);
|
||||
if (!hash_equals($expectedResponse, $response)) {
|
||||
stderr($lang_usercp['std_error'], $lang_usercp['std_wrong_password_note'].goback(), 0);
|
||||
}
|
||||
|
||||
$updateset = array();
|
||||
$changedemail = 0;
|
||||
$passupdated = 0;
|
||||
@@ -724,7 +733,7 @@ tr_small($lang_usercp['row_funbox'],"<input type=checkbox name=showfb".($CURUSER
|
||||
$resetpasskey = $_POST["resetpasskey"];
|
||||
$email = mysql_real_escape_string( htmlspecialchars( trim($_POST["email"]) ));
|
||||
$chpassword = $_POST["chpassword"];
|
||||
$passagain = $_POST["passagain"];
|
||||
// $passagain = $_POST["passagain"];
|
||||
$privacy = $_POST["privacy"];
|
||||
$twoStepSecret = $_POST['two_step_secret'] ?? '';
|
||||
$twoStepSecretHash = $_POST['two_step_code'];
|
||||
@@ -747,47 +756,30 @@ tr_small($lang_usercp['row_funbox'],"<input type=checkbox name=showfb".($CURUSER
|
||||
}
|
||||
|
||||
if ($chpassword != "") {
|
||||
if ($chpassword == $CURUSER["username"]) {
|
||||
stderr($lang_usercp['std_error'], $lang_usercp['std_password_equals_username'].goback("-2"), 0);
|
||||
die;
|
||||
}
|
||||
if (strlen($chpassword) > 40) {
|
||||
stderr($lang_usercp['std_error'], $lang_usercp['std_password_too_long'].goback("-2"), 0);
|
||||
die;
|
||||
}
|
||||
if (strlen($chpassword) < 6) {
|
||||
stderr($lang_usercp['std_error'], $lang_usercp['std_password_too_short'].goback("-2"), 0);
|
||||
die;
|
||||
}
|
||||
if ($chpassword != $passagain) {
|
||||
stderr($lang_usercp['std_error'], $lang_usercp['std_passwords_unmatched'].goback("-2"), 0);
|
||||
die;
|
||||
}
|
||||
// if ($chpassword == $CURUSER["username"]) {
|
||||
// stderr($lang_usercp['std_error'], $lang_usercp['std_password_equals_username'].goback("-2"), 0);
|
||||
// die;
|
||||
// }
|
||||
// if (strlen($chpassword) > 40) {
|
||||
// stderr($lang_usercp['std_error'], $lang_usercp['std_password_too_long'].goback("-2"), 0);
|
||||
// die;
|
||||
// }
|
||||
// if (strlen($chpassword) < 6) {
|
||||
// stderr($lang_usercp['std_error'], $lang_usercp['std_password_too_short'].goback("-2"), 0);
|
||||
// die;
|
||||
// }
|
||||
// if ($chpassword != $passagain) {
|
||||
// stderr($lang_usercp['std_error'], $lang_usercp['std_passwords_unmatched'].goback("-2"), 0);
|
||||
// die;
|
||||
// }
|
||||
|
||||
$sec = mksecret();
|
||||
$passhash = md5($sec . $chpassword . $sec);
|
||||
// $passhash = md5($sec . $chpassword . $sec);
|
||||
$passhash = hash('sha256', $sec . $chpassword);
|
||||
$updateset[] = "secret = " . sqlesc($sec);
|
||||
$updateset[] = "passhash = " . sqlesc($passhash);
|
||||
|
||||
//die($securelogin . base64_decode($_COOKIE["c_secure_login"]));
|
||||
if ($_COOKIE["c_secure_login"] == base64("yeah"))
|
||||
{
|
||||
$passh = md5($passhash . $_SERVER["REMOTE_ADDR"]);
|
||||
$securelogin_indentity_cookie = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$passh = md5($passhash);
|
||||
$securelogin_indentity_cookie = false;
|
||||
}
|
||||
|
||||
if($_COOKIE["c_secure_ssl"] == base64("yeah"))
|
||||
$ssl = true;
|
||||
else
|
||||
$ssl = false;
|
||||
|
||||
logincookie($CURUSER["id"], $passh ,1,get_setting('system.cookie_valid_days', 365) * 86400,$securelogin_indentity_cookie,$ssl);
|
||||
//sessioncookie($CURUSER["id"], $passh);
|
||||
logincookie($CURUSER["id"], $userInfo->auth_key);
|
||||
$passupdated = 1;
|
||||
}
|
||||
|
||||
@@ -864,13 +856,15 @@ EOD;
|
||||
if ($privacyupdated == 1)
|
||||
$to .= "&privacy=1";
|
||||
clear_user_cache($CURUSER["id"]);
|
||||
\Nexus\Database\NexusDB::cache_get(get_challenge_key($userInfo->username));
|
||||
header("Location: $to");
|
||||
}
|
||||
stdhead($lang_usercp['head_control_panel'].$lang_usercp['head_security_settings']);
|
||||
usercpmenu ("security");
|
||||
form ("security", $type == "save" ? "confirm" : "save","security");
|
||||
print ("<table border=0 cellspacing=0 cellpadding=5 width=".CONTENT_WIDTH.">");
|
||||
if ($type == 'save') {
|
||||
print("<form method=post action=usercp.php><input type=hidden name=action value=security><input type=hidden name=type value=confirm>");
|
||||
// print("<form method=post action=usercp.php><input type=hidden name=action value=security><input type=hidden name=type value=confirm>");
|
||||
$resetpasskey = $_POST["resetpasskey"];
|
||||
$resetauthkey = $_POST["resetauthkey"];
|
||||
$email = mysql_real_escape_string( htmlspecialchars( trim($_POST["email"]) ));
|
||||
@@ -885,20 +879,23 @@ EOD;
|
||||
print("<input type=\"hidden\" name=\"resetauthkey\" value=\"1\">");
|
||||
print("<input type=\"hidden\" name=\"email\" value=\"$email\">");
|
||||
print("<input type=\"hidden\" name=\"chpassword\" value=\"$chpassword\">");
|
||||
print("<input type=\"hidden\" name=\"passagain\" value=\"$passagain\">");
|
||||
// print("<input type=\"hidden\" name=\"passagain\" value=\"$passagain\">");
|
||||
print("<input type=\"hidden\" name=\"privacy\" value=\"$privacy\">");
|
||||
print("<input type=\"hidden\" name=\"two_step_secret\" value=\"$two_step_secret\">");
|
||||
print("<input type=\"hidden\" name=\"two_step_code\" value=\"$two_step_code\">");
|
||||
Print("<tr><td class=\"rowhead nowrap\" valign=\"top\" align=\"right\" width=1%>".$lang_usercp['row_security_check']."</td><td valign=\"top\" align=\"left\" width=\"99%\"><input type=password name=oldpassword style=\"width: 200px\"><br /><font class=small>".$lang_usercp['text_security_check_note']."</font></td></tr>\n");
|
||||
do_action("usercp_security_update_confirm", $_POST);
|
||||
submit();
|
||||
print("</table>");
|
||||
Print("<tr><td class=\"rowhead nowrap\" valign=\"top\" align=\"right\" width=1%>".$lang_usercp['row_security_check']."</td><td valign=\"top\" align=\"left\" width=\"99%\"><input type=password class=oldpassword style=\"width: 200px\"><br /><font class=small>".$lang_usercp['text_security_check_note']."</font></td></tr>\n");
|
||||
print('<input type=hidden name=username value="'.$CURUSER["username"].'">');
|
||||
print('<input type=hidden name=response>');
|
||||
do_action("usercp_security_update_confirm", $_POST);
|
||||
submit("button");
|
||||
print("</table></form>");
|
||||
render_password_challenge_js("security", "username", "oldpassword");
|
||||
stdfoot();
|
||||
die;
|
||||
}
|
||||
if ($type == 'saved')
|
||||
print("<tr><td colspan=2 class=\"heading\" valign=\"top\" align=\"center\"><font color=red>".$lang_usercp['text_saved'].($_GET["mail"] == "1" ? $lang_usercp['std_confirmation_email_sent'] : "")." ".($_GET["passkey"] == "1" ? $lang_usercp['std_passkey_reset'] : "")." ".($_GET["password"] == "1" ? $lang_usercp['std_password_changed'] : "")." ".($_GET["privacy"] == "1" ? $lang_usercp['std_privacy_level_updated'] : "")."</font></td></tr>\n");
|
||||
form ("security");
|
||||
|
||||
tr_small($lang_usercp['row_reset_passkey'],"<input type=checkbox name=resetpasskey value=1 />".$lang_usercp['checkbox_reset_my_passkey']."<br /><font class=small>".$lang_usercp['text_reset_passkey_note']."</font>", 1);
|
||||
// tr_small($lang_usercp['row_reset_authkey'],"<input type=checkbox name=resetauthkey value=1 />".$lang_usercp['checkbox_reset_my_authkey']."<br /><font class=small>".$lang_usercp['text_reset_authkey_note']."</font>", 1);
|
||||
|
||||
@@ -927,11 +924,14 @@ EOD;
|
||||
if ($disableemailchange != 'no' && $smtptype != 'none') //system-wide setting
|
||||
tr_small($lang_usercp['row_email_address'], "<input type=\"text\" name=\"email\" style=\"width: 200px\" value=\"" . htmlspecialchars($CURUSER["email"]) . "\" /> <br /><font class=small>".$lang_usercp['text_email_address_note']."</font>", 1);
|
||||
do_action("usercp_security_setting_form");
|
||||
tr_small($lang_usercp['row_change_password'], "<input type=\"password\" name=\"chpassword\" style=\"width: 200px\" />", 1);
|
||||
tr_small($lang_usercp['row_type_password_again'], "<input type=\"password\" name=\"passagain\" style=\"width: 200px\" />", 1);
|
||||
tr_small($lang_usercp['row_change_password'], "<input type=\"password\" class=\"password\" style=\"width: 200px\" />", 1);
|
||||
print('<input type="hidden" name="chpassword" />');
|
||||
tr_small($lang_usercp['row_type_password_again'], "<input type=\"password\" class=\"passagain\" style=\"width: 200px\" />", 1);
|
||||
tr_small($lang_usercp['row_privacy_level'], priv("normal", $lang_usercp['radio_normal']) . " " . priv("low", $lang_usercp['radio_low']) . " " . priv("strong", $lang_usercp['radio_strong']), 1);
|
||||
submit();
|
||||
print("</table>");
|
||||
submit("button");
|
||||
print("</table></form>");
|
||||
|
||||
render_password_hash_js("security", "password", "chpassword", false,"passagain");
|
||||
stdfoot();
|
||||
die;
|
||||
break;
|
||||
|
||||
8
resources/lang/en/signup.php
Normal file
8
resources/lang/en/signup.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'passwords_unmatched' => "The passwords didn't match! Must've typoed. Try again.",
|
||||
'password_too_short' => "Sorry, password is too short (min is 6 chars)",
|
||||
'password_too_long' => "Sorry, password is too long (max is 40 chars)",
|
||||
'password_equals_username' => "Sorry, password cannot be same as user name.",
|
||||
];
|
||||
8
resources/lang/zh_CN/signup.php
Normal file
8
resources/lang/zh_CN/signup.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'passwords_unmatched' => "两次输入的密码不一致!请重试。",
|
||||
'password_too_short' => "对不起,密码过短(至少6个字符)",
|
||||
'password_too_long' => "对不起,密码过长(至多40个字符)",
|
||||
'password_equals_username' => "对不起,用户名和密码不能相同。",
|
||||
];
|
||||
8
resources/lang/zh_TW/signup.php
Normal file
8
resources/lang/zh_TW/signup.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'passwords_unmatched' => "兩次輸入的密碼不壹致!請重試。",
|
||||
'password_too_short' => "對不起,密碼過短(至少6個字符)",
|
||||
'password_too_long' => "對不起,密碼過長(至多40個字符)",
|
||||
'password_equals_username' => "對不起,用戶名和密碼不能相同。",
|
||||
];
|
||||
@@ -6,6 +6,8 @@ Route::group(['middleware' => ['auth.nexus:passkey', 'locale']], function () {
|
||||
});
|
||||
|
||||
|
||||
Route::post('challenge', [\App\Http\Controllers\AuthenticateController::class, 'challenge']);
|
||||
|
||||
Route::post('nastools/approve', [\App\Http\Controllers\AuthenticateController::class, 'nasToolsApprove']);
|
||||
Route::get('iyuu/approve', [\App\Http\Controllers\AuthenticateController::class, 'iyuuApprove']);
|
||||
Route::post('ammds/approve', [\App\Http\Controllers\AuthenticateController::class, 'ammdsApprove']);
|
||||
|
||||
Reference in New Issue
Block a user