From a59dae0c42ef4c97ad266e6b50363b29900b88de Mon Sep 17 00:00:00 2001 From: kimchanhyung98 Date: Thu, 4 Apr 2024 17:33:24 +0900 Subject: [PATCH] =?UTF-8?q?=ED=9A=8C=EC=9B=90=20=EC=88=98=EC=A0=95,=20?= =?UTF-8?q?=ED=83=88=ED=87=B4=20=EC=B6=94=EA=B0=80=20(#67)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update users migration, nickname unique * Update users nickname * Update UserResource * Fix UserController namespace * Create user language(localization) * Create User Update&Destroy 초안 작성 * Update user destroy, provider disconnect * Update user edit * Fix return type&comment --- .../Controllers/Account/AppleController.php | 6 +- .../Controllers/Account/KakaoController.php | 6 +- .../Controllers/Account/SignInController.php | 8 +-- .../Controllers/Account/SignUpController.php | 13 ++-- .../{Account => User}/UserController.php | 10 ++- .../User/UserDestroyController.php | 65 +++++++++++++++++++ .../Controllers/User/UserUpdateController.php | 44 +++++++++++++ app/Http/Requests/Account/SignUpRequest.php | 2 +- app/Http/Resources/Account/UserResource.php | 1 - app/Models/User.php | 14 ++++ .../2014_10_12_000000_create_users_table.php | 3 +- lang/ko/user.php | 13 ++++ routes/api.php | 8 ++- 13 files changed, 160 insertions(+), 33 deletions(-) rename app/Http/Controllers/{Account => User}/UserController.php (53%) create mode 100644 app/Http/Controllers/User/UserDestroyController.php create mode 100644 app/Http/Controllers/User/UserUpdateController.php create mode 100644 lang/ko/user.php diff --git a/app/Http/Controllers/Account/AppleController.php b/app/Http/Controllers/Account/AppleController.php index 0f254ff..e36ddf6 100644 --- a/app/Http/Controllers/Account/AppleController.php +++ b/app/Http/Controllers/Account/AppleController.php @@ -18,11 +18,9 @@ class AppleController extends Controller public const string PROVIDER = 'apple'; /** - * SocialLogin (Apple) - * - * @return AccessTokenResource + * 소셜로그인 (애플) */ - public function __invoke(Request $request) + public function __invoke(Request $request): AccessTokenResource { $this->getToken($request->redirect_uri); diff --git a/app/Http/Controllers/Account/KakaoController.php b/app/Http/Controllers/Account/KakaoController.php index 5accf6e..1c46fb4 100644 --- a/app/Http/Controllers/Account/KakaoController.php +++ b/app/Http/Controllers/Account/KakaoController.php @@ -16,11 +16,9 @@ class KakaoController extends Controller public const string PROVIDER = 'kakao'; /** - * SocialLogin (Kakao) - * - * @return AccessTokenResource + * 소셜로그인 (카카오) */ - public function __invoke(Request $request) + public function __invoke(Request $request): AccessTokenResource { DB::beginTransaction(); try { diff --git a/app/Http/Controllers/Account/SignInController.php b/app/Http/Controllers/Account/SignInController.php index 0bf988b..d92723a 100644 --- a/app/Http/Controllers/Account/SignInController.php +++ b/app/Http/Controllers/Account/SignInController.php @@ -12,11 +12,9 @@ class SignInController extends Controller { /** - * Sign in - * - * @return AccessTokenResource + * 로그인 */ - public function __invoke(SignInRequest $request) + public function __invoke(SignInRequest $request): AccessTokenResource { try { $user = User::where('email', $request->email)->firstOrFail(); @@ -26,7 +24,7 @@ public function __invoke(SignInRequest $request) } } catch (Exception $e) { logger($e); - abort(401, 'invalid credentials'); + abort(401, __('user.signin_denied')); } return new AccessTokenResource( diff --git a/app/Http/Controllers/Account/SignUpController.php b/app/Http/Controllers/Account/SignUpController.php index 782fdda..c2353c0 100644 --- a/app/Http/Controllers/Account/SignUpController.php +++ b/app/Http/Controllers/Account/SignUpController.php @@ -13,27 +13,24 @@ class SignUpController extends Controller { /** - * Sign up - * - * @return AccessTokenResource + * 회원 가입 */ - public function __invoke(SignUpRequest $request) + public function __invoke(SignUpRequest $request): AccessTokenResource { - DB::beginTransaction(); try { + DB::beginTransaction(); $user = User::firstOrCreate([ 'email' => $request->email, ], [ 'name' => $request->name, - 'nickname' => $request->nickname ?? $request->name, + 'nickname' => $request->nickname, 'password' => Hash::make($request->password), ]); if (! $user->wasRecentlyCreated) { - abort(409, 'already exists'); + abort(409, __('user.signup_duplicate_email')); } // $user->sendEmailVerificationNotification(); - DB::commit(); } catch (Exception $e) { DB::rollBack(); diff --git a/app/Http/Controllers/Account/UserController.php b/app/Http/Controllers/User/UserController.php similarity index 53% rename from app/Http/Controllers/Account/UserController.php rename to app/Http/Controllers/User/UserController.php index 31c813e..bfdc04d 100644 --- a/app/Http/Controllers/Account/UserController.php +++ b/app/Http/Controllers/User/UserController.php @@ -1,6 +1,6 @@ revoke($user, $request->deleted_reason); + DB::commit(); + } catch (Exception $e) { + DB::rollBack(); + logger($e); + abort($e->getCode(), __('user.destroy_denied')); + } + + return new MessageResource([ + 'message' => __('user.destroy'), + ]); + } + + /** + * 소셜 로그인 탈퇴 처리 + */ + private function revoke($user, $reason): void + { + if ($user->provider === 'apple') { + $user->apple->delete(); + // @todo : Apple 로그인 탈퇴 처리 + } elseif ($user->provider === 'kakao') { + $user->kakao->delete(); + /* + Http::withHeaders(['Authorization' => 'KakaoAK '.config('services.kakao.admin_key')]) + ->asForm()->throw() + ->post('https://kapi.kakao.com/v1/user/unlink', [ + 'target_id_type' => 'user_id', + 'target_id' => $user->provider_id, + ]); + */ + } else { + $user->update(['password' => null]); + } + + $user->update(['deleted_reason' => $reason]); + $user->tokens()->delete(); + $user->delete(); + } +} diff --git a/app/Http/Controllers/User/UserUpdateController.php b/app/Http/Controllers/User/UserUpdateController.php new file mode 100644 index 0000000..4a24874 --- /dev/null +++ b/app/Http/Controllers/User/UserUpdateController.php @@ -0,0 +1,44 @@ +update([ + 'name' => $request->name, + 'nickname' => $request->nickname, + 'email' => $request->email, + // 'password' => $request->password ? Hash::make($request->password) : $user->password, + ]); + DB::commit(); + } catch (Exception $e) { + DB::rollBack(); + logger($e); + abort($e->getCode(), __('user.update_denied')); + } + + return new MessageResource([ + 'message' => __('user.update'), + ]); + } +} diff --git a/app/Http/Requests/Account/SignUpRequest.php b/app/Http/Requests/Account/SignUpRequest.php index fc57e66..704db33 100644 --- a/app/Http/Requests/Account/SignUpRequest.php +++ b/app/Http/Requests/Account/SignUpRequest.php @@ -11,7 +11,7 @@ public function rules(): array return [ 'email' => ['required', 'email', 'unique:users,email', 'max:100'], 'name' => ['required', 'string', 'max:50'], - 'nickname' => ['nullable', 'string', 'max:50'], + 'nickname' => ['required', 'string', 'unique:users,nickname', 'max:50'], 'password' => ['required', 'string', 'min:8', 'max:100'], ]; } diff --git a/app/Http/Resources/Account/UserResource.php b/app/Http/Resources/Account/UserResource.php index 8173551..e009614 100644 --- a/app/Http/Resources/Account/UserResource.php +++ b/app/Http/Resources/Account/UserResource.php @@ -10,7 +10,6 @@ class UserResource extends JsonResource public function toArray(Request $request): array { return [ - 'id' => $this->id, 'name' => $this->name, 'nickname' => $this->nickname, 'email' => $this->email, diff --git a/app/Models/User.php b/app/Models/User.php index 18ffbc9..3582086 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -2,7 +2,10 @@ namespace App\Models; +use App\Models\User\UserApple; +use App\Models\User\UserKakao; use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; @@ -19,6 +22,7 @@ class User extends Authenticatable */ protected $fillable = [ 'name', + 'nickname', 'email', 'password', ]; @@ -42,4 +46,14 @@ class User extends Authenticatable 'email_verified_at' => 'datetime', 'password' => 'hashed', ]; + + public function apple(): HasOne + { + return $this->HasOne(UserApple::class); + } + + public function kakao(): HasOne + { + return $this->hasOne(UserKakao::class); + } } 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 f63f270..0e7e6e5 100644 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -14,7 +14,7 @@ public function up(): void Schema::create('users', static function (Blueprint $table) { $table->id(); $table->string('name', 50); - $table->string('nickname', 50)->nullable(); + $table->string('nickname', 50)->unique(); $table->string('email', 200)->nullable()->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password', 100)->nullable(); @@ -27,6 +27,7 @@ public function up(): void $table->rememberToken(); $table->timestamps(); $table->softDeletes(); + $table->string('deleted_reason', 200)->nullable(); }); } diff --git a/lang/ko/user.php b/lang/ko/user.php new file mode 100644 index 0000000..5585e1f --- /dev/null +++ b/lang/ko/user.php @@ -0,0 +1,13 @@ + '회원 가입 중 오류가 발생했습니다.', + 'signup_duplicate_email' => '이미 가입한 이메일 주소입니다.', + 'signin_denied' => '로그인 중 오류가 발생했습니다.', + 'update' => '회원 정보가 수정되었습니다.', + 'update_denied' => '회원 정보 수정 중 오류가 발생했습니다.', + 'destroy' => '회원 탈퇴가 완료되었습니다.', + 'destroy_denied' => '회원 탈퇴 처리 중 오류가 발생했습니다.', + +]; diff --git a/routes/api.php b/routes/api.php index a94c78c..cf76161 100644 --- a/routes/api.php +++ b/routes/api.php @@ -4,8 +4,10 @@ use App\Http\Controllers\Account\KakaoController; use App\Http\Controllers\Account\SignInController; use App\Http\Controllers\Account\SignUpController; -use App\Http\Controllers\Account\UserController; use App\Http\Controllers\PostController; +use App\Http\Controllers\User\UserController; +use App\Http\Controllers\User\UserDestroyController; +use App\Http\Controllers\User\UserUpdateController; use Illuminate\Support\Facades\Route; /* @@ -32,8 +34,8 @@ Route::middleware('auth:sanctum')->group(static function () { Route::get('/', UserController::class); - // Route::put('/', UserUpdateController::class); - // Route::delete('/', UserDeleteController::class); + Route::put('/', UserUpdateController::class); + Route::delete('/', UserDestroyController::class); }); });