1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-09 20:52:56 +01:00

Added support for Zapier

This commit is contained in:
Hillel Coren 2014-07-27 23:31:41 +03:00
parent f5f87319b2
commit 9feb616f1b
23 changed files with 913 additions and 303 deletions

View File

@ -20,6 +20,7 @@ Site design by [kantorp-wegl.in](http://kantorp-wegl.in/)
* Integrates with many payment providers
* Recurring invoices
* Tax rates and payment terms
* Multi-user support
### Steps to setup

View File

@ -379,6 +379,7 @@ class AccountController extends \BaseController {
$client = Client::createNew();
$contact = Contact::createNew();
$contact->is_primary = true;
$contact->send_invoice = true;
$count++;
foreach ($row as $index => $value)
@ -443,7 +444,7 @@ class AccountController extends \BaseController {
$client->save();
$client->contacts()->save($contact);
Activity::createClient($client);
Activity::createClient($client, false);
}
$message = Utils::pluralize('created_client', $count);
@ -470,7 +471,7 @@ class AccountController extends \BaseController {
if (count($csv->data) + Client::scope()->count() > Auth::user()->getMaxNumClients())
{
$message = Utils::pluralize('limit_clients', Auth::user()->getMaxNumClients());
$message = trans('texts.limit_clients', ['count' => Auth::user()->getMaxNumClients()]);
Session::flash('error', $message);
return Redirect::to('company/import_export');
}

View File

@ -17,6 +17,6 @@ class BaseController extends Controller {
public function __construct()
{
$this->beforeFilter('csrf', array('on' => array('post', 'delete', 'put')));
$this->beforeFilter('csrf', array('on' => array('post', 'delete', 'put')));
}
}

View File

@ -3,58 +3,46 @@
use ninja\repositories\ClientRepository;
use Client;
class ClientApiController extends \BaseController {
class ClientApiController extends Controller {
protected $clientRepo;
public function __construct(ClientRepository $clientRepo)
{
parent::__construct();
$this->clientRepo = $clientRepo;
}
public function ping()
{
$headers = Utils::getApiHeaders();
return Response::make('', 200, $headers);
}
public function index()
{
$clients = Client::scope()->get();
/*
$response = [
'status' => 200,
'error' => false,
'clients' => $clients->toArray()
];
*/
if (!Utils::isPro()) {
Redirect::to('/');
}
$response = json_encode($clients->toArray(), JSON_PRETTY_PRINT);
$headers = [
'Content-Type' => 'application/json',
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => 'GET',
//'Access-Control-Allow-Headers' => 'Origin, Content-Type, Accept, Authorization, X-Requested-With',
//'Access-Control-Allow-Credentials' => 'true',
//'X-Total-Count' => 0
//'X-Rate-Limit-Limit' - The number of allowed requests in the current period
//'X-Rate-Limit-Remaining' - The number of remaining requests in the current period
//'X-Rate-Limit-Reset' - The number of seconds left in the current period,
];
$clients = Client::scope()->with('contacts')->orderBy('created_at', 'desc')->get();
$clients = Utils::remapPublicIds($clients->toArray());
/*
200 OK - Response to a successful GET, PUT, PATCH or DELETE. Can also be used for a POST that doesn't result in a creation.
201 Created - Response to a POST that results in a creation. Should be combined with a Location header pointing to the location of the new resource
204 No Content - Response to a successful request that won't be returning a body (like a DELETE request)
304 Not Modified - Used when HTTP caching headers are in play
400 Bad Request - The request is malformed, such as if the body does not parse
401 Unauthorized - When no or invalid authentication details are provided. Also useful to trigger an auth popup if the API is used from a browser
403 Forbidden - When authentication succeeded but authenticated user doesn't have access to the resource
404 Not Found - When a non-existent resource is requested
405 Method Not Allowed - When an HTTP method is being requested that isn't allowed for the authenticated user
410 Gone - Indicates that the resource at this end point is no longer available. Useful as a blanket response for old API versions
415 Unsupported Media Type - If incorrect content type was provided as part of the request
422 Unprocessable Entity - Used for validation errors
429 Too Many Requests - When a request is rejected due to rate limiting
*/
$response = json_encode($clients, JSON_PRETTY_PRINT);
$headers = Utils::getApiHeaders(count($clients));
return Response::make($response, 200, $headers);
}
public function store()
{
if (!Utils::isPro()) {
Redirect::to('/');
}
$data = Input::all();
$client = $this->clientRepo->save(false, $data, false);
$response = json_encode($client, JSON_PRETTY_PRINT);
$headers = Utils::getApiHeaders();
return Response::make($response, 200, $headers);
}
}

View File

@ -0,0 +1,29 @@
<?php
class IntegrationController extends Controller {
public function subscribe()
{
$eventId = Utils::lookupEventId(trim(Input::get('event')));
if (!$eventId)
{
return Response::json('', 500);
}
$subscription = Subscription::where('account_id', '=', Auth::user()->account_id)->where('event_id', '=', $eventId)->first();
if (!$subscription)
{
$subscription = new Subscription;
$subscription->account_id = Auth::user()->account_id;
$subscription->event_id = $eventId;
}
$subscription->target_url = trim(Input::get('target_url'));
$subscription->save();
return Response::json('{"id":'.$subscription->id.'}', 201);
}
}

View File

@ -0,0 +1,40 @@
<?php
use ninja\repositories\InvoiceRepository;
use Invoice;
class InvoiceApiController extends Controller {
protected $invoiceRepo;
public function __construct(InvoiceRepository $invoiceRepo)
{
$this->invoiceRepo = $invoiceRepo;
}
public function index()
{
if (!Utils::isPro()) {
Redirect::to('/');
}
$invoices = Invoice::scope()->where('invoices.is_quote', '=', false)->orderBy('created_at', 'desc')->get();
$invoices = Utils::remapPublicIds($invoices->toArray());
$response = json_encode($invoices, JSON_PRETTY_PRINT);
$headers = Utils::getApiHeaders(count($invoices));
return Response::make($response, 200, $headers);
}
/*
public function store()
{
$data = Input::all();
$invoice = $this->invoiceRepo->save(false, $data, false);
$response = json_encode($invoice, JSON_PRETTY_PRINT);
$headers = Utils::getApiHeaders();
return Response::make($response, 200, $headers);
}
*/
}

View File

@ -0,0 +1,40 @@
<?php
use ninja\repositories\PaymentRepository;
use Payment;
class PaymentApiController extends Controller {
protected $paymentRepo;
public function __construct(PaymentRepository $paymentRepo)
{
$this->paymentRepo = $paymentRepo;
}
public function index()
{
if (!Utils::isPro()) {
Redirect::to('/');
}
$payments = Payment::scope()->orderBy('created_at', 'desc')->get();
$payments = Utils::remapPublicIds($payments->toArray());
$response = json_encode($payments, JSON_PRETTY_PRINT);
$headers = Utils::getApiHeaders(count($payments));
return Response::make($response, 200, $headers);
}
/*
public function store()
{
$data = Input::all();
$invoice = $this->invoiceRepo->save(false, $data, false);
$response = json_encode($invoice, JSON_PRETTY_PRINT);
$headers = Utils::getApiHeaders();
return Response::make($response, 200, $headers);
}
*/
}

View File

@ -0,0 +1,40 @@
<?php
use ninja\repositories\InvoiceRepository;
use Invoice;
class QuoteApiController extends Controller {
protected $invoiceRepo;
public function __construct(InvoiceRepository $invoiceRepo)
{
$this->invoiceRepo = $invoiceRepo;
}
public function index()
{
if (!Utils::isPro()) {
Redirect::to('/');
}
$invoices = Invoice::scope()->where('invoices.is_quote', '=', true)->orderBy('created_at', 'desc')->get();
$invoices = Utils::remapPublicIds($invoices->toArray());
$response = json_encode($invoices, JSON_PRETTY_PRINT);
$headers = Utils::getApiHeaders(count($invoices));
return Response::make($response, 200, $headers);
}
/*
public function store()
{
$data = Input::all();
$invoice = $this->invoiceRepo->save(false, $data, false);
$response = json_encode($invoice, JSON_PRETTY_PRINT);
$headers = Utils::getApiHeaders();
return Response::make($response, 200, $headers);
}
*/
}

View File

@ -0,0 +1,42 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddZapierSupport extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('subscriptions', function($table)
{
$table->increments('id');
$table->unsignedInteger('account_id')->nullable();
$table->timestamps();
$table->softDeletes();
$table->unsignedInteger('event_id')->nullable();
$table->string('target_url');
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$table->unique( ['account_id', 'event_id'] );
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('subscriptions');
}
}

View File

@ -119,11 +119,11 @@ Route::filter('csrf', function()
{
$token = Request::ajax() ? Request::header('X-CSRF-Token') : Input::get('_token');
if (Session::token() != $token)
{
Session::flash('warning', trans('texts.session_expired'));
if (Session::token() != $token)
{
Session::flash('warning', trans('texts.session_expired'));
return Redirect::to('/');
//throw new Illuminate\Session\TokenMismatchException;
}
return Redirect::to('/');
//throw new Illuminate\Session\TokenMismatchException;
}
});

View File

@ -463,4 +463,76 @@ class Utils
}
return join('-', $parts);
}
public static function lookupEventId($eventName)
{
if ($eventName == 'create_client') {
return EVENT_CREATE_CLIENT;
} else if ($eventName == 'create_invoice') {
return EVENT_CREATE_INVOICE;
} else if ($eventName == 'create_quote') {
return EVENT_CREATE_QUOTE;
} else if ($eventName == 'create_payment') {
return EVENT_CREATE_PAYMENT;
} else {
return false;
}
}
public static function notifyZapier($subscription, $data) {
$curl = curl_init();
$jsonEncodedData = json_encode($data->toJson());
$opts = [
CURLOPT_URL => $subscription->target_url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $jsonEncodedData,
CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'Content-Length: ' . strlen($jsonEncodedData)]
];
curl_setopt_array($curl, $opts);
$result = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($status == 410)
{
$subscription->delete();
}
}
public static function remapPublicIds($data) {
foreach ($data as $index => $record) {
if (!isset($data[$index]['public_id'])) {
continue;
}
$data[$index]['id'] = $data[$index]['public_id'];
unset($data[$index]['public_id']);
foreach ($record as $key => $val) {
if (is_array($val)) {
$data[$index][$key] = Utils::remapPublicIds($val);
}
}
}
return $data;
}
public static function getApiHeaders($count = 0) {
return [
'Content-Type' => 'application/json',
//'Access-Control-Allow-Origin' => '*',
//'Access-Control-Allow-Methods' => 'GET',
//'Access-Control-Allow-Headers' => 'Origin, Content-Type, Accept, Authorization, X-Requested-With',
//'Access-Control-Allow-Credentials' => 'true',
'X-Total-Count' => $count,
//'X-Rate-Limit-Limit' - The number of allowed requests in the current period
//'X-Rate-Limit-Remaining' - The number of remaining requests in the current period
//'X-Rate-Limit-Reset' - The number of seconds left in the current period,
];
}
}

View File

@ -248,4 +248,8 @@ class Account extends Eloquent
return $interval->y == 0;
}
public function getSubscription($eventId)
{
return Subscription::where('account_id', '=', $this->id)->where('event_id', '=', $eventId)->first();
}
}

View File

@ -67,13 +67,18 @@ class Activity extends Eloquent
return $activity;
}
public static function createClient($client)
public static function createClient($client, $notify = true)
{
$activity = Activity::getBlank();
$activity->client_id = $client->id;
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_CLIENT;
$activity->message = Utils::encodeActivity(Auth::user(), 'created', $client);
$activity->save();
if ($notify)
{
Activity::checkSubscriptions(EVENT_CREATE_CLIENT, $client);
}
}
public static function updateClient($client)
@ -129,6 +134,8 @@ class Activity extends Eloquent
$activity->balance = $client->balance;
$activity->adjustment = $adjustment;
$activity->save();
Activity::checkSubscriptions($invoice->is_quote ? EVENT_CREATE_QUOTE : EVENT_CREATE_INVOICE, $invoice);
}
public static function archiveInvoice($invoice)
@ -290,6 +297,8 @@ class Activity extends Eloquent
$activity->balance = $client->balance;
$activity->adjustment = $payment->amount * -1;
$activity->save();
Activity::checkSubscriptions(EVENT_CREATE_PAYMENT, $payment);
}
public static function updatePayment($payment)
@ -429,4 +438,14 @@ class Activity extends Eloquent
$activity->balance = $credit->client->balance;
$activity->save();
}
private static function checkSubscriptions($event, $data)
{
$subscription = Auth::user()->account->getSubscription($event);
if ($subscription)
{
Utils::notifyZapier($subscription, $data);
}
}
}

View File

@ -0,0 +1,7 @@
<?php
class Subscription extends Eloquent
{
public $timestamps = true;
protected $softDelete = true;
}

View File

@ -51,7 +51,7 @@ class User extends ConfideUser implements UserInterface, RemindableInterface
* @return mixed
*/
public function getAuthIdentifier()
{
{
return $this->getKey();
}
@ -173,5 +173,5 @@ class User extends ConfideUser implements UserInterface, RemindableInterface
public function getRememberTokenName()
{
return 'remember_token';
}
}
}

View File

@ -32,13 +32,22 @@ class ClientRepository
return $query;
}
public function save($publicId, $data)
{
if ($publicId == "-1")
public function save($publicId, $data, $notify = true)
{
$contact = isset($data['contacts']) ? (array)$data['contacts'][0] : (isset($data['contact']) ? $data['contact'] : []);
$validator = \Validator::make($contact, ['email' => 'required|email']);
if ($validator->fails()) {
dd($validator->messages());
return false;
}
if (!$publicId || $publicId == "-1")
{
$client = Client::createNew();
$client->currency_id = 1;
$contact = Contact::createNew();
$contact->is_primary = true;
$contact->send_invoice = true;
}
else
{
@ -46,66 +55,128 @@ class ClientRepository
$contact = $client->contacts()->where('is_primary', '=', true)->firstOrFail();
}
if (isset($data['name'])) {
$client->name = trim($data['name']);
}
if (isset($data['work_phone'])) {
$client->work_phone = trim($data['work_phone']);
}
if (isset($data['custom_value1'])) {
$client->custom_value1 = trim($data['custom_value1']);
}
if (isset($data['custom_value2'])) {
$client->custom_value2 = trim($data['custom_value2']);
}
if (isset($data['address1'])) {
$client->address1 = trim($data['address1']);
}
if (isset($data['address2'])) {
$client->address2 = trim($data['address2']);
}
if (isset($data['city'])) {
$client->city = trim($data['city']);
}
if (isset($data['state'])) {
$client->state = trim($data['state']);
}
if (isset($data['postal_code'])) {
$client->postal_code = trim($data['postal_code']);
}
if (isset($data['country_id'])) {
$client->country_id = $data['country_id'] ? $data['country_id'] : null;
}
if (isset($data['private_notes'])) {
$client->private_notes = trim($data['private_notes']);
}
if (isset($data['size_id'])) {
$client->size_id = $data['size_id'] ? $data['size_id'] : null;
}
if (isset($data['industry_id'])) {
$client->industry_id = $data['industry_id'] ? $data['industry_id'] : null;
}
if (isset($data['currency_id'])) {
$client->currency_id = $data['currency_id'] ? $data['currency_id'] : 1;
}
if (isset($data['payment_terms'])) {
$client->payment_terms = $data['payment_terms'];
}
if (isset($data['website'])) {
$client->website = trim($data['website']);
}
$client->name = trim($data['name']);
$client->work_phone = trim($data['work_phone']);
$client->custom_value1 = trim($data['custom_value1']);
$client->custom_value2 = trim($data['custom_value2']);
$client->address1 = trim($data['address1']);
$client->address2 = trim($data['address2']);
$client->city = trim($data['city']);
$client->state = trim($data['state']);
$client->postal_code = trim($data['postal_code']);
$client->country_id = $data['country_id'] ? $data['country_id'] : null;
$client->private_notes = trim($data['private_notes']);
$client->size_id = $data['size_id'] ? $data['size_id'] : null;
$client->industry_id = $data['industry_id'] ? $data['industry_id'] : null;
$client->currency_id = $data['currency_id'] ? $data['currency_id'] : 1;
$client->payment_terms = $data['payment_terms'];
$client->website = trim($data['website']);
$client->save();
$isPrimary = true;
$contactIds = [];
foreach ($data['contacts'] as $record)
if (isset($data['contact']))
{
$record = (array) $record;
if ($publicId != "-1" && isset($record['public_id']) && $record['public_id'])
{
$contact = Contact::scope($record['public_id'])->firstOrFail();
$info = $data['contact'];
if (isset($info['email'])) {
$contact->email = trim(strtolower($info['email']));
}
else
{
$contact = Contact::createNew();
if (isset($info['first_name'])) {
$contact->first_name = trim($info['first_name']);
}
$contact->email = trim(strtolower($record['email']));
$contact->first_name = trim($record['first_name']);
$contact->last_name = trim($record['last_name']);
$contact->phone = trim($record['phone']);
$contact->is_primary = $isPrimary;
$contact->send_invoice = $record['send_invoice'];
$isPrimary = false;
if (isset($info['last_name'])) {
$contact->last_name = trim($info['last_name']);
}
if (isset($info['phone'])) {
$contact->phone = trim($info['phone']);
}
$contact->is_primary = true;
$contact->send_invoice = true;
$client->contacts()->save($contact);
$contactIds[] = $contact->public_id;
}
foreach ($client->contacts as $contact)
else
{
if (!in_array($contact->public_id, $contactIds))
{
$contact->delete();
foreach ($data['contacts'] as $record)
{
$record = (array) $record;
if ($publicId != "-1" && isset($record['public_id']) && $record['public_id'])
{
$contact = Contact::scope($record['public_id'])->firstOrFail();
}
else
{
$contact = Contact::createNew();
}
if (isset($record['email'])) {
$contact->email = trim(strtolower($record['email']));
}
if (isset($record['first_name'])) {
$contact->first_name = trim($record['first_name']);
}
if (isset($record['last_name'])) {
$contact->last_name = trim($record['last_name']);
}
if (isset($record['phone'])) {
$contact->phone = trim($record['phone']);
}
$contact->is_primary = $isPrimary;
$contact->send_invoice = isset($record['send_invoice']) ? $record['send_invoice'] : true;
$isPrimary = false;
$client->contacts()->save($contact);
$contactIds[] = $contact->public_id;
}
foreach ($client->contacts as $contact)
{
if (!in_array($contact->public_id, $contactIds))
{
$contact->delete();
}
}
}
$client->save();
if ($publicId == "-1")
if (!$publicId || $publicId == "-1")
{
\Activity::createClient($client);
\Activity::createClient($client, $notify);
}
return $client;

View File

@ -154,30 +154,30 @@ class InvoiceRepository
{
$contact = (array) $input->client->contacts[0];
$rules = ['email' => 'required|email'];
$validator = \Validator::make($contact, $rules);
$validator = \Validator::make($contact, $rules);
if ($validator->fails())
{
return $validator;
}
if ($validator->fails())
{
return $validator;
}
$invoice = (array) $input;
$invoiceId = isset($invoice['public_id']) && $invoice['public_id'] ? Invoice::getPrivateId($invoice['public_id']) : null;
$rules = ['invoice_number' => 'required|unique:invoices,invoice_number,' . $invoiceId . ',id,account_id,' . \Auth::user()->account_id];
$invoice = (array) $input;
$invoiceId = isset($invoice['public_id']) && $invoice['public_id'] ? Invoice::getPrivateId($invoice['public_id']) : null;
$rules = ['invoice_number' => 'required|unique:invoices,invoice_number,' . $invoiceId . ',id,account_id,' . \Auth::user()->account_id];
if ($invoice['is_recurring'] && $invoice['start_date'] && $invoice['end_date'])
{
$rules['end_date'] = 'after:' . $invoice['start_date'];
}
if ($invoice['is_recurring'] && $invoice['start_date'] && $invoice['end_date'])
{
$rules['end_date'] = 'after:' . $invoice['start_date'];
}
$validator = \Validator::make($invoice, $rules);
$validator = \Validator::make($invoice, $rules);
if ($validator->fails())
{
return $validator;
}
if ($validator->fails())
{
return $validator;
}
return false;
return false;
}
public function save($publicId, $data, $entityType)

View File

@ -1,5 +1,6 @@
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
@ -22,6 +23,7 @@
//dd(gethostname());
//Log::error('test');
Route::get('/', 'HomeController@showIndex');
Route::get('/rocksteady', 'HomeController@showIndex');
Route::get('/about', 'HomeController@showAboutUs');
@ -123,12 +125,20 @@ Route::group(array('before' => 'auth'), function()
Route::post('credits/bulk', 'CreditController@bulk');
});
// Route group for API versioning
// Route group for API
Route::group(array('prefix' => 'api/v1', 'before' => 'auth.basic'), function()
{
Route::resource('clients', 'ClientApiController');
Route::resource('ping', 'ClientApiController@ping');
Route::resource('clients', 'ClientApiController');
Route::resource('invoices', 'InvoiceApiController');
Route::resource('quotes', 'QuoteApiController');
Route::resource('payments', 'PaymentApiController');
});
Route::group(array('before' => 'auth.basic'), function()
{
Route::post('api/hooks', 'IntegrationController@subscribe');
});
define('CONTACT_EMAIL', 'contact@invoiceninja.com');
define('CONTACT_NAME', 'Invoice Ninja');
@ -215,12 +225,17 @@ define('GATEWAY_PAYPAL_EXPRESS', 17);
define('GATEWAY_BEANSTREAM', 29);
define('GATEWAY_PSIGATE', 30);
define('EVENT_CREATE_CLIENT', 1);
define('EVENT_CREATE_INVOICE', 2);
define('EVENT_CREATE_QUOTE', 3);
define('EVENT_CREATE_PAYMENT', 4);
define('REQUESTED_PRO_PLAN', 'REQUESTED_PRO_PLAN');
define('NINJA_ACCOUNT_KEY', 'zg4ylmzDkdkPOT8yoKQw9LTWaoZJx79h');
define('NINJA_GATEWAY_ID', GATEWAY_AUTHORIZE_NET);
define('NINJA_GATEWAY_CONFIG', '{"apiLoginId":"626vWcD5","transactionKey":"4bn26TgL9r4Br4qJ","testMode":"","developerMode":""}');
define('NINJA_URL', 'https://www.invoiceninja.com');
define('NINJA_VERSION', '1.3.0');
define('NINJA_VERSION', '1.3.1');
define('PRO_PLAN_PRICE', 50);
define('LICENSE_PRICE', 30);
@ -380,3 +395,5 @@ if (Auth::check() && Auth::user()->id === 1)
}
*/

View File

@ -63,6 +63,10 @@ App::error(function(Exception $exception, $code)
Utils::logError($exception . ' ' . $code);
return Response::view('error', ['hideHeader' => true, 'error' => "A {$code} error occurred."], $code);
}
else if (Utils::isNinjaDev())
{
return "{$exception->getFile()}:{$exception->getLine()} => {$exception->getMessage()}";
}
else
{
return null;

View File

@ -57,7 +57,7 @@
'password_confirmation' => 'required',
)); }}
<h2 class="form-signin-heading">Set Passord</h2><p/>&nbsp;
<h2 class="form-signin-heading">Set Password</h2><p/>&nbsp;
<input type="hidden" name="token" value="{{{ $token }}}">
<p>

View File

@ -32,6 +32,14 @@ if (!function_exists('gethostname')) {
}
}
// Fortrabbit HTTP AUTH CODE
if (!empty($_SERVER['REMOTE_USER'])) {
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(
':',
base64_decode(substr($_SERVER['REMOTE_USER'], 6))
);
}
/*
|--------------------------------------------------------------------------

594
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -5,4 +5,7 @@
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization}]
</IfModule>