diff --git a/app/Api/Controllers/UserController.php b/app/Api/Controllers/UserController.php index 8d8a5d5..39449a5 100644 --- a/app/Api/Controllers/UserController.php +++ b/app/Api/Controllers/UserController.php @@ -24,7 +24,9 @@ class UserController extends Controller $keyword = $request->keyword; $list = User::where('username', 'like', "%$keyword%") - ->where('privacy', 0) + ->whereHas('setting', function ($query) { + $query->where('privacy', 1); + }) ->limit(3) ->get(); diff --git a/app/Models/Comment.php b/app/Models/Comment.php index 1281df6..7ec86cf 100644 --- a/app/Models/Comment.php +++ b/app/Models/Comment.php @@ -2,17 +2,14 @@ namespace App\Models; +use App\Models\Traits\BelongsToUser; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\SoftDeletes; class Comment extends Model { use SoftDeletes; - - public function user(): BelongsTo - { - return $this->belongsTo(User::class); - } + use BelongsToUser; public function parent(): BelongsTo { diff --git a/app/Models/Dynamic.php b/app/Models/Dynamic.php index 9f91b7e..f0f4a1a 100644 --- a/app/Models/Dynamic.php +++ b/app/Models/Dynamic.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Models\Traits\BelongsToUser; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\MorphMany; use Illuminate\Database\Eloquent\SoftDeletes; @@ -11,16 +12,12 @@ use Illuminate\Support\Str; class Dynamic extends Model { use SoftDeletes; + use BelongsToUser; protected $casts = [ 'pictures' => 'json', ]; - public function user() - { - return $this->belongsTo(User::class); - } - public function getPicturesUrlAttribute(): array { $pictures = $this->getAttribute('pictures'); diff --git a/app/Models/Group.php b/app/Models/Group.php index 0578744..9a7d2ca 100644 --- a/app/Models/Group.php +++ b/app/Models/Group.php @@ -2,7 +2,9 @@ namespace App\Models; +use App\Models\Traits\BelongsToUser; + class Group extends Model { - + use BelongsToUser; } diff --git a/app/Models/Like.php b/app/Models/Like.php index 5feda4c..8e6cc70 100644 --- a/app/Models/Like.php +++ b/app/Models/Like.php @@ -2,16 +2,14 @@ namespace App\Models; +use App\Models\Traits\BelongsToUser; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\MorphTo; class Like extends Model { - public function user(): BelongsTo - { - return $this->belongsTo(User::class); - } + use BelongsToUser; public function likeable(): MorphTo { diff --git a/app/Models/Traits/BelongsToUser.php b/app/Models/Traits/BelongsToUser.php new file mode 100644 index 0000000..8a4835f --- /dev/null +++ b/app/Models/Traits/BelongsToUser.php @@ -0,0 +1,14 @@ +belongsTo(User::class); + } +} \ No newline at end of file diff --git a/app/Models/User.php b/app/Models/User.php index de8918c..d8ad9f1 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -30,6 +30,7 @@ class User extends Authenticatable protected static function boot() { parent::boot(); + self::created(function ($model) { $model->info()->create([ 'nickname' => '用户'.substr($model->username, -4), @@ -40,6 +41,7 @@ class User extends Authenticatable 'FaceUrl' => '', ]; app('im')->send('im_open_login_svc', 'account_import', $params); + $model->setting()->create(); }); } @@ -68,4 +70,9 @@ class User extends Authenticatable { return $this->hasOne(UserInfo::class); } + + public function setting(): HasOne + { + return $this->hasOne(UserSetting::class); + } } diff --git a/app/Models/UserInfo.php b/app/Models/UserInfo.php index 38d7738..c972d88 100644 --- a/app/Models/UserInfo.php +++ b/app/Models/UserInfo.php @@ -2,23 +2,11 @@ namespace App\Models; -use Illuminate\Database\Eloquent\Relations\BelongsTo; +use App\Models\Traits\BelongsToUser; class UserInfo extends Model { + use BelongsToUser; protected $primaryKey = 'user_id'; - - protected static function boot() - { - parent::boot(); - - self::created(function ($model) { - }); - } - - public function user(): BelongsTo - { - return $this->belongsTo(User::class); - } } diff --git a/app/Models/UserSetting.php b/app/Models/UserSetting.php new file mode 100644 index 0000000..c80d3c5 --- /dev/null +++ b/app/Models/UserSetting.php @@ -0,0 +1,21 @@ +secret_key = app('pragmarx.google2fa')->generateSecretKey(); + }); + } +} diff --git a/composer.json b/composer.json index 6fd5296..e8aabd3 100644 --- a/composer.json +++ b/composer.json @@ -16,6 +16,7 @@ "laravel/framework": "^8.75", "laravel/sanctum": "^2.11", "laravel/tinker": "^2.5", + "pragmarx/google2fa-laravel": "^2.0", "tencent/tls-sig-api-v2": "^1.1" }, "require-dev": { diff --git a/composer.lock b/composer.lock index f14e3b9..5bfa5c8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7855730e25a112fd12d46eb09796ef2b", + "content-hash": "38994ac810d984cb2c4309f91a92a625", "packages": [ { "name": "adbario/php-dot-notation", @@ -3472,6 +3472,79 @@ }, "time": "2022-01-27T09:35:39+00:00" }, + { + "name": "paragonie/constant_time_encoding", + "version": "v2.6.3", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "58c3f47f650c94ec05a151692652a868995d2938" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/58c3f47f650c94ec05a151692652a868995d2938", + "reference": "58c3f47f650c94ec05a151692652a868995d2938", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": "^7|^8" + }, + "require-dev": { + "phpunit/phpunit": "^6|^7|^8|^9", + "vimeo/psalm": "^1|^2|^3|^4" + }, + "type": "library", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "time": "2022-06-14T06:56:20+00:00" + }, { "name": "phpoption/phpoption", "version": "1.8.1", @@ -3602,6 +3675,219 @@ }, "time": "2013-05-22T20:46:20+00:00" }, + { + "name": "pragmarx/google2fa", + "version": "v8.0.1", + "source": { + "type": "git", + "url": "https://github.com/antonioribeiro/google2fa.git", + "reference": "80c3d801b31fe165f8fe99ea085e0a37834e1be3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/antonioribeiro/google2fa/zipball/80c3d801b31fe165f8fe99ea085e0a37834e1be3", + "reference": "80c3d801b31fe165f8fe99ea085e0a37834e1be3", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "paragonie/constant_time_encoding": "^1.0|^2.0", + "php": "^7.1|^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.18", + "phpunit/phpunit": "^7.5.15|^8.5|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "PragmaRX\\Google2FA\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Antonio Carlos Ribeiro", + "email": "acr@antoniocarlosribeiro.com", + "role": "Creator & Designer" + } + ], + "description": "A One Time Password Authentication package, compatible with Google Authenticator.", + "keywords": [ + "2fa", + "Authentication", + "Two Factor Authentication", + "google2fa" + ], + "support": { + "issues": "https://github.com/antonioribeiro/google2fa/issues", + "source": "https://github.com/antonioribeiro/google2fa/tree/v8.0.1" + }, + "time": "2022-06-13T21:57:56+00:00" + }, + { + "name": "pragmarx/google2fa-laravel", + "version": "v2.0.2", + "source": { + "type": "git", + "url": "https://github.com/antonioribeiro/google2fa-laravel.git", + "reference": "d8243b8f812472f1112716c5462157e0ec128fce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/antonioribeiro/google2fa-laravel/zipball/d8243b8f812472f1112716c5462157e0ec128fce", + "reference": "d8243b8f812472f1112716c5462157e0ec128fce", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "laravel/framework": ">=5.4.36|^8.0|^9.0", + "php": ">=7.0", + "pragmarx/google2fa-qrcode": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "bacon/bacon-qr-code": "^2.0", + "orchestra/testbench": "3.4.*|3.5.*|3.6.*|3.7.*|4.*|5.*|6.*", + "phpunit/phpunit": "~5|~6|~7|~8|~9" + }, + "suggest": { + "bacon/bacon-qr-code": "Required to generate inline QR Codes.", + "pragmarx/recovery": "Generate recovery codes." + }, + "type": "library", + "extra": { + "component": "package", + "frameworks": [ + "Laravel" + ], + "branch-alias": { + "dev-master": "0.2-dev" + }, + "laravel": { + "providers": [ + "PragmaRX\\Google2FALaravel\\ServiceProvider" + ], + "aliases": { + "Google2FA": "PragmaRX\\Google2FALaravel\\Facade" + } + } + }, + "autoload": { + "psr-4": { + "PragmaRX\\Google2FALaravel\\": "src/", + "PragmaRX\\Google2FALaravel\\Tests\\": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Antonio Carlos Ribeiro", + "email": "acr@antoniocarlosribeiro.com", + "role": "Creator & Designer" + } + ], + "description": "A One Time Password Authentication package, compatible with Google Authenticator.", + "keywords": [ + "Authentication", + "Two Factor Authentication", + "google2fa", + "laravel" + ], + "support": { + "issues": "https://github.com/antonioribeiro/google2fa-laravel/issues", + "source": "https://github.com/antonioribeiro/google2fa-laravel/tree/v2.0.2" + }, + "time": "2022-03-08T18:03:04+00:00" + }, + { + "name": "pragmarx/google2fa-qrcode", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/antonioribeiro/google2fa-qrcode.git", + "reference": "ce4d8a729b6c93741c607cfb2217acfffb5bf76b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/antonioribeiro/google2fa-qrcode/zipball/ce4d8a729b6c93741c607cfb2217acfffb5bf76b", + "reference": "ce4d8a729b6c93741c607cfb2217acfffb5bf76b", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.1", + "pragmarx/google2fa": ">=4.0" + }, + "require-dev": { + "bacon/bacon-qr-code": "^2.0", + "chillerlan/php-qrcode": "^1.0|^2.0|^3.0|^4.0", + "khanamiryan/qrcode-detector-decoder": "^1.0", + "phpunit/phpunit": "~4|~5|~6|~7|~8|~9" + }, + "suggest": { + "bacon/bacon-qr-code": "For QR Code generation, requires imagick", + "chillerlan/php-qrcode": "For QR Code generation" + }, + "type": "library", + "extra": { + "component": "package", + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "PragmaRX\\Google2FAQRCode\\": "src/", + "PragmaRX\\Google2FAQRCode\\Tests\\": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Antonio Carlos Ribeiro", + "email": "acr@antoniocarlosribeiro.com", + "role": "Creator & Designer" + } + ], + "description": "QR Code package for Google2FA", + "keywords": [ + "2fa", + "Authentication", + "Two Factor Authentication", + "google2fa", + "qr code", + "qrcode" + ], + "support": { + "issues": "https://github.com/antonioribeiro/google2fa-qrcode/issues", + "source": "https://github.com/antonioribeiro/google2fa-qrcode/tree/v3.0.0" + }, + "time": "2021-08-15T12:53:48+00:00" + }, { "name": "psr/container", "version": "1.1.2", diff --git a/config/google2fa.php b/config/google2fa.php new file mode 100644 index 0000000..a04fefd --- /dev/null +++ b/config/google2fa.php @@ -0,0 +1,83 @@ + env('OTP_ENABLED', true), + + /* + * Lifetime in minutes. + * + * In case you need your users to be asked for a new one time passwords from time to time. + */ + 'lifetime' => env('OTP_LIFETIME', 0), // 0 = eternal + + /* + * Renew lifetime at every new request. + */ + 'keep_alive' => env('OTP_KEEP_ALIVE', true), + + /* + * Auth container binding. + */ + 'auth' => 'auth', + + /* + * Guard. + */ + 'guard' => '', + + /* + * 2FA verified session var. + */ + 'session_var' => 'google2fa', + + /* + * One Time Password request input name. + */ + 'otp_input' => 'one_time_password', + + /* + * One Time Password Window. + */ + 'window' => 1, + + /* + * Forbid user to reuse One Time Passwords. + */ + 'forbid_old_passwords' => false, + + /* + * User's table column for google2fa secret. + */ + 'otp_secret_column' => 'google2fa_secret', + + /* + * One Time Password View. + */ + 'view' => 'google2fa.index', + + /* + * One Time Password error message. + */ + 'error_messages' => [ + 'wrong_otp' => "The 'One Time Password' typed was wrong.", + 'cannot_be_empty' => 'One Time Password cannot be empty.', + 'unknown' => 'An unknown error has occurred. Please try again.', + ], + + /* + * Throw exceptions or just fire events? + */ + 'throw_exceptions' => env('OTP_THROW_EXCEPTION', true), + + /* + * Which image backend to use for generating QR codes? + * + * Supports imagemagick, svg and eps + */ + 'qrcode_image_backend' => \PragmaRX\Google2FALaravel\Support\Constants::QRCODE_IMAGE_BACKEND_SVG, + +]; diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php index 203458f..5bc105c 100644 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -20,8 +20,6 @@ class CreateUsersTable extends Migration $table->string('mobile')->index()->nullable(); $table->string('email')->index()->nullable(); $table->string('mnemonic')->nullable(); - $table->boolean('privacy')->default(1)->index(); - $table->rememberToken(); $table->timestamps(); $table->softDeletes(); }); diff --git a/database/migrations/2022_11_01_161556_create_user_settings_table.php b/database/migrations/2022_11_01_161556_create_user_settings_table.php new file mode 100644 index 0000000..fb87714 --- /dev/null +++ b/database/migrations/2022_11_01_161556_create_user_settings_table.php @@ -0,0 +1,34 @@ +unsignedBigInteger('user_id')->primary(); + $table->boolean('google2fa')->default(0)->comment('开启2步验证'); + $table->string('secret_key', 32)->nullable()->comment('验证器密钥'); + $table->boolean('privacy')->default(1)->index()->comment('是否允许搜索我'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('user_settings'); + } +}