Skip to content

Commit

Permalink
Merge pull request #40 from fleetbase/feature-authentication
Browse files Browse the repository at this point in the history
feature: 2FA
  • Loading branch information
TemuulenBM authored Jan 22, 2024
2 parents c9f4564 + 32bd87c commit efc94ef
Show file tree
Hide file tree
Showing 16 changed files with 1,303 additions and 30 deletions.
42 changes: 36 additions & 6 deletions src/Http/Controllers/Internal/v1/AuthController.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@
use Fleetbase\Models\VerificationCode;
use Fleetbase\Notifications\UserForgotPassword;
use Fleetbase\Support\Auth;
use Fleetbase\Support\TwoFactorAuth;
use Fleetbase\Support\Utils;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Str;
use Laravel\Sanctum\PersonalAccessToken;

class AuthController extends Controller
{
Expand All @@ -32,14 +34,43 @@ class AuthController extends Controller
*/
public function login(LoginRequest $request)
{
$email = $request->input('email');
$password = $request->input('password');
$user = User::where('email', $email)->first();
$identity = $request->input('identity');
$password = $request->input('password');
$authToken = $request->input('authToken');

// if attempting to authenticate with auth token validate it first against database and respond with it
if ($authToken) {
$personalAccessToken = PersonalAccessToken::findToken($authToken);

if ($personalAccessToken) {
return response()->json(['token' => $authToken]);
}
}

// Find the user using the identity provided
$user = User::where(function ($query) use ($identity) {
$query->where('email', $identity)->orWhere('phone', $identity);
})->first();

if (!$user) {
return response()->error('No user found by this email.', 401, ['code' => 'no_user']);
return response()->error('No user found by the provided identity.', 401, ['code' => 'no_user']);
}

// Check if 2FA enabled
if (TwoFactorAuth::isEnabled($user)) {
$twoFaSession = TwoFactorAuth::start($user);

return response()->json([
'twoFaSession' => $twoFaSession,
'isEnabled' => true,
]);
}

// Create token
$token = $user->createToken($user->uuid);

return response()->json(['token' => $token->plainTextToken]);

if (Auth::isInvalidPassword($password, $user->password)) {
return response()->error('Authentication failed using password provided.', 401, ['code' => 'invalid_password']);
}
Expand Down Expand Up @@ -418,8 +449,7 @@ public function signUp(SignUpRequest $request)
$companyDetails = $request->input('company');

$newUser = Auth::register($userDetails, $companyDetails);

$token = $newUser->createToken($request->ip());
$token = $newUser->createToken($newUser->uuid);

return response()->json(['token' => $token->plainTextToken]);
}
Expand Down
45 changes: 45 additions & 0 deletions src/Http/Controllers/Internal/v1/CompanyController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
use Fleetbase\Http\Resources\Organization;
use Fleetbase\Models\Company;
use Fleetbase\Models\Invite;
use Fleetbase\Support\Auth;
use Fleetbase\Support\TwoFactorAuth;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class CompanyController extends FleetbaseController
Expand Down Expand Up @@ -39,4 +42,46 @@ public function findCompany(string $id)

return new Organization($company);
}

/**
* Get the current organization's two factor authentication settings.
*
* @return \Illuminate\Http\Response
*/
public function getTwoFactorSettings()
{
$company = Auth::getCompany();

if (!$company) {
return response()->error('No company session found', 401);
}

$twoFaSettings = TwoFactorAuth::getTwoFaSettingsForCompany($company);

return response()->json($twoFaSettings->value);
}


/**
* Save the two factor authentication settings for the current company.
*
* @param \Illuminate\Http\Request $request The HTTP request.
*
* @return \Illuminate\Http\Response
*/
public function saveTwoFactorSettings(Request $request)
{
$twoFaSettings = $request->array('twoFaSettings');
$company = Auth::getCompany();

if (!$company) {
return response()->error('No company session found', 401);
}
if (isset($twoFaSettings['enabled']) && $twoFaSettings['enabled'] === false) {
$twoFaSettings['enforced'] = false;
}
TwoFactorAuth::saveTwoFaSettingsForCompany($company, $twoFaSettings);

return response()->json(['message' => 'Two-Factor Authentication saved successfully']);
}
}
166 changes: 166 additions & 0 deletions src/Http/Controllers/Internal/v1/TwoFaController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
<?php

namespace Fleetbase\Http\Controllers\Internal\v1;

use Fleetbase\Http\Controllers\Controller;
use Fleetbase\Http\Requests\TwoFaValidationRequest;
use Fleetbase\Models\Company;
use Fleetbase\Support\TwoFactorAuth;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

/**
* Class TwoFaController.
*/
class TwoFaController extends Controller
{
/**
* Save Two-Factor Authentication system wide settings.
*
* @return \Illuminate\Http\Response
*/
public function saveSystemConfig(Request $request)
{
$twoFaSettings = $request->array('twoFaSettings');
if (isset($twoFaSettings['enabled']) && $twoFaSettings['enabled'] === false) {
$twoFaSettings['enforced'] = false;
}
$settings = TwoFactorAuth::configureTwoFaSettings($twoFaSettings);

return response()->json($settings->value);
}

/**
* Get Two-Factor Authentication system wide settings.
*
* @return \Illuminate\Http\Response
*/
public function getSystemConfig()
{
$settings = TwoFactorAuth::getTwoFaConfiguration();

return response()->json($settings->value);
}

/**
* Check Two-Factor Authentication status for a given user identity.
*
* @return \Illuminate\Http\Response
*/
public function checkTwoFactor(Request $request)
{
$identity = $request->input('identity');
$twoFaSession = TwoFactorAuth::createTwoFaSessionIfEnabled($identity);
$isTwoFaEnabled = $twoFaSession !== null;

return response()->json([
'twoFaSession' => $twoFaSession,
'isTwoFaEnabled' => $isTwoFaEnabled,
]);
}

/**
* Verify Two-Factor Authentication code.
*
* @return \Illuminate\Http\Response
*/
public function validateSession(TwoFaValidationRequest $request)
{
$token = $request->input('token');
$identity = $request->input('identity');
$clientToken = $request->input('clientToken');

try {
$validClientToken = TwoFactorAuth::getClientSessionTokenFromTwoFaSession($token, $identity, $clientToken);

return response()->json([
'clientToken' => $validClientToken,
'expired' => false,
]);
} catch (\Exception $e) {
$errorMessage = $e->getMessage();

if (Str::contains($errorMessage, ['2FA Verification', 'expired'])) {
return response()->json([
'expired' => true,
]);
}

return response()->error($errorMessage);
}
}

/**
* Verify Two-Factor Authentication code.
*
* @return \Illuminate\Http\Response
*/
public function verifyCode(Request $request)
{
$code = $request->input('code');
$token = $request->input('token');
$clientToken = $request->input('clientToken');

try {
$authToken = TwoFactorAuth::verifyCode($code, $token, $clientToken);

return response()->json([
'authToken' => $authToken,
]);
} catch (\Exception $e) {
return response()->error($e->getMessage());
}
}

/**
* Resend Two-Factor Authentication verification code.
*
* @return \Illuminate\Http\Response
*/
public function resendCode(Request $request)
{
$identity = $request->input('identity');
$token = $request->input('token');

try {
$clientToken = TwoFactorAuth::resendCode($identity, $token);

return response()->json([
'clientToken' => $clientToken,
]);
} catch (\Exception $e) {
return response()->error($e->getMessage());
}
}

/**
* Invalidate the current two-factor session.
*
* @return \Illuminate\Http\Response
*/
public function invalidateSession(Request $request)
{
$identity = $request->input('identity');
$token = $request->input('token');

try {
$ok = TwoFactorAuth::forgetTwoFaSession($token, $identity);

return response()->json([
'ok' => $ok,
]);
} catch (\Exception $e) {
return response()->json(['ok' => false]);
}
}

public function shouldEnforce(Request $request)
{
$user = $request->user();
$enforceTwoFa = TwoFactorAuth::shouldEnforce($user);

return response()->json([
'shouldEnforce' => $enforceTwoFa,
]);
}
}
Loading

0 comments on commit efc94ef

Please sign in to comment.