Merge branch 'v5-develop' of https://github.com/turbo124/invoiceninja into v5-develop

This commit is contained in:
David Bomba 2022-06-29 10:38:56 +10:00
commit 7129cd1e6f
15 changed files with 136124 additions and 135711 deletions

View File

@ -235,6 +235,9 @@ class InvitationController extends Controller
->with('contact.client')
->firstOrFail();
if($invitation->contact->trashed())
$invitation->contact->restore();
auth()->guard('contact')->loginUsingId($invitation->contact->id, true);
$invoice = $invitation->invoice;

View File

@ -22,6 +22,7 @@ use Google_Client;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
use Microsoft\Graph\Model;
class ConnectedAccountController extends BaseController
{
@ -81,12 +82,61 @@ class ConnectedAccountController extends BaseController
return $this->handleGoogleOauth();
}
if ($request->input('provider') == 'microsoft') {
return $this->handleMicrosoftOauth($request);
}
return response()
->json(['message' => 'Provider not supported'], 400)
->header('X-App-Version', config('ninja.app_version'))
->header('X-Api-Version', config('ninja.minimum_client_version'));
}
private function handleMicrosoftOauth($request)
{
nlog($request->all());
if(!$request->has('access_token'))
return response()->json(['message' => 'No access_token parameter found!'], 400);
$graph = new \Microsoft\Graph\Graph();
$graph->setAccessToken($request->input('access_token'));
$user = $graph->createRequest("GET", "/me")
->setReturnType(Model\User::class)
->execute();
if($user){
$email = $user->getMail() ?: $user->getUserPrincipalName();
if(auth()->user()->email != $email && MultiDB::checkUserEmailExists($email))
return response()->json(['message' => ctrans('texts.email_already_register')], 400);
$connected_account = [
'email' => $email,
'oauth_user_id' => $user->getId(),
'oauth_provider_id' => 'microsoft',
'email_verified_at' =>now()
];
auth()->user()->update($connected_account);
auth()->user()->email_verified_at = now();
auth()->user()->save();
$this->setLoginCache(auth()->user());
return $this->itemResponse(auth()->user());
}
return response()
->json(['message' => ctrans('texts.invalid_credentials')], 401)
->header('X-App-Version', config('ninja.app_version'))
->header('X-Api-Version', config('ninja.minimum_client_version'));
}
private function handleGoogleOauth()
{
$user = false;

View File

@ -633,11 +633,23 @@ class PurchaseOrderController extends BaseController
//check query parameter for email_type and set the template else use calculateTemplate
PurchaseOrderEmail::dispatch($purchase_order, $purchase_order->company);
if (! $bulk) {
return response()->json(['message' => 'email sent'], 200);
}
case 'cancel':
if($purchase_order->status_id <= PurchaseOrder::STATUS_SENT)
{
$purchase_order->status_id = PurchaseOrder::STATUS_CANCELLED;
$purchase_order->save();
}
if (! $bulk) {
return $this->listResponse($purchase_order);
}
break;
default:
return response()->json(['message' => ctrans('texts.action_unavailable', ['action' => $action])], 400);
break;

View File

@ -158,7 +158,7 @@ class UserController extends BaseController
*/
public function create(CreateUserRequest $request)
{
$user = UserFactory::create(auth()->user()->account->id);
$user = UserFactory::create(auth()->user()->account_id);
return $this->itemResponse($user);
}

View File

@ -63,35 +63,57 @@ class PasswordProtection
//user is attempting to reauth with OAuth - check the token value
//todo expand this to include all OAuth providers
$user = false;
$google = new Google();
$user = $google->getTokenResponse(request()->header('X-API-OAUTH-PASSWORD'));
if (is_array($user)) {
$query = [
'oauth_user_id' => $google->harvestSubField($user),
'oauth_provider_id'=> 'google'
];
if(auth()->user()->oauth_provider_id == 'google')
{
$user = false;
$google = new Google();
$user = $google->getTokenResponse(request()->header('X-API-OAUTH-PASSWORD'));
//If OAuth and user also has a password set - check both
if ($existing_user = MultiDB::hasUser($query) && auth()->user()->company()->oauth_password_required && auth()->user()->has_password && Hash::check(auth()->user()->password, $x_api_password)) {
if (is_array($user)) {
$query = [
'oauth_user_id' => $google->harvestSubField($user),
'oauth_provider_id'=> 'google'
];
nlog("existing user with password");
//If OAuth and user also has a password set - check both
if ($existing_user = MultiDB::hasUser($query) && auth()->user()->company()->oauth_password_required && auth()->user()->has_password && Hash::check(auth()->user()->password, $x_api_password)) {
nlog("existing user with password");
Cache::put(auth()->user()->hashed_id.'_'.auth()->user()->account_id.'_logged_in', Str::random(64), $timeout);
return $next($request);
}
elseif($existing_user = MultiDB::hasUser($query) && !auth()->user()->company()->oauth_password_required){
nlog("existing user without password");
Cache::put(auth()->user()->hashed_id.'_'.auth()->user()->account_id.'_logged_in', Str::random(64), $timeout);
return $next($request);
}
}
}
elseif(auth()->user()->oauth_provider_id == 'microsoft')
{
try{
$payload = json_decode(base64_decode(str_replace('_', '/', str_replace('-','+',explode('.', request()->header('X-API-OAUTH-PASSWORD'))[1]))));
}
catch(\Exception $e){
nlog("could not decode microsoft response");
return response()->json(['message' => 'Could not decode the response from Microsoft'], 412);
}
if($payload->preferred_username == auth()->user()->email){
Cache::put(auth()->user()->hashed_id.'_'.auth()->user()->account_id.'_logged_in', Str::random(64), $timeout);
return $next($request);
}
elseif($existing_user = MultiDB::hasUser($query) && !auth()->user()->company()->oauth_password_required){
nlog("existing user without password");
Cache::put(auth()->user()->hashed_id.'_'.auth()->user()->account_id.'_logged_in', Str::random(64), $timeout);
return $next($request);
}
}
return response()->json($error, 412);

View File

@ -200,6 +200,14 @@ class NinjaMailerJob implements ShouldQueue
$user = User::find($this->decodePrimaryKey($sending_user));
/* Always ensure the user is set on the correct account */
if($user->account_id != $this->company->account_id){
$this->nmo->settings->email_sending_method = 'default';
return $this->setMailDriver();
}
nlog("Sending via {$user->name()}");
$token = $this->refreshOfficeToken($user);
@ -236,6 +244,14 @@ class NinjaMailerJob implements ShouldQueue
$user = User::find($this->decodePrimaryKey($sending_user));
/* Always ensure the user is set on the correct account */
if($user->account_id != $this->company->account_id){
$this->nmo->settings->email_sending_method = 'default';
return $this->setMailDriver();
}
nlog("Sending via {$user->name()}");
$google = (new Google())->init();

View File

@ -255,6 +255,7 @@ class InstantPayment
'tokens' => $tokens,
'payment_method_id' => $payment_method_id,
'amount_with_fee' => $invoice_totals + $fee_totals,
'client' => $client,
];
if ($is_credit_payment || $totals <= 0) {

View File

@ -51,7 +51,6 @@ class PurchaseOrderService
// //TODO implement design, footer, terms
// /* If client currency differs from the company default currency, then insert the client exchange rate on the model.*/
// if (!isset($this->purchase_order->exchange_rate) && $this->purchase_order->client->currency()->id != (int)$this->purchase_order->company->settings->currency_id)
// $this->purchase_order->exchange_rate = $this->purchase_order->client->currency()->exchange_rate;
@ -89,7 +88,6 @@ class PurchaseOrderService
return $this;
}
public function touchPdf($force = false)
{
try {

View File

@ -8,7 +8,7 @@ const RESOURCES = {
"canvaskit/profiling/canvaskit.js": "ae2949af4efc61d28a4a80fffa1db900",
"canvaskit/profiling/canvaskit.wasm": "95e736ab31147d1b2c7b25f11d4c32cd",
"canvaskit/canvaskit.wasm": "4b83d89d9fecbea8ca46f2f760c5a9ba",
"/": "17a515c261fe3010e0533ce4573dca71",
"/": "a74757af1ea3d863d3b901f549f66929",
"flutter.js": "0816e65a103ba8ba51b174eeeeb2cb67",
"icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35",
"icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed",
@ -39,7 +39,7 @@ const RESOURCES = {
"assets/assets/images/payment_types/other.png": "d936e11fa3884b8c9f1bd5c914be8629",
"assets/packages/material_design_icons_flutter/lib/fonts/materialdesignicons-webfont.ttf": "b62641afc9ab487008e996a5c5865e56",
"assets/NOTICES": "9b6b63256d3a6491659b71127ee9f3b6",
"main.dart.js": "c2902a32d34abff107d9e1e71c2858b2"
"main.dart.js": "943526b26dd93b9a38f54ae32cdf6795"
};
// The application shell files that are downloaded before a service worker can

135202
public/main.dart.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

131898
public/main.foss.dart.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -212,6 +212,7 @@ Route::group(['middleware' => ['throttle:100,1', 'api_db', 'token_auth', 'locale
Route::get('purchase_orders/{purchase_order}/{action}', 'PurchaseOrderController@action')->name('purchase_orders.action');
Route::get('users', 'UserController@index');
Route::get('users/create', 'UserController@create')->middleware('password_protected');
Route::get('users/{user}', 'UserController@show')->middleware('password_protected');
Route::put('users/{user}', 'UserController@update')->middleware('password_protected');
Route::post('users', 'UserController@store')->middleware('password_protected');