Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 109
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
AccountSignupStep2Logic
0.00% covered (danger)
0.00%
0 / 109
0.00% covered (danger)
0.00%
0 / 4
110
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 startup
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
2
 validateImpl
0.00% covered (danger)
0.00%
0 / 33
0.00% covered (danger)
0.00%
0 / 1
42
 executeImpl
0.00% covered (danger)
0.00%
0 / 65
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3declare(strict_types=1);
4
5namespace PeServer\App\Models\Domain\Page\Account;
6
7use PeServer\App\Models\AppCryptography;
8use PeServer\App\Models\AppDatabaseCache;
9use PeServer\App\Models\AppMailer;
10use PeServer\App\Models\AppTemplate;
11use PeServer\App\Models\AuditLog;
12use PeServer\App\Models\Dao\Entities\SignUpWaitEmailsEntityDao;
13use PeServer\App\Models\Dao\Entities\UserAuthenticationsEntityDao;
14use PeServer\App\Models\Dao\Entities\UsersEntityDao;
15use PeServer\App\Models\Domain\AccountValidator;
16use PeServer\App\Models\Domain\Page\PageLogicBase;
17use PeServer\App\Models\Domain\Page\SessionAnonymousTrait;
18use PeServer\App\Models\Domain\UserLevel;
19use PeServer\App\Models\Domain\UserState;
20use PeServer\App\Models\Domain\UserUtility;
21use PeServer\App\Models\Data\SessionAccount;
22use PeServer\App\Models\Data\SessionAnonymous;
23use PeServer\App\Models\SessionKey;
24use PeServer\Core\Cryptography;
25use PeServer\Core\Database\IDatabaseContext;
26use PeServer\Core\Http\HttpStatus;
27use PeServer\Core\I18n;
28use PeServer\Core\Mail\EmailAddress;
29use PeServer\Core\Mail\EmailMessage;
30use PeServer\Core\Mail\Mailer;
31use PeServer\Core\Mvc\LogicCallMode;
32use PeServer\Core\Mvc\LogicParameter;
33use PeServer\Core\Text;
34
35class AccountSignupStep2Logic extends PageLogicBase
36{
37    use SessionAnonymousTrait;
38
39    public function __construct(LogicParameter $parameter, private AppCryptography $cryptography, private AppDatabaseCache $dbCache, private Mailer $mailer, private AppTemplate $appTemplate)
40    {
41        parent::__construct($parameter);
42    }
43
44    #region PageLogicBase
45
46    protected function startup(LogicCallMode $callMode): void
47    {
48        $this->registerParameterKeys([
49            'token',
50            'account_signup_email',
51            'account_signup_login_id',
52            'account_signup_password',
53            'account_signup_password_confirm',
54            'account_signup_name',
55        ], true);
56
57        $this->setValue('account_signup_password', Text::EMPTY);
58        $this->setValue('account_signup_password_confirm', Text::EMPTY);
59    }
60
61    protected function validateImpl(LogicCallMode $callMode): void
62    {
63        if ($callMode === LogicCallMode::Initialize) {
64            return;
65        }
66
67        $this->throwHttpStatusIfNotSignup2(HttpStatus::NotFound);
68
69        $this->validation('account_signup_email', function (string $key, string $value) {
70            $accountValidator = new AccountValidator($this, $this->validator);
71
72            if ($accountValidator->isEmail($key, $value)) {
73                $database = $this->openDatabase();
74                $signUpWaitEmailsEntityDao = new SignUpWaitEmailsEntityDao($database);
75
76                // ミドルウェアでトークン確認しているので取得できない場合は例外でOK
77                $email = $signUpWaitEmailsEntityDao->selectEmail($this->getRequest('token'));
78                $rawEmail = $this->cryptography->decrypt($email);
79                if ($value !== $rawEmail) {
80                    $this->addError($key, I18n::message('error/sign_up_not_equal_email'));
81                }
82            }
83        });
84
85        $this->validation('account_signup_login_id', function (string $key, string $value) {
86            $accountValidator = new AccountValidator($this, $this->validator);
87            if ($accountValidator->isLoginId($key, $value)) {
88                $database = $this->openDatabase();
89                $accountValidator->isFreeLoginId($database, $key, $value);
90            }
91        });
92
93        $this->validation('account_signup_password', function (string $key, string $value) {
94            $accountValidator = new AccountValidator($this, $this->validator);
95            $accountValidator->isPassword($key, $value);
96        }, ['trim' => false]);
97
98        $this->validation('account_signup_password_confirm', function (string $key, string $value) {
99            $this->validator->isNotWhiteSpace($key, $value);
100            $newPassword = $this->getRequest('account_signup_password', Text::EMPTY, false);
101            if ($value !== $newPassword) {
102                $this->addError($key, I18n::message('error/password_confirm'));
103            }
104        });
105
106        $this->validation('account_signup_name', function (string $key, string $value) {
107            $accountValidator = new AccountValidator($this, $this->validator);
108            $accountValidator->isUserName($key, $value);
109        });
110    }
111
112    protected function executeImpl(LogicCallMode $callMode): void
113    {
114        if ($callMode === LogicCallMode::Initialize) {
115            $this->setSession(SessionKey::ANONYMOUS, new SessionAnonymous(signup2: true));
116            return;
117        }
118
119        $userId = UserUtility::generateUserId();
120        $token = $this->getRequest('token');
121        $email = $this->getRequest('account_signup_email');
122        $password = $this->getRequest('account_signup_password', Text::EMPTY, false);
123
124        $params = [
125            'token' => $token,
126            'user_id' => $userId,
127            'login_id' => $this->getRequest('account_signup_login_id'),
128            'email' => $this->cryptography->encrypt($email),
129            'mark_email' => $this->cryptography->toMark($email),
130            'user_name' => $this->getRequest('account_signup_name'),
131            'password' => Cryptography::hashPassword($password)
132        ];
133
134        $database = $this->openDatabase();
135        $database->transaction(function (IDatabaseContext $context) use ($params) {
136            $usersEntityDao = new UsersEntityDao($context);
137            $userAuthenticationsEntityDao = new UserAuthenticationsEntityDao($context);
138            $signUpWaitEmailsEntityDao = new SignUpWaitEmailsEntityDao($context);
139
140            $usersEntityDao->insertUser(
141                $params['user_id'],
142                $params['login_id'],
143                UserLevel::USER,
144                UserState::ENABLED,
145                $params['user_name'],
146                $params['email'],
147                $params['mark_email'],
148                Text::EMPTY,
149                Text::EMPTY,
150                Text::EMPTY
151            );
152
153            $userAuthenticationsEntityDao->insertUserAuthentication(
154                $params['user_id'],
155                $params['password']
156            );
157
158            $signUpWaitEmailsEntityDao->deleteToken($params['token']);
159
160            $this->writeAuditLogTargetUser($params['user_id'], AuditLog::USER_CREATE, ['token' => $params['token']], $context);
161
162            return true;
163        });
164
165        $subject = I18n::message('subject/sign_up_step2');
166        $values = [
167            'name' => $params['user_name'],
168            'login_id' => $params['login_id'],
169        ];
170        $html = $this->appTemplate->createMailTemplate('mail_signup_step2', $subject, $values);
171
172        $this->mailer->toAddresses = [
173            new EmailAddress($email, $params['user_name']),
174        ];
175        $this->mailer->subject = $subject;
176        $this->mailer->setMessage(new EmailMessage(null, $html));
177
178        $this->mailer->send();
179
180        $this->removeSession(SessionKey::ANONYMOUS);
181        $this->setSession(SessionKey::ACCOUNT, new SessionAccount(
182            $userId,
183            $params['login_id'],
184            $params['user_name'],
185            UserLevel::USER,
186            UserState::ENABLED
187        ));
188        $this->dbCache->exportUserInformation();
189        $this->restartSession();
190
191        $this->addTemporaryMessage('現在ログイン中です');
192        $this->addTemporaryMessage('ユーザー登録が完了しました、通知メールを確認してください');
193    }
194
195    #endregion
196}