398 lines
14 KiB
PHP
398 lines
14 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Http\Resources\UserResource;
|
|
use App\Mail\EmailActivation;
|
|
use App\Models\Log;
|
|
use App\Models\Token;
|
|
use App\Models\User;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Facades\Mail;
|
|
|
|
class AuthController extends Controller
|
|
{
|
|
/**
|
|
* @OA\Post(
|
|
* path="/api/auth/register",
|
|
* summary="Register a new user",
|
|
* tags={"Auth"},
|
|
* @OA\RequestBody(
|
|
* required=true,
|
|
* @OA\JsonContent(
|
|
* required={"username","email","password","password_confirmation"},
|
|
* @OA\Property(property="username", type="string", maxLength=100, example="root"),
|
|
* @OA\Property(property="email", type="string", format="email", maxLength=100, example="root@example.com"),
|
|
* @OA\Property(property="password", type="string", format="password", example="123456"),
|
|
* @OA\Property(property="password_confirmation", type="string", format="password", example="123456")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="User registered successfully. Confirmation email sent.",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(property="message", type="string", example="You successfully registered! Please, confirm your account using email")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=422,
|
|
* description="Validation error",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(property="message", type="string", example="The given data was invalid."),
|
|
* @OA\Property(
|
|
* property="errors",
|
|
* type="object",
|
|
* example={"email": {"The email has already been taken."}, "password": {"The password must be at least 6 characters."}}
|
|
* )
|
|
* )
|
|
* )
|
|
* )
|
|
*/
|
|
public function register(Request $request)
|
|
{
|
|
$fields = $request->validate([
|
|
'username' => 'required|max:100|unique:users',
|
|
'email' => 'required|max:100|unique:users',
|
|
'password' => 'required|min:6|confirmed'
|
|
]);
|
|
$fields['password'] = Hash::make($fields['password']);
|
|
|
|
$user = User::create($fields);
|
|
|
|
Log::writeLog("User '" . $user->username . "' is registered");
|
|
|
|
$token = Token::existsToken($user, 'email_verification');
|
|
if(!$token) {
|
|
$token = Token::createToken($user, 'email_verification');
|
|
}
|
|
Mail::to($user->email)->send(new EmailActivation($user, $token->token));
|
|
|
|
return response()->json([
|
|
'message' => 'You successfully registered! Please, confirm your account using email'
|
|
]);
|
|
}
|
|
/**
|
|
* @OA\Post(
|
|
* path="/api/auth/login",
|
|
* summary="User login",
|
|
* tags={"Auth"},
|
|
* @OA\RequestBody(
|
|
* required=true,
|
|
* @OA\JsonContent(
|
|
* required={"email","password"},
|
|
* @OA\Property(property="email", type="string", format="email", example="root@example.com"),
|
|
* @OA\Property(property="password", type="string", format="password", example="123456")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Login successful",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(property="access_token", type="string", example="1|JfjOc5DkOHHTtWnM4SdpLM0BR0YvpycoeNAWanlH1305fab7"),
|
|
* @OA\Property(property="token_type", type="string", example="Bearer"),
|
|
* @OA\Property(
|
|
* property="user",
|
|
* ref="#/components/schemas/UserResource"
|
|
* )
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=401,
|
|
* description="Invalid credentials",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(property="message", type="string", example="Invalid credentials")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=403,
|
|
* description="Email not verified",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(property="message", type="string", example="Please verify your email first")
|
|
* )
|
|
* )
|
|
* )
|
|
*/
|
|
public function login(Request $request)
|
|
{
|
|
$fields = $request->validate([
|
|
'email' => 'required|email',
|
|
'password' => 'required',
|
|
]);
|
|
|
|
$user = User::where('email', $fields['email'])->first();
|
|
if (!$user || !Hash::check($fields['password'], $user->password)) {
|
|
return response()->json(['message' => 'Invalid credentials'], 401);
|
|
}
|
|
if (!$user->email_verified_at) {
|
|
return response()->json(['message' => 'Please verify your email first'], 403);
|
|
}
|
|
$token = $user->createToken('auth_token')->plainTextToken;
|
|
|
|
Log::writeLog("User '" . $user->username . "' is logged into his account");
|
|
|
|
return response()->json([
|
|
'access_token' => $token,
|
|
'token_type' => 'Bearer',
|
|
'user' => new UserResource($user),
|
|
]);
|
|
}
|
|
/**
|
|
* @OA\Post(
|
|
* path="/api/auth/logout",
|
|
* summary="Logout current user",
|
|
* tags={"Auth"},
|
|
* security={{"bearerAuth": {}}},
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Successfully logged out",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(property="message", type="string", example="Successfully logged out")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=401,
|
|
* description="Unauthenticated",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(property="message", type="string", example="Unauthenticated")
|
|
* )
|
|
* )
|
|
* )
|
|
*/
|
|
public function logout(Request $request)
|
|
{
|
|
$request->user()->currentAccessToken()->delete();
|
|
|
|
return response()->json([
|
|
'message' => 'Successfully logged out'
|
|
]);
|
|
}
|
|
/**
|
|
* @OA\Post(
|
|
* path="/api/auth/forgot-password",
|
|
* summary="Send password reset link to user email",
|
|
* tags={"Auth"},
|
|
* @OA\RequestBody(
|
|
* required=true,
|
|
* @OA\JsonContent(
|
|
* required={"email"},
|
|
* @OA\Property(property="email", type="string", format="email", example="user@example.com")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Password reset link sent successfully",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(
|
|
* property="message",
|
|
* type="string",
|
|
* example="Password reset link has been sent to your email. Please check your inbox."
|
|
* )
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=404,
|
|
* description="User not found",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(
|
|
* property="message",
|
|
* type="string",
|
|
* example="User is not found"
|
|
* )
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=422,
|
|
* description="Validation error",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(
|
|
* property="message",
|
|
* type="string",
|
|
* example="The given data was invalid."
|
|
* ),
|
|
* @OA\Property(
|
|
* property="errors",
|
|
* type="object",
|
|
* example={"email": {"The email must be a valid email address."}}
|
|
* )
|
|
* )
|
|
* )
|
|
* )
|
|
*/
|
|
public function forgotPassword(Request $request)
|
|
{
|
|
$fields = $request->validate([
|
|
'email' => 'required|email',
|
|
]);
|
|
|
|
$user = User::where('email', $fields['email'])->first();
|
|
if (!$user) {
|
|
return response()->json(['message' => 'User is not found'], 404);
|
|
}
|
|
|
|
$token = Token::existsToken($user, 'password_reset');
|
|
if(!$token) {
|
|
$token = Token::createToken($user, 'password_reset');
|
|
}
|
|
Mail::to($user->email)->send(new EmailActivation($user, $token->token));
|
|
|
|
return response()->json([
|
|
'message' => 'Password reset link has been sent to your email. Please check your inbox.'
|
|
]);
|
|
}
|
|
/**
|
|
* @OA\Post(
|
|
* path="/api/auth/reset-password",
|
|
* summary="Reset user password using token",
|
|
* tags={"Auth"},
|
|
* @OA\RequestBody(
|
|
* required=true,
|
|
* @OA\JsonContent(
|
|
* required={"token","password","password_confirmation"},
|
|
* @OA\Property(property="token", type="string", example="abcdef123456"),
|
|
* @OA\Property(property="password", type="string", format="password", example="newpassword123"),
|
|
* @OA\Property(property="password_confirmation", type="string", format="password", example="newpassword123")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Password reset successfully",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(property="message", type="string", example="Your password was successfully changed!")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=401,
|
|
* description="Invalid token",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(property="message", type="string", example="Your token is not valid")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=422,
|
|
* description="Validation error",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(property="message", type="string", example="The given data was invalid."),
|
|
* @OA\Property(
|
|
* property="errors",
|
|
* type="object",
|
|
* example={
|
|
* "password": {"The password must be at least 6 characters."},
|
|
* "password_confirmation": {"The password confirmation does not match."}
|
|
* }
|
|
* )
|
|
* )
|
|
* )
|
|
* )
|
|
*/
|
|
public function resetPassword(Request $request)
|
|
{
|
|
$fields = $request->validate([
|
|
'token' => 'required',
|
|
'password' => 'required|min:6|confirmed'
|
|
]);
|
|
$token = Token::existsTokenByToken($fields['token'], 'password_reset');
|
|
if(!$token) {
|
|
return response()->json(['message' => 'Your token is not valid'], 401);
|
|
}
|
|
$token->delete();
|
|
|
|
$user = $token->user;
|
|
$new_password = Hash::make($fields['password']);
|
|
$user->password = $new_password;
|
|
$user->save();
|
|
|
|
Log::writeLog("User '" . $user->username . "' is resetted his password");
|
|
|
|
|
|
return response()->json([
|
|
'message' => 'Your password was successfully changed!'
|
|
]);
|
|
}
|
|
/**
|
|
* @OA\Post(
|
|
* path="/api/auth/activate-account",
|
|
* summary="Confirm user account via email verification token",
|
|
* tags={"Auth"},
|
|
* @OA\RequestBody(
|
|
* required=true,
|
|
* @OA\JsonContent(
|
|
* required={"token"},
|
|
* @OA\Property(property="token", type="string", example="abcdef123456")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Account successfully activated",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(property="message", type="string", example="Your account was successfully activated")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=404,
|
|
* description="Invalid token",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(property="message", type="string", example="Your token is not valid")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=422,
|
|
* description="Validation error",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(property="message", type="string", example="The given data was invalid."),
|
|
* @OA\Property(
|
|
* property="errors",
|
|
* type="object",
|
|
* example={"token": {"The token field is required."}}
|
|
* )
|
|
* )
|
|
* )
|
|
* )
|
|
*/
|
|
public function confirmationAccount(Request $request)
|
|
{
|
|
$fields = $request->validate([
|
|
'token' => 'required'
|
|
]);
|
|
$token = Token::existsTokenByToken($fields['token'], 'email_verification');
|
|
if(!$token) {
|
|
return response()->json(['message' => 'Your token is not valid'], 404);
|
|
}
|
|
$user = $token->user;
|
|
$token->delete();
|
|
|
|
if ($user->email_verified_at) {
|
|
return response()->json([
|
|
'message' => 'Your account has already been verified.'
|
|
]);
|
|
}
|
|
|
|
$user->email_verified_at = now();
|
|
$user->save();
|
|
|
|
return response()->json(['message' => 'Your account was successfully activated']);
|
|
}
|
|
/**
|
|
* @OA\Get(
|
|
* path="/api/auth/me",
|
|
* summary="Get current user info",
|
|
* tags={"Auth"},
|
|
* security={{"bearerAuth": {}}},
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="User info",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(property="user", ref="#/components/schemas/UserResource")
|
|
* )
|
|
* ),
|
|
* @OA\Response(response=401, description="Unauthenticated")
|
|
* )
|
|
*/
|
|
public function me(Request $request)
|
|
{
|
|
return response()->json([
|
|
'user' => new UserResource($request->user())
|
|
]);
|
|
}
|
|
}
|