| @@ -0,0 +1,66 @@ | |||
| <?php | |||
| namespace App\Http\Controllers\Web\Auth; | |||
| use App\Http\Controllers\Web\WebController; | |||
| use App\Kintone\Models\Customer; | |||
| use App\Models\User; | |||
| use Illuminate\Http\JsonResponse; | |||
| use Illuminate\Http\Request; | |||
| use Illuminate\Support\Facades\Hash; | |||
| class LoginCheckController extends WebController | |||
| { | |||
| public function name(): string | |||
| { | |||
| return "ログインチェック"; | |||
| } | |||
| public function description(): string | |||
| { | |||
| return "ログインチェックを行う"; | |||
| } | |||
| public function __construct(protected LoginCheckParam $param) | |||
| { | |||
| parent::__construct(); | |||
| } | |||
| protected function run(Request $request): JsonResponse | |||
| { | |||
| $param = $this->param; | |||
| // 取得したユーザ情報を登録しログインを行う | |||
| // ログインパスワードチェック | |||
| $users = User::whereEmail($param->email) | |||
| ->get(); | |||
| foreach ($users as $user) { | |||
| info($user->toArray()); | |||
| if (!Hash::check($param->password, $user->password)) { | |||
| return $this->failedResponse(); | |||
| } | |||
| } | |||
| $access = Customer::getAccess(); | |||
| $query = Customer::getQuery()->where(Customer::FIELD_EMAIL, $param->email); | |||
| $customers = $access->all($query); | |||
| if ($customers->isEmpty()) { | |||
| return $this->failedResponse(); | |||
| } | |||
| $ret = []; | |||
| foreach ($customers as $customer) { | |||
| $ret[] = [ | |||
| 'customer_code' => $customer->customerCode, | |||
| 'name' => $customer->customerName, | |||
| ]; | |||
| } | |||
| return $this->successResponse($ret); | |||
| } | |||
| } | |||
| @@ -0,0 +1,20 @@ | |||
| <?php | |||
| namespace App\Http\Controllers\Web\Auth; | |||
| use App\Http\Controllers\Web\BaseParam; | |||
| /** | |||
| * @property string $email | |||
| * @property string $password | |||
| */ | |||
| class LoginCheckParam extends BaseParam | |||
| { | |||
| public function rules(): array | |||
| { | |||
| return [ | |||
| 'email' => $this->str(), | |||
| 'password' => $this->str(), | |||
| ]; | |||
| } | |||
| } | |||
| @@ -2,15 +2,13 @@ | |||
| namespace App\Http\Controllers\Web\Auth; | |||
| use App\Codes\EnvironmentName; | |||
| use App\Http\Controllers\Web\WebController; | |||
| use App\Kintone\Models\Customer; | |||
| use App\Models\User; | |||
| use Exception; | |||
| use Illuminate\Http\JsonResponse; | |||
| use Illuminate\Http\Request; | |||
| use Illuminate\Support\Facades\Auth; | |||
| use League\CommonMark\Environment\Environment; | |||
| use Illuminate\Support\Facades\Hash; | |||
| class LoginController extends WebController | |||
| { | |||
| @@ -37,7 +35,8 @@ class LoginController extends WebController | |||
| $param = $this->param; | |||
| $access = Customer::getAccess(); | |||
| $query = Customer::getQuery()->where(Customer::FIELD_EMAIL, $param->email); | |||
| $query = Customer::getQuery()->where(Customer::FIELD_EMAIL, $param->email) | |||
| ->where(Customer::FIELD_CUSTOMER_CODE, $param->customerCode); | |||
| $customer = $access->some($query); | |||
| @@ -53,46 +52,18 @@ class LoginController extends WebController | |||
| ->first(); | |||
| if ($user instanceof User) { | |||
| // すでにユーザー登録されているケース | |||
| // パスワードチェック | |||
| if (!Hash::check($param->password, $user->password)) { | |||
| return $this->failedResponse(); | |||
| } | |||
| //データ同期 | |||
| //データ同期 Email | |||
| if ($user->email !== $param->email) { | |||
| $user->email = $param->email; | |||
| $user->save(); | |||
| } | |||
| if ($user->kintone_customer_code !== $customer->getNumber(Customer::FIELD_CUSTOMER_CODE)) { | |||
| $user->kintone_customer_code = $customer->getNumber(Customer::FIELD_CUSTOMER_CODE); | |||
| $user->save(); | |||
| } | |||
| if (Auth::attempt([ | |||
| 'email' => $param->email, | |||
| 'password' => $param->password, | |||
| ])) { | |||
| return $this->successResponse($customer->toArray()); | |||
| } else { | |||
| return $this->failedResponse(); | |||
| } | |||
| } else if (app()->environment([EnvironmentName::LOCAL->value]) && $param->password === "testuser") { | |||
| // ローカル環境でのテストユーザー作成処理 | |||
| $user = new User(); | |||
| $user->email = $param->email; | |||
| $user->kintone_id = $customer->getRecordId(); | |||
| $user->password = "testuser"; | |||
| $user->kintone_customer_code = $customer->getNumber(Customer::FIELD_CUSTOMER_CODE); | |||
| $user->save(); | |||
| if (Auth::attempt([ | |||
| 'email' => $param->email, | |||
| 'password' => 'testuser', | |||
| ])) { | |||
| return $this->successResponse($customer->toArray()); | |||
| } else { | |||
| return $this->failedResponse(); | |||
| } | |||
| } else { | |||
| return $this->failedResponse(); | |||
| Auth::login($user); | |||
| return $this->successResponse($customer->toArray()); | |||
| } | |||
| } | |||
| } | |||
| @@ -7,6 +7,7 @@ use App\Http\Controllers\Web\BaseParam; | |||
| /** | |||
| * @property string $email | |||
| * @property string $password | |||
| * @property int $customerCode | |||
| */ | |||
| class LoginParam extends BaseParam | |||
| { | |||
| @@ -15,6 +16,7 @@ class LoginParam extends BaseParam | |||
| return [ | |||
| 'email' => $this->str(), | |||
| 'password' => $this->str(), | |||
| 'customer_code' => $this->numeric(), | |||
| ]; | |||
| } | |||
| } | |||
| @@ -8,6 +8,7 @@ use App\Logic\PasswordSettingManager; | |||
| use App\Models\User; | |||
| use Illuminate\Http\JsonResponse; | |||
| use Illuminate\Http\Request; | |||
| use Illuminate\Support\Collection; | |||
| class PasswordSettingStartController extends WebController | |||
| { | |||
| @@ -35,43 +36,48 @@ class PasswordSettingStartController extends WebController | |||
| $access = Customer::getAccess(); | |||
| $query = Customer::getQuery()->where(Customer::FIELD_EMAIL, $param->email); | |||
| $customer = $access->some($query); | |||
| $customers = $access->all($query); | |||
| if ($customer->count() !== 1) { | |||
| if ($customers->isEmpty()) { | |||
| // 無効なユーザだが、セキュリティ対策として成功と見せかける | |||
| return $this->successResponse(); | |||
| } | |||
| $customer = $customer->first(); | |||
| // トークン生成 | |||
| $this->tokenGenerate($customers); | |||
| $kintoneId = $customer->getRecordId(); | |||
| return $this->successResponse(); | |||
| } | |||
| $user = User::whereKintoneId($kintoneId) | |||
| ->first(); | |||
| /** | |||
| * Undocumented function | |||
| * | |||
| * @param Collection<int,Customer> $customers | |||
| * @return void | |||
| */ | |||
| private function tokenGenerate(Collection $customers) | |||
| { | |||
| if ($user instanceof User) { | |||
| //データ同期 | |||
| if ($user->email !== $param->email) { | |||
| $user->email = $param->email; | |||
| $user->save(); | |||
| } | |||
| if ($user->kintone_customer_code !== $customer->getNumber(Customer::FIELD_CUSTOMER_CODE)) { | |||
| foreach ($customers as $customer) { | |||
| $kintoneId = $customer->getRecordId(); | |||
| $user = User::whereKintoneId($kintoneId) | |||
| ->first(); | |||
| if ($user instanceof User) { | |||
| } else { | |||
| // 新規の場合はユーザーを追加する | |||
| $user = new User(); | |||
| $user->email = $customer->email; | |||
| $user->kintone_id = $customer->getRecordId(); | |||
| $user->kintone_customer_code = $customer->getNumber(Customer::FIELD_CUSTOMER_CODE); | |||
| $user->save(); | |||
| } | |||
| } else { | |||
| // 新規の場合はユーザーを追加する | |||
| $user = new User(); | |||
| $user->email = $param->email; | |||
| $user->kintone_id = $customer->getRecordId(); | |||
| $user->kintone_customer_code = $customer->getNumber(Customer::FIELD_CUSTOMER_CODE); | |||
| $user->save(); | |||
| } | |||
| // トークン生成 | |||
| $this->manager->generate($user); | |||
| return $this->successResponse(); | |||
| // トークン生成 | |||
| $this->manager->generate($user); | |||
| } | |||
| } | |||
| } | |||
| @@ -3,9 +3,7 @@ | |||
| namespace App\Http\Controllers\Web\Auth; | |||
| use App\Http\Controllers\Web\WebController; | |||
| use App\Kintone\Models\Customer; | |||
| use App\Logic\PasswordSettingManager; | |||
| use App\Models\User; | |||
| use Illuminate\Http\JsonResponse; | |||
| use Illuminate\Http\Request; | |||
| @@ -22,7 +20,6 @@ class PasswordSettingVerifyController extends WebController | |||
| return "パスワード設定手続きを認証する"; | |||
| } | |||
| public function __construct(protected PasswordSettingVerifyParam $param, private PasswordSettingManager $manager) | |||
| { | |||
| parent::__construct(); | |||
| @@ -32,13 +29,15 @@ class PasswordSettingVerifyController extends WebController | |||
| { | |||
| $param = $this->param; | |||
| $user = $this->manager->verify($param->token); | |||
| if ($user === null) { | |||
| $users = $this->manager->verify($param->token); | |||
| if ($users === null) { | |||
| return $this->failedResponse(); | |||
| } | |||
| $user->password = $param->password; | |||
| $user->save(); | |||
| foreach ($users as $user) { | |||
| $user->password = $param->password; | |||
| $user->save(); | |||
| } | |||
| return $this->successResponse(); | |||
| } | |||
| @@ -4,9 +4,9 @@ namespace App\Http\Controllers\Web\Customer; | |||
| use App\Http\Controllers\Web\WebController; | |||
| use App\Logic\EmailChangeManager; | |||
| use App\Transmissions\HTICWeb\Sender; | |||
| use Illuminate\Http\JsonResponse; | |||
| use Illuminate\Http\Request; | |||
| use Illuminate\Support\Facades\Auth; | |||
| class ChangeEmailVerifyController extends WebController | |||
| { | |||
| @@ -21,24 +21,20 @@ class ChangeEmailVerifyController extends WebController | |||
| return "Emailの変更手続きを認証する"; | |||
| } | |||
| use Sender; | |||
| public function __construct(protected ChangeEmailVerifyParams $param, private EmailChangeManager $manager) | |||
| { | |||
| parent::__construct(); | |||
| // $this->middleware('auth:sanctum'); | |||
| } | |||
| protected function run(Request $request): JsonResponse | |||
| { | |||
| $param = $this->param; | |||
| $ret = $this->manager | |||
| $customer = $this->manager | |||
| ->verify($param->token); | |||
| if (!$ret) { | |||
| $this->failedResponse(); | |||
| } | |||
| return $this->successResponse(); | |||
| } | |||
| } | |||
| @@ -24,6 +24,7 @@ class UserRegisterParam extends BaseParam | |||
| 'address2' => $this->str(true), | |||
| 'address3' => $this->str(true), | |||
| 'phone_number' => $this->str(true), | |||
| 'parent_user_id' => $this->str(true), | |||
| ]; | |||
| } | |||
| } | |||
| @@ -15,6 +15,7 @@ use Illuminate\Support\Facades\Auth; | |||
| * @property string address | |||
| * @property string bankBranchId | |||
| * @property ?Carbon bankAccountRegisterRemaindDatetime | |||
| * @property ?int icSeasonTicektUserId | |||
| */ | |||
| class Customer extends KintoneModel | |||
| { | |||
| @@ -72,4 +73,9 @@ class Customer extends KintoneModel | |||
| 'customer_name_kana_hankaku' => mb_convert_kana($this->customerNameKana, "sk"), | |||
| ]; | |||
| } | |||
| public function isHTICWebUser(): bool | |||
| { | |||
| return !!$this->icSeasonTicektUserId; | |||
| } | |||
| } | |||
| @@ -82,7 +82,7 @@ class EmailChangeManager | |||
| // トークン削除 | |||
| $model->delete(); | |||
| return true; | |||
| return $customer; | |||
| } | |||
| /** | |||
| @@ -6,6 +6,7 @@ use App\Email\Guests\PasswordSettingStart; | |||
| use App\Models\PasswordSettingToken; | |||
| use App\Models\User; | |||
| use App\Util\DateUtil; | |||
| use Illuminate\Support\Collection; | |||
| use Illuminate\Support\Str; | |||
| class PasswordSettingManager | |||
| @@ -31,20 +32,29 @@ class PasswordSettingManager | |||
| $emailManager->confirm(); | |||
| } | |||
| public function verify(string $token): User|null | |||
| /** | |||
| * @param string $token | |||
| * @return Collection<int, User>|null | |||
| */ | |||
| public function verify(string $token): Collection|null | |||
| { | |||
| $model = PasswordSettingToken::whereToken($token) | |||
| $passwords = | |||
| PasswordSettingToken::whereToken($token) | |||
| ->expiresIn() | |||
| ->first(); | |||
| ->get(); | |||
| if ($model === null) { | |||
| return null; | |||
| } | |||
| $user = User::whereId($model->user_id)->firstOrFail(); | |||
| $users = User::whereIn( | |||
| User::COL_NAME_ID, | |||
| $passwords->pluck(PasswordSettingToken::COL_NAME_USER_ID) | |||
| ) | |||
| ->get(); | |||
| $model->delete(); | |||
| foreach ($passwords as $password) { | |||
| $password->delete(); | |||
| } | |||
| return $user; | |||
| return $users; | |||
| } | |||
| } | |||
| @@ -7,6 +7,7 @@ use App\Events\Model\CreatingEvent; | |||
| use App\Events\Model\DeletedEvent; | |||
| use App\Events\Model\UpdatingEvent; | |||
| use App\Models\Feature\IModelFeature; | |||
| use Eloquent; | |||
| use Illuminate\Database\Eloquent\Concerns\HasUuids; | |||
| use Illuminate\Database\Eloquent\Factories\HasFactory; | |||
| use Illuminate\Database\Eloquent\SoftDeletes; | |||
| @@ -16,6 +17,9 @@ use Illuminate\Notifications\Notifiable; | |||
| use Illuminate\Support\Facades\DB; | |||
| use Laravel\Sanctum\HasApiTokens; | |||
| /** | |||
| * @mixin Eloquent | |||
| */ | |||
| class User extends Authenticatable implements IModelFeature | |||
| { | |||
| use HasApiTokens, HasFactory, Notifiable, HasUuids, SoftDeletes; | |||
| @@ -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->dropUnique("users_email_unique"); | |||
| }); | |||
| } | |||
| /** | |||
| * Reverse the migrations. | |||
| */ | |||
| public function down(): void | |||
| { | |||
| Schema::table('users', function (Blueprint $table) { | |||
| $table->string('email')->unique()->change(); | |||
| }); | |||
| } | |||
| }; | |||
| @@ -16,6 +16,7 @@ use Illuminate\Support\Facades\Route; | |||
| RouteHelper::post('/login', App\Http\Controllers\Web\Auth\LoginController::class); | |||
| RouteHelper::post('/login/check', App\Http\Controllers\Web\Auth\LoginCheckController::class); | |||
| RouteHelper::get('/logout', App\Http\Controllers\Web\Auth\LogoutController::class); | |||
| RouteHelper::get('/me', App\Http\Controllers\Web\Auth\MeController::class); | |||