<commit_before><?php

namespace api\modules\v1\controllers;

use api\config\ApiCode;
use api\forms\LoginForm;
use api\forms\RegisterUserForm;
use common\exceptions\BetterHttpException;
use common\models\Device;
use yii\base\InvalidConfigException;
use yii\rest\Controller;
use yii\web\HttpException;

/**
 * Class AuthController
 * @package api\modules\v1\controllers
 * @author Haqqi <<EMAIL>>
 */
class AuthController extends Controller
{
    public function behaviors()
    {
        $behaviors = parent::behaviors();

        $behaviors['authenticator']['except'] = [
            'login',
            'forgot-password',
            'reset-password',
            'register'
        ];

        return $behaviors;
    }

    protected function verbs()
    {
        return [
            'login'           => ['post'],
            'logout'          => ['post'],
            'forgot-password' => ['post'],
            'reset-password'  => ['get', 'post'],
            'register'        => ['post'],
            'change-password' => ['post']
        ];
    }

    /**
     * Register user through API.
     *
     * @return array the success response.
     * @throws BetterHttpException if the user failed to register.
     */
    public function actionRegister()
    {
        try {
            $userForm = new RegisterUserForm(\Yii::$app->request->headers->get('X-Device-identifier'));
        } catch (InvalidConfigException $e) {
            throw new HttpException(400, $e->getMessage(), ApiCode::DEVICE_IDENTIFIER_NOT_FOUND);
        }

        $userForm->load(\Yii::$app->request->post(), 'User');

        if ($userForm->validate()) {
            $user = $userForm->register();

            return [
                'name'    => 'Success',
                'message' => 'Registration as user ' . $user->username . ' success.',
                'code'    => ApiCode::REGISTER_SUCCESS,
                'status'  => 200,
                'data'    => $user->toArray([
                    'username',
                    'email',
                ])
            ];
        }

        throw new BetterHttpException(400, 'Registration failed.', [
            'User' => $userForm->getErrors()
        ], ApiCode::REGISTER_FAILED);
    }

    /**
     * Log user in through API. This will create a new device record with active status.
     * Any device that has same identifier will be deactivated.
     *
     * @return array the success response containing accessToken.
     * @throws BetterHttpException if the user failed to login.
     */
    public function actionLogin()
    {
        try {
            $loginForm = new LoginForm(\Yii::$app->request->headers->get('X-Device-identifier'));
        } catch (InvalidConfigException $e) {
            throw new HttpException(400, $e->getMessage(), ApiCode::DEVICE_IDENTIFIER_NOT_FOUND);
        }

        $loginByEmail = \Yii::$app->params['loginByEmail'];

        if ($loginByEmail) {
            $loginForm->setScenario(LoginForm::SCENARIO_SUBMIT_LOGIN_EMAIL);
        } else {
            $loginForm->setScenario(LoginForm::SCENARIO_SUBMIT_LOGIN_USERNAME);
        }

        $loginForm->load(\Yii::$app->request->post(), 'User');

        /*
         * Try to login
         */
        if ($loginForm->login()) {
            /**
             * @var $user User
             */
            $user = \Yii::$app->user->getIdentity();

            $msgLoginBy = $loginByEmail ? 'email ' . $user->email : 'username ' . $user->username;

            return [
                'name'    => 'Success',
                'message' => 'Login by ' . $msgLoginBy . ' success.',
                'code'    => ApiCode::LOGIN_SUCCESS,
                'status'  => 200,
                'data'    => $user->toArray([
                    // main fields
                    'hashId',
                    'username',
                    'email'
                ], [
                    // extra fields
                    'activeDevice'
                ])
            ];
        } else {
            throw new BetterHttpException(401, 'Login Failed', [
                'User' => $loginForm->getErrors()
            ], ApiCode::LOGIN_FAILED);
        }
    }

    /**
     * Log user out. This will need accessToken to log in the user via AccessTokenAuth.
     * The device that the user is using will be deactivated and the token will be invalid to do other request.
     *
     * @return array the success response.
     */
    public function actionLogout()
    {
        /**
         * @var $user User
         */
        $user           = \Yii::$app->user->getIdentity();
        $device         = $user->getActiveDevice();
        $device->status = Device::STATUS_INACTIVE;
        $device->save();

        \Yii::$app->user->logout();

        return [
            'name'    => 'Success',
            'message' => 'You have been logged out.',
            'code'    => ApiCode::LOGOUT_SUCCESS,
            'status'  => 200,
        ];
    }

    public function actionForgotPassword()
    {
        return [];
    }<commit_msg>[update] scenario forgot password by email<commit_after><?php

namespace api\modules\v1\controllers;

use api\config\ApiCode;
use api\forms\LoginForm;
use api\forms\RegisterUserForm;
use common\exceptions\BetterHttpException;
use common\forms\ForgotPasswordForm;
use common\models\Device;
use yii\base\InvalidConfigException;
use yii\rest\Controller;
use yii\web\HttpException;

/**
 * Class AuthController
 * @package api\modules\v1\controllers
 * @author Haqqi <<EMAIL>>
 */
class AuthController extends Controller
{
    public function behaviors()
    {
        $behaviors = parent::behaviors();

        $behaviors['authenticator']['except'] = [
            'login',
            'forgot-password',
            'reset-password',
            'register'
        ];

        return $behaviors;
    }

    protected function verbs()
    {
        return [
            'login'           => ['post'],
            'logout'          => ['post'],
            'forgot-password' => ['post'],
            'reset-password'  => ['get', 'post'],
            'register'        => ['post'],
            'change-password' => ['post']
        ];
    }

    /**
     * Register user through API.
     *
     * @return array the success response.
     * @throws BetterHttpException if the user failed to register.
     */
    public function actionRegister()
    {
        try {
            $userForm = new RegisterUserForm(\Yii::$app->request->headers->get('X-Device-identifier'));
        } catch (InvalidConfigException $e) {
            throw new HttpException(400, $e->getMessage(), ApiCode::DEVICE_IDENTIFIER_NOT_FOUND);
        }

        $userForm->load(\Yii::$app->request->post(), 'User');

        if ($userForm->validate()) {
            $user = $userForm->register();

            return [
                'name'    => 'Success',
                'message' => 'Registration as user ' . $user->username . ' success.',
                'code'    => ApiCode::REGISTER_SUCCESS,
                'status'  => 200,
                'data'    => $user->toArray([
                    'username',
                    'email',
                ])
            ];
        }

        throw new BetterHttpException(400, 'Registration failed.', [
            'User' => $userForm->getErrors()
        ], ApiCode::REGISTER_FAILED);
    }

    /**
     * Log user in through API. This will create a new device record with active status.
     * Any device that has same identifier will be deactivated.
     *
     * @return array the success response containing accessToken.
     * @throws BetterHttpException if the user failed to login.
     */
    public function actionLogin()
    {
        try {
            $loginForm = new LoginForm(\Yii::$app->request->headers->get('X-Device-identifier'));
        } catch (InvalidConfigException $e) {
            throw new HttpException(400, $e->getMessage(), ApiCode::DEVICE_IDENTIFIER_NOT_FOUND);
        }

        $loginByEmail = \Yii::$app->params['loginByEmail'];

        if ($loginByEmail) {
            $loginForm->setScenario(LoginForm::SCENARIO_SUBMIT_LOGIN_EMAIL);
        } else {
            $loginForm->setScenario(LoginForm::SCENARIO_SUBMIT_LOGIN_USERNAME);
        }

        $loginForm->load(\Yii::$app->request->post(), 'User');

        /*
         * Try to login
         */
        if ($loginForm->login()) {
            /**
             * @var $user User
             */
            $user = \Yii::$app->user->getIdentity();

            $msgLoginBy = $loginByEmail ? 'email ' . $user->email : 'username ' . $user->username;

            return [
                'name'    => 'Success',
                'message' => 'Login by ' . $msgLoginBy . ' success.',
                'code'    => ApiCode::LOGIN_SUCCESS,
                'status'  => 200,
                'data'    => $user->toArray([
                    // main fields
                    'hashId',
                    'username',
                    'email'
                ], [
                    // extra fields
                    'activeDevice'
                ])
            ];
        } else {
            throw new BetterHttpException(401, 'Login Failed', [
                'User' => $loginForm->getErrors()
            ], ApiCode::LOGIN_FAILED);
        }
    }

    /**
     * Log user out. This will need accessToken to log in the user via AccessTokenAuth.
     * The device that the user is using will be deactivated and the token will be invalid to do other request.
     *
     * @return array the success response.
     */
    public function actionLogout()
    {
        /**
         * @var $user User
         */
        $user           = \Yii::$app->user->getIdentity();
        $device         = $user->getActiveDevice();
        $device->status = Device::STATUS_INACTIVE;
        $device->save();

        \Yii::$app->user->logout();

        return [
            'name'    => 'Success',
            'message' => 'You have been logged out.',
            'code'    => ApiCode::LOGOUT_SUCCESS,
            'status'  => 200,
        ];
    }

    /**
     * Accept form submission of email. The system will generate passwordResetToken that can be sent via email.
     *
     * @return array success response
     * @throws BetterHttpException if email is not filled
     * @throws NotFoundHttpException if user is not found from the email
     */
    public function actionForgotPassword()
    {
        $forgotForm = new ForgotPasswordForm();

        $ByEmail = \Yii::$app->params['loginByEmail'];

        if ($ByEmail) {
            $forgotForm->setScenario(LoginForm::SCENARIO_SUBMIT_LOGIN_EMAIL);
        }
//        else {
//            $loginForm->setScenario(LoginForm::SCENARIO_SUBMIT_LOGIN_USERNAME);
//        }

        $forgotForm->load(\Yii::$app->request->post(), 'User');

        if ($forgotForm->validate()) {
            $user = $forgotForm->getUser();
            $user->generatePasswordResetToken();
            if ($user->save()) {
                // @todo: send password reset link to email
                // for now, just assume that you will create the passwordResetToken and log it to get it for reset password
                return [
                  'name'    => 'Success',
                  'message' => 'Your reset password link has been sent to email ' . $forgotForm->email,
                  'code'    => ApiCode::FORGOT_PASSWORD_SUCCESS,
                  'status'  => 200
                ];
            }
        }
    }
{'fraction_non_alphanumeric': 0.1328707718993929, 'fraction_numerical': 0.00424978317432784, 'mean_word_length': 1.6835001163602514, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 138, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6531321', 'n_tokens_mistral': 3207, 'n_tokens_neox': 3118, 'n_words': 710}