mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 02:24:29 -04:00
Merge branch 'v5-develop' of https://github.com/turbo124/invoiceninja into v5-develop
This commit is contained in:
commit
7129cd1e6f
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
4
public/flutter_service_worker.js
vendored
4
public/flutter_service_worker.js
vendored
@ -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
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
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
4558
public/main.profile.dart.js
vendored
4558
public/main.profile.dart.js
vendored
File diff suppressed because one or more lines are too long
@ -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');
|
||||
|
Loading…
x
Reference in New Issue
Block a user