22
33namespace Pterodactyl \Http \Controllers \Auth ;
44
5+ use Illuminate \Auth \AuthManager ;
56use Illuminate \Http \JsonResponse ;
7+ use PragmaRX \Google2FA \Google2FA ;
8+ use Illuminate \Contracts \Config \Repository ;
9+ use Illuminate \Contracts \Encryption \Encrypter ;
610use Pterodactyl \Http \Requests \Auth \LoginCheckpointRequest ;
11+ use Illuminate \Contracts \Cache \Repository as CacheRepository ;
12+ use Pterodactyl \Contracts \Repository \UserRepositoryInterface ;
713use Pterodactyl \Exceptions \Repository \RecordNotFoundException ;
814
915class LoginCheckpointController extends AbstractLoginController
1016{
17+ /**
18+ * @var \Illuminate\Contracts\Cache\Repository
19+ */
20+ private $ cache ;
21+
22+ /**
23+ * @var \Pterodactyl\Contracts\Repository\UserRepositoryInterface
24+ */
25+ private $ repository ;
26+
27+ /**
28+ * @var \PragmaRX\Google2FA\Google2FA
29+ */
30+ private $ google2FA ;
31+
32+ /**
33+ * @var \Illuminate\Contracts\Encryption\Encrypter
34+ */
35+ private $ encrypter ;
36+
37+ /**
38+ * LoginCheckpointController constructor.
39+ *
40+ * @param \Illuminate\Auth\AuthManager $auth
41+ * @param \Illuminate\Contracts\Encryption\Encrypter $encrypter
42+ * @param \PragmaRX\Google2FA\Google2FA $google2FA
43+ * @param \Illuminate\Contracts\Config\Repository $config
44+ * @param \Illuminate\Contracts\Cache\Repository $cache
45+ * @param \Pterodactyl\Contracts\Repository\UserRepositoryInterface $repository
46+ */
47+ public function __construct (
48+ AuthManager $ auth ,
49+ Encrypter $ encrypter ,
50+ Google2FA $ google2FA ,
51+ Repository $ config ,
52+ CacheRepository $ cache ,
53+ UserRepositoryInterface $ repository
54+ ) {
55+ parent ::__construct ($ auth , $ config );
56+
57+ $ this ->google2FA = $ google2FA ;
58+ $ this ->cache = $ cache ;
59+ $ this ->repository = $ repository ;
60+ $ this ->encrypter = $ encrypter ;
61+ }
62+
1163 /**
1264 * Handle a login where the user is required to provide a TOTP authentication
1365 * token. Once a user has reached this stage it is assumed that they have already
@@ -16,29 +68,28 @@ class LoginCheckpointController extends AbstractLoginController
1668 * @param \Pterodactyl\Http\Requests\Auth\LoginCheckpointRequest $request
1769 * @return \Illuminate\Http\JsonResponse
1870 *
71+ * @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
72+ * @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
73+ * @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
1974 * @throws \Pterodactyl\Exceptions\DisplayException
2075 */
2176 public function __invoke (LoginCheckpointRequest $ request ): JsonResponse
2277 {
2378 try {
24- $ cache = $ this ->cache ->pull ($ request ->input ('confirmation_token ' ), []);
25- $ user = $ this ->repository ->find (array_get ($ cache , 'user_id ' , 0 ));
79+ $ user = $ this ->repository ->find (
80+ $ this ->cache ->pull ($ request ->input ('confirmation_token ' ), 0 )
81+ );
2682 } catch (RecordNotFoundException $ exception ) {
2783 return $ this ->sendFailedLoginResponse ($ request );
2884 }
2985
30- if (array_get ($ cache , 'request_ip ' ) !== $ request ->ip ()) {
31- return $ this ->sendFailedLoginResponse ($ request , $ user );
32- }
86+ $ decrypted = $ this ->encrypter ->decrypt ($ user ->totp_secret );
87+ $ window = $ this ->config ->get ('pterodactyl.auth.2fa.window ' );
3388
34- if (! $ this ->google2FA ->verifyKey (
35- $ this ->encrypter ->decrypt ($ user ->totp_secret ),
36- $ request ->input ('authentication_code ' ),
37- config ('pterodactyl.auth.2fa.window ' )
38- )) {
39- return $ this ->sendFailedLoginResponse ($ request , $ user );
89+ if ($ this ->google2FA ->verifyKey ($ decrypted , $ request ->input ('authentication_code ' ), $ window )) {
90+ return $ this ->sendLoginResponse ($ user , $ request );
4091 }
4192
42- return $ this ->sendLoginResponse ( $ user , $ request );
93+ return $ this ->sendFailedLoginResponse ( $ request , $ user );
4394 }
4495}
0 commit comments