Reversion for user auth changes

This commit is contained in:
David Bomba 2025-05-28 08:16:55 +10:00
parent 0b49cf90b3
commit d1e466a158
15 changed files with 285 additions and 308 deletions

View File

@ -105,11 +105,11 @@ class AccountController extends BaseController
$company_user = $cu->first();
// $truth = app()->make(TruthSource::class);
// $truth->setCompanyUser($company_user);
// $truth->setUser($company_user->user);
// $truth->setCompany($company_user->company);
// $truth->setCompanyToken($company_user->tokens()->where('user_id', $company_user->user_id)->where('company_id', $company_user->company_id)->first());
$truth = app()->make(TruthSource::class);
$truth->setCompanyUser($company_user);
$truth->setUser($company_user->user);
$truth->setCompany($company_user->company);
$truth->setCompanyToken($company_user->tokens()->where('user_id', $company_user->user_id)->where('company_id', $company_user->company_id)->first());
return $this->listResponse($cu);
}

View File

@ -122,7 +122,7 @@ class ContactResetPasswordController extends Controller
event(new PasswordReset($user));
auth()->login($user, true);
auth()->login($user, false);
$response = Password::PASSWORD_RESET;

View File

@ -39,7 +39,6 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Response;
use Laravel\Socialite\Facades\Socialite;
use Microsoft\Graph\Model;
@ -73,6 +72,20 @@ class LoginController extends BaseController
parent::__construct();
}
/**
* Once the user is authenticated, we need to set
* the default company into a session variable.
*
* @param Request $request
* @param User $user
* @return void
* @deprecated .1 API ONLY we don't need to set any session variables
*/
public function authenticated(Request $request, User $user): void
{
//$this->setCurrentCompanyId($user->companies()->first()->account->default_company_id);
}
/**
* Login via API.
*
@ -83,10 +96,8 @@ class LoginController extends BaseController
{
$this->forced_includes = ['company_users'];
/** Checks the required fields for auth are present */
$this->validateLogin($request);
/** Native laravel login throttling */
if ($this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
@ -96,23 +107,18 @@ class LoginController extends BaseController
->header('X-Api-Version', config('ninja.minimum_client_version'));
}
// Direct user query based on email and password verification
$user = MultiDB::hasUser(['email' => $request->email]);
if ($user && \Illuminate\Support\Facades\Hash::check(trim($request->password), $user->password)) {
//Authenticate for this request only.
auth()->login($user, false);
auth()->user()->setContext($user->account->default_company, $user->tokens()->where('company_id', $user->account->default_company_id)->where('is_system', true)->first());
if ($this->attemptLogin($request)) {
LightLogs::create(new LoginSuccess())
->increment()
->batch();
LightLogs::create(new LoginMeta($request->email, $request->ip(), 'success'))
LightLogs::create(new LoginMeta($request->email, $request->ip, 'success'))
->batch();
// Process2FA on this request if the parameters are present.
/** @var \App\Models\User $user */
$user = $this->guard()->user();
//2FA
if ($user->google_2fa_secret && $request->has('one_time_password')) {
$google2fa = new Google2FA();
@ -140,8 +146,6 @@ class LoginController extends BaseController
/** @var \App\Models\CompanyUser $cu */
$cu = $this->hydrateCompanyUser();
nlog("LOGIN:: ".$request->email." {$user->account_id}");
if ($cu->count() == 0) {
return response()->json(['message' => 'User found, but not attached to any companies, please see your administrator'], 400);
}
@ -159,7 +163,7 @@ class LoginController extends BaseController
->increment()
->batch();
LightLogs::create(new LoginMeta($request->email, $request->ip(), 'failure'))
LightLogs::create(new LoginMeta($request->email, $request->ip, 'failure'))
->batch();
$this->incrementLoginAttempts($request);
@ -179,7 +183,13 @@ class LoginController extends BaseController
*/
public function refresh(Request $request)
{
$company_token = auth()->user()->getCurrentToken();
$truth = app()->make(TruthSource::class);
if ($truth->getCompanyToken()) {
$company_token = $truth->getCompanyToken();
} else {
$company_token = CompanyToken::where('token', $request->header('X-API-TOKEN'))->first();
}
$cu = CompanyUser::query()
->where('user_id', $company_token->user_id);
@ -238,27 +248,12 @@ class LoginController extends BaseController
->header('X-App-Version', config('ninja.app_version'))
->header('X-Api-Version', config('ninja.minimum_client_version'));
}
/**
* getSocialiteUser
*
* Returns the socialite user if successful
* @param string $provider
* @param string $token
*/
private function getSocialiteUser(string $provider, string $token)
{
return Socialite::driver($provider)->userFromToken($token);
}
/**
* handleSocialiteLogin
*
* Handles authentication for Apple OAuth only!
*
* @param string $provider
* @param string $token
*/
private function handleSocialiteLogin($provider, $token)
{
$user = $this->getSocialiteUser($provider, $token);
@ -272,13 +267,7 @@ class LoginController extends BaseController
->header('X-App-Version', config('ninja.app_version'))
->header('X-Api-Version', config('ninja.minimum_client_version'));
}
/**
* loginOrCreateFromSocialite
*
* @param mixed $user
* @param string $provider
*/
private function loginOrCreateFromSocialite($user, $provider)
{
$query = [
@ -291,8 +280,7 @@ class LoginController extends BaseController
return response()->json(['message' => 'User exists, but not attached to any companies! Orphaned user!'], 400);
}
auth()->login($existing_user, false);
auth()->user()->setContext($existing_user->account->default_company, $existing_user->tokens()->where('company_id', $existing_user->account->default_company_id)->where('is_system', true)->first());
Auth::login($existing_user, false);
/** @var \App\Models\CompanyUser $cu */
$cu = $this->hydrateCompanyUser();
@ -307,7 +295,39 @@ class LoginController extends BaseController
return $this->timeConstrainedResponse($cu);
}
//If this is a result user/email combo - lets add their OAuth details details
if ($existing_login_user = MultiDB::hasUser(['email' => $user->email])) {
if (!$existing_login_user->account) {
return response()->json(['message' => 'User exists, but not attached to any companies! Orphaned user!'], 400);
}
Auth::login($existing_login_user, false);
/** @var \App\Models\User $user */
$user = auth()->user();
$user->update([
'oauth_user_id' => $user->id,
'oauth_provider_id' => $provider,
]);
/** @var \App\Models\CompanyUser $cu */
$cu = $this->hydrateCompanyUser();
if ($cu->count() == 0) {
return response()->json(['message' => 'User found, but not attached to any companies, please see your administrator'], 400);
}
if (Ninja::isHosted() && !$cu->first()->is_owner && !$existing_login_user->account->isEnterprisePaidClient()) {
return response()->json(['message' => 'Pro / Free accounts only the owner can log in. Please upgrade'], 403);
}
return $this->timeConstrainedResponse($cu);
}
// nlog("socialite");
// nlog($user);
$name = OAuth::splitName($user->name);
if ($provider == 'apple') {
@ -332,11 +352,10 @@ class LoginController extends BaseController
$account = (new CreateAccount($new_account, request()->getClientIp()))->handle();
$user = $account->users()->first();
Auth::login($account->default_company->owner(), false);
auth()->login($user, false);
auth()->user()->setCompany($account->default_company);
auth()->user()->setContext($account->default_company, $user->tokens()->where('company_id', $account->default_company_id)->where('is_system', true)->first());
/** @var \App\Models\User $user */
$user = auth()->user();
$user->email_verified_at = now();
$user->save();
@ -354,14 +373,7 @@ class LoginController extends BaseController
return $this->timeConstrainedResponse($cu);
}
/**
* hydrateCompanyUser
*
* Hydrates the company user for the response
*
* @return Builder
*/
private function hydrateCompanyUser(): Builder
{
@ -385,12 +397,14 @@ class LoginController extends BaseController
$this->setLoginCache($user);
// $truth = app()->make(TruthSource::class);
// $truth->setCompanyUser($cu->first());
// $truth->setUser($user);
// $truth->setCompany($set_company);
$truth = app()->make(TruthSource::class);
$truth->setCompanyUser($cu->first());
$truth->setUser($user);
$truth->setCompany($set_company);
//21-03-2024
$cu->each(function ($cu) {
/** @var \App\Models\CompanyUser $cu */
if (CompanyToken::query()->where('company_id', $cu->company_id)->where('user_id', $cu->user_id)->where('is_system', true)->doesntExist()) {
@ -398,9 +412,7 @@ class LoginController extends BaseController
}
});
// $truth->setCompanyToken(CompanyToken::where('user_id', $user->id)->where('company_id', $set_company->id)->where('is_system', true)->first());
$user->setContext($set_company, CompanyToken::where('user_id', $user->id)->where('company_id', $set_company->id)->where('is_system', true)->first());
$truth->setCompanyToken(CompanyToken::where('user_id', $user->id)->where('company_id', $set_company->id)->where('is_system', true)->first());
return CompanyUser::query()->where('user_id', $user->id);
}
@ -444,17 +456,6 @@ class LoginController extends BaseController
return response()->json(['message' => 'User exists, but never authenticated with OAuth, please use your email and password to login.'], 400);
}
// If this is a result user/email combo - lets add their OAuth details details
// if ($email && $existing_login_user = MultiDB::hasUser(['email' => $email, 'oauth_provider_id' => 'microsoft'])) {
// if (!$existing_login_user->account) {
// return response()->json(['message' => 'User exists, but not attached to any companies! Orphaned user!'], 400);
// }
// Auth::login($existing_login_user, true);
// return $this->existingLoginUser($user->getId(), 'microsoft');
// }
// Signup!
if (request()->has('create') && request()->input('create') == 'true') {
$new_account = [
@ -484,9 +485,7 @@ class LoginController extends BaseController
*/
private function existingOauthUser($existing_user)
{
auth()->login($existing_user, false);
auth()->user()->setContext($existing_user->account->default_company, $existing_user->tokens()->where('company_id', $existing_user->account->default_company->id)->where('is_system', true)->first());
Auth::login($existing_user, false);
/** @var \App\Models\CompanyUser $cu */
$cu = $this->hydrateCompanyUser();
@ -502,6 +501,31 @@ class LoginController extends BaseController
return $this->timeConstrainedResponse($cu);
}
private function existingLoginUser($oauth_user_id, $provider)
{
/** @var \App\Models\User $user */
$user = auth()->user();
$user->update([
'oauth_user_id' => $oauth_user_id,
'oauth_provider_id' => $provider,
]);
/** @var \App\Models\CompanyUser $cu */
$cu = $this->hydrateCompanyUser();
if ($cu->count() == 0) {
return response()->json(['message' => 'User found, but not attached to any companies, please see your administrator'], 400);
}
if (Ninja::isHosted() && !$cu->first()->is_owner && !auth()->user()->account->isEnterprisePaidClient()) {
return response()->json(['message' => 'Pro / Free accounts only the owner can log in. Please upgrade'], 403);
}
return $this->timeConstrainedResponse($cu);
}
private function handleGoogleOauth()
{
$user = false;
@ -534,30 +558,20 @@ class LoginController extends BaseController
return response()->json(['message' => 'Please use your email and password to login.'], 400);
}
// 2025-05-19 - this caused an issue when a user/email password combo user used their google account to login, it raced through and attempted to create a new account.
//If this is a result user/email combo - lets add their OAuth details details
// if ($existing_login_user = MultiDB::hasUser(['email' => $google->harvestEmail($user), 'oauth_provider_id' => 'google'])) {
// if (!$existing_login_user->account) {
// return response()->json(['message' => 'User exists, but not attached to any companies! Orphaned user!'], 400);
// }
// Auth::login($existing_login_user, true);
// return $this->existingLoginUser($google->harvestSubField($user), 'google');
// }
}
if ($user) {
//check the user doesn't already exist in some form
// if ($existing_login_user = MultiDB::hasUser(['email' => $google->harvestEmail($user), 'oauth_provider_id' => 'google'])) {
// if (!$existing_login_user->account) {
// return response()->json(['message' => 'User exists, but not attached to any companies! Orphaned user!'], 400);
// }
if ($existing_login_user = MultiDB::hasUser(['email' => $google->harvestEmail($user), 'oauth_provider_id' => 'google'])) {
if (!$existing_login_user->account) {
return response()->json(['message' => 'User exists, but not attached to any companies! Orphaned user!'], 400);
}
// Auth::login($existing_login_user, true);
Auth::login($existing_login_user, false);
// return $this->existingLoginUser($google->harvestSubField($user), 'google');
// }
return $this->existingLoginUser($google->harvestSubField($user), 'google');
}
if (request()->has('create') && request()->input('create') == 'true') {
//user not found anywhere - lets sign them up.
@ -593,11 +607,10 @@ class LoginController extends BaseController
return $account;
}
$user = $account->default_company->owner();
// Auth::login($user, true);
auth()->login($user, false);
auth()->user()->setCompany($account->default_company);
auth()->user()->setContext($account->default_company, $user->tokens()->where('company_id', $account->default_company_id)->where('is_system', true)->first());
Auth::login($account->default_company->owner(), false);
/** @var \App\Models\User $user */
$user = auth()->user();
$user->email_verified_at = now();
$user->save();

View File

@ -12,51 +12,52 @@
namespace App\Http;
use App\Http\Middleware\ApiSecretCheck;
use App\Http\Middleware\Cors;
use App\Http\Middleware\SetDb;
use App\Http\Middleware\Locale;
use App\Http\Middleware\SetWebDb;
use App\Http\Middleware\UrlSetDb;
use App\Http\Middleware\TokenAuth;
use App\Http\Middleware\SetEmailDb;
use App\Http\Middleware\VerifyHash;
use App\Http\Middleware\SetInviteDb;
use App\Http\Middleware\TrimStrings;
use App\Http\Middleware\Authenticate;
use App\Http\Middleware\CheckClientExistence;
use App\Http\Middleware\CheckForMaintenanceMode;
use App\Http\Middleware\ClientPortalEnabled;
use App\Http\Middleware\ContactSetDb;
use App\Http\Middleware\QueryLogging;
use App\Http\Middleware\TrustProxies;
use App\Http\Middleware\UserVerified;
use App\Http\Middleware\VendorLocale;
use App\Http\Middleware\PhantomSecret;
use App\Http\Middleware\SetDocumentDb;
use App\Http\Middleware\ApiSecretCheck;
use App\Http\Middleware\ContactAccount;
use App\Http\Middleware\EncryptCookies;
use App\Http\Middleware\SessionDomains;
use App\Http\Middleware\ContactKeyLogin;
use App\Http\Middleware\ContactRegister;
use App\Http\Middleware\ContactSetDb;
use App\Http\Middleware\ContactTokenAuth;
use App\Http\Middleware\Cors;
use App\Http\Middleware\EncryptCookies;
use App\Http\Middleware\Locale;
use App\Http\Middleware\PasswordProtection;
use App\Http\Middleware\PhantomSecret;
use App\Http\Middleware\QueryLogging;
use App\Http\Middleware\RedirectIfAuthenticated;
use App\Http\Middleware\SessionDomains;
use App\Http\Middleware\SetDbByCompanyKey;
use App\Http\Middleware\SetDocumentDb;
use App\Http\Middleware\SetDomainNameDb;
use App\Http\Middleware\SetEmailDb;
use App\Http\Middleware\SetInviteDb;
use App\Http\Middleware\SetWebDb;
use App\Http\Middleware\TokenAuth;
use App\Http\Middleware\TrimStrings;
use App\Http\Middleware\TrustProxies;
use App\Http\Middleware\UrlSetDb;
use App\Http\Middleware\UserVerified;
use App\Http\Middleware\ValidateSignature;
use App\Http\Middleware\VendorContactKeyLogin;
use App\Http\Middleware\VendorLocale;
use App\Http\Middleware\VerifyCsrfToken;
use App\Http\Middleware\VerifyHash;
use Illuminate\Auth\Middleware\AuthenticateWithBasicAuth;
use App\Http\Middleware\ContactTokenAuth;
use Illuminate\Auth\Middleware\Authorize;
use Illuminate\Auth\Middleware\EnsureEmailIsVerified;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
use Illuminate\Foundation\Http\Middleware\ValidatePostSize;
use App\Http\Middleware\SetDbByCompanyKey;
use App\Http\Middleware\ValidateSignature;
use App\Http\Middleware\PasswordProtection;
use App\Http\Middleware\ClientPortalEnabled;
use App\Http\Middleware\CheckClientExistence;
use App\Http\Middleware\VendorContactKeyLogin;
use Illuminate\Http\Middleware\SetCacheHeaders;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\StartSession;
use App\Http\Middleware\CheckForMaintenanceMode;
use App\Http\Middleware\RedirectIfAuthenticated;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
use Illuminate\Auth\Middleware\EnsureEmailIsVerified;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\View\Middleware\ShareErrorsFromSession;
use Illuminate\Auth\Middleware\AuthenticateWithBasicAuth;
use Illuminate\Foundation\Http\Middleware\ValidatePostSize;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
class Kernel extends HttpKernel
{
@ -150,6 +151,7 @@ class Kernel extends HttpKernel
'portal_enabled' => ClientPortalEnabled::class,
'url_db' => UrlSetDb::class,
'web_db' => SetWebDb::class,
'api_db' => SetDb::class,
'company_key_db' => SetDbByCompanyKey::class,
'locale' => Locale::class,
'vendor_locale' => VendorLocale::class,
@ -172,6 +174,7 @@ class Kernel extends HttpKernel
SessionDomains::class,
Cors::class,
SetDomainNameDb::class,
SetDb::class,
SetWebDb::class,
UrlSetDb::class,
ContactSetDb::class,

View File

@ -0,0 +1,48 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://www.elastic.co/licensing/elastic-license
*/
namespace App\Http\Middleware;
use App\Libraries\MultiDB;
use Closure;
use Illuminate\Http\Request;
use stdClass;
class SetDb
{
/**
* Handle an incoming request.
*
* @param Request $request
* @param Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$error = [
'message' => 'Invalid Token',
'errors' => new stdClass(),
];
if ($request->header('X-API-TOKEN') && config('ninja.db.multi_db_enabled')) {
if (! MultiDB::findAndSetDb($request->header('X-API-TOKEN'))) {
return response()->json($error, 403);
}
} elseif (! config('ninja.db.multi_db_enabled')) {
return $next($request);
} else {
return response()->json($error, 403);
}
return $next($request);
}
}

View File

@ -32,18 +32,18 @@ class TokenAuth
*/
public function handle($request, Closure $next)
{
if (config('ninja.db.multi_db_enabled') &&
$request->header('X-API-TOKEN') &&
($company_token = MultiDB::getCompanyToken($request->header('X-API-TOKEN')))) {
} elseif ($request->header('X-API-TOKEN') && ($company_token = CompanyToken::with([
if ($request->header('X-API-TOKEN') && ($company_token = CompanyToken::with([
'user.account',
'company',
'account',
'cu',
])->where('token', $request->header('X-API-TOKEN'))->first())) {
} else {
return response()->json(['message' => 'Invalid token'], 403);
}
$user = $company_token->user;
$error = [
@ -64,6 +64,24 @@ class TokenAuth
return response()->json($error, 403);
}
/*
|
| Necessary evil here: As we are authenticating on CompanyToken,
| we need to link the company to the user manually. This allows
| us to decouple a $user and their attached companies completely.
|
*/
$truth = app()->make(TruthSource::class);
$truth->setCompanyUser($company_token->cu);
$truth->setUser($company_token->user);
$truth->setCompany($company_token->company);
$truth->setCompanyToken($company_token);
$truth->setPremiumHosted($company_token->account->isPremium());
/*
| This method binds the db to the jobs created using this
| session
*/
app('queue')->createPayloadUsing(function () use ($company_token) {
return ['db' => $company_token->company->db];
});
@ -81,13 +99,7 @@ class TokenAuth
//stateless, don't remember the user.
auth()->login($user, false);
auth()->user()->setCompany($company_token->company);
auth()->user()->setContext($company_token->company, $company_token);
// Alternative: Bind context to service container for request duration
app()->instance('current.company', $company_token->company);
app()->instance('current.company_user', $company_token->cu);
app()->instance('current.company_token', $company_token);
return $next($request);
}
}

View File

@ -84,7 +84,7 @@ class BaseImport
)
: null;
auth()->login($this->company->owner(), true);
auth()->login($this->company->owner(), false);
/** @var \App\Models\User $user */
$user = auth()->user();

View File

@ -115,8 +115,6 @@ class CreateAccount
event(new AccountCreated($spaa9f78, $sp035a66, Ninja::eventVars()));
}
//@replaces truthsource
auth()->user()->setContext($sp035a66, $sp2d97e8);
$spaa9f78->fresh();

View File

@ -191,108 +191,6 @@ class User extends Authenticatable implements MustVerifyEmail
'referral_earnings' => AsReferralEarningCollection::class,
];
////////////////////////////////////////////////////////////////////////////////////
private ?Company $contextCompany = null;
private ?CompanyUser $contextCompanyUser = null;
private ?CompanyToken $contextToken = null;
// Set context explicitly
public function setContext(Company $company, ?CompanyToken $token = null): self
{
$this->contextCompany = $company;
$this->contextToken = $token;
$this->contextCompanyUser = $token?->company_user;
return $this;
}
// Transfer context from authenticated user to this instance
public function inheritContextFromAuth(): self
{
if (auth()->check() && auth()->user()->id === $this->id) {
$authUser = auth()->user();
$this->contextCompany = $authUser->contextCompany;
$this->contextToken = $authUser->contextToken;
$this->contextCompanyUser = $authUser->contextCompanyUser;
}
return $this;
}
// Get current company with fallback chain
public function getCurrentCompany(): Company
{
// 1. Use explicit context if set
if ($this->contextCompany) {
return $this->contextCompany;
}
// 2. Try service container binding (if available)
if (app()->bound('current.company')) {
return app('current.company');
}
// 3. Use token-based lookup
if ($token = $this->getCurrentToken()) {
return $token->company;
}
// 4. Use default company
$defaultCompany = $this->companies()->first();
if ($defaultCompany instanceof Company) {
return $defaultCompany;
}
throw new \Exception('No Company Found for user ID: ' . $this->id);
}
public function getCurrentCompanyUser(): ?CompanyUser
{
nlog("getcu");
if ($this->contextCompanyUser) {
nlog("level1");
return $this->contextCompanyUser;
}
// Try service container binding (if available)
if (app()->bound('current.company_user')) {
nlog("level2");
return app('current.company_user');
}
$company = $this->getCurrentCompany();
nlog($company?->id);
nlog("level3");
nlog("xxxx ".$this->company_users()->count());
nlog("id = ". $this->id);
return $this->company_users()
->where('company_id', $company->id)
->where('user_id', $this->id)
->first();
}
public function getCurrentToken(): ?CompanyToken
{
if ($this->contextToken) {
return $this->contextToken;
}
if ($apiToken = request()->header('X-API-TOKEN')) {
return CompanyToken::where('token', $apiToken)->first();
}
return $this->tokens()->first();
}
/////////////////////////////////////////////////////
public function name()
{
return $this->first_name.' '.$this->last_name;
@ -330,19 +228,18 @@ class User extends Authenticatable implements MustVerifyEmail
public function token()
{
return $this->getCurrentToken();
// $truth = app()->make(TruthSource::class);
$truth = app()->make(TruthSource::class);
// if ($truth->getCompanyToken()) {
// return $truth->getCompanyToken();
// }
if ($truth->getCompanyToken()) {
return $truth->getCompanyToken();
}
// // if (request()->header('X-API-TOKEN')) {
// if (request()->header('X-API-TOKEN')) {
// return CompanyToken::with(['cu'])->where('token', request()->header('X-API-TOKEN'))->first();
// }
if (request()->header('X-API-TOKEN')) {
return CompanyToken::with(['cu'])->where('token', request()->header('X-API-TOKEN'))->first();
}
// return $this->tokens()->first();
return $this->tokens()->first();
}
/**
@ -373,20 +270,19 @@ class User extends Authenticatable implements MustVerifyEmail
*/
public function getCompany(): ?Company
{
return $this->getCurrentCompany();
// $truth = app()->make(TruthSource::class);
$truth = app()->make(TruthSource::class);
// // @phpstan-ignore-next-line
// if ($this->company) {
// return $this->company;
// } elseif ($truth->getCompany()) {
// return $truth->getCompany();
// } elseif (request()->header('X-API-TOKEN')) {
// $company_token = CompanyToken::with('company')->where('token', request()->header('X-API-TOKEN'))->first();
// return $company_token->company;
// }
// @phpstan-ignore-next-line
if ($this->company) {
return $this->company;
} elseif ($truth->getCompany()) {
return $truth->getCompany();
} elseif (request()->header('X-API-TOKEN')) {
$company_token = CompanyToken::with('company')->where('token', request()->header('X-API-TOKEN'))->first();
return $company_token->company;
}
// throw new \Exception('No Company Found');
throw new \Exception('No Company Found');
}
public function companyIsSet(): bool
@ -411,30 +307,28 @@ class User extends Authenticatable implements MustVerifyEmail
public function co_user()
{
return $this->getCurrentCompanyUser();
// $truth = app()->make(TruthSource::class);
$truth = app()->make(TruthSource::class);
// if ($truth->getCompanyUser()) {
// return $truth->getCompanyUser();
// }
if ($truth->getCompanyUser()) {
return $truth->getCompanyUser();
}
// return $this->token()->cu;
return $this->token()->cu;
}
public function company_user()
{
return $this->getCurrentCompanyUser();
// if ($this->companyId()) {
// return $this->belongsTo(CompanyUser::class)->where('company_id', $this->companyId())->withTrashed();
// }
if ($this->companyId()) {
return $this->belongsTo(CompanyUser::class)->where('company_id', $this->companyId())->withTrashed();
}
// $truth = app()->make(TruthSource::class);
$truth = app()->make(TruthSource::class);
// if ($truth->getCompanyUser()) {
// return $truth->getCompanyUser();
// }
if ($truth->getCompanyUser()) {
return $truth->getCompanyUser();
}
// return $this->token()->cu;
return $this->token()->cu;
}

View File

@ -82,9 +82,11 @@ class AppServiceProvider extends ServiceProvider
});
/* Ensure we don't have stale state in jobs */
// Queue::before(function (JobProcessing $event) {
// App::forgetInstance(TruthSource::class);
// });
Queue::before(function (JobProcessing $event) {
App::forgetInstance(TruthSource::class);
});
app()->instance(TruthSource::class, new TruthSource());
/* Extension for custom mailers */

View File

@ -92,7 +92,7 @@ class UserRepository extends BaseRepository
/*No company user exists - attach the user*/
if (! $cu) {
$data['company_user']['account_id'] = $account->id;
$data['company_user']['notifications'] = CompanySettings::notificationDefaults();
$data['company_user']['notifications'] = isset($data['company_user']['notifications']['email']) ? $data['company_user']['notifications'] : CompanySettings::notificationDefaults();
$user->companies()->attach($company->id, $data['company_user']);
} else {
if (auth()->user()->isAdmin()) {

View File

@ -139,7 +139,7 @@ Route::group(['middleware' => ['throttle:login', 'api_secret_check', 'email_db']
Route::post('api/v1/reset_password', [ForgotPasswordController::class, 'sendResetLinkEmail']);
});
Route::group(['middleware' => ['throttle:api', 'token_auth', 'valid_json','locale'], 'prefix' => 'api/v1', 'as' => 'api.'], function () {
Route::group(['middleware' => ['throttle:api', 'api_db', 'token_auth', 'valid_json','locale'], 'prefix' => 'api/v1', 'as' => 'api.'], function () {
Route::post('password_timeout', PasswordTimeoutController::class)->name('password_timeout');
Route::put('accounts/{account}', [AccountController::class, 'update'])->name('account.update');

View File

@ -121,10 +121,10 @@ class CsvImportTest extends TestCase
// $this->user->setContext($this->company, $this->token);
// $truth = app()->make(TruthSource::class);
// $truth->setCompanyUser($this->cu);
// $truth->setUser($this->user);
// $truth->setCompany($this->company);
$truth = app()->make(TruthSource::class);
$truth->setCompanyUser($this->cu);
$truth->setUser($this->user);
$truth->setCompany($this->company);
$csv_importer = new Csv($data, $this->company);

View File

@ -117,7 +117,14 @@ class UserTest extends TestCase
$company_token->is_system = true;
$company_token->save();
auth()->user()->setContext($company, $company_token);
// auth()->user()->setContext($company, $company_token);
$truth = app()->make(TruthSource::class);
$truth->setCompanyUser($company_token->cu);
$truth->setUser($company_token->user);
$truth->setCompany($company_token->company);
$truth->setCompanyToken($company_token);
return $company_token;

View File

@ -295,12 +295,12 @@ trait MockAccountData
$company_token->save();
$user->setContext($this->company, $company_token);
// $user->setContext($this->company, $company_token);
// $truth = app()->make(TruthSource::class);
// $truth->setCompanyUser($company_token->first());
// $truth->setUser($this->user);
// $truth->setCompany($this->company);
$truth = app()->make(TruthSource::class);
$truth->setCompanyUser($company_token->first());
$truth->setUser($this->user);
$truth->setCompany($this->company);
//todo create one token with token name TOKEN - use firstOrCreate