Implement CompanyToken and Subscriptions CRUD (#3609)

* Working on Tokens CRUD

* Fixes for company filters

* Working on Token CRUD

* Tests for tokens

* Fixes for OPENApi

* Subscriptions

* Subscriptions
This commit is contained in:
David Bomba 2020-04-09 20:48:04 +10:00 committed by GitHub
parent 8f4fa5e80d
commit 05443d69ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 2592 additions and 94 deletions

View File

@ -0,0 +1,42 @@
<?php
namespace App\Events\CompanyToken;
use App\Models\CompanyToken;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class CompanyTokenWasDeleted
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* @var Company
*/
public $company_token;
/**
* Create a new event instance.
*
* @param Company $company
*/
public function __construct(CompanyToken $company_token)
{
$this->company_token = $company_token;
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('channel-name');
}
}

View File

@ -0,0 +1,31 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Factory;
use App\Models\CompanyToken;
use Illuminate\Support\Str;
class CompanyTokenFactory
{
public static function create(int $company_id, int $user_id, int $account_id) :CompanyToken
{
$token = new CompanyToken;
$token->user_id = $user_id;
$token->account_id = $account_id;
$token->token = Str::random(64);
$token->name = '';
$token->company_id = $company_id;
return $token;
}
}

View File

@ -0,0 +1,29 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Factory;
use App\Models\Subscription;
class SubscriptionFactory
{
public static function create(int $company_id, int $user_id) :Subscription
{
$subscription = new Subscription;
$subscription->company_id = $company_id;
$subscription->user_id = $user_id;
$subscription->target_url = '';
$subscription->event_id = 1;
$subscription->format = 'JSON';
return $subscription;
}
}

View File

@ -0,0 +1,143 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Filters;
use App\Models\Subscription;
use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Gate;
/**
* TokenFilters
*/
class SubscriptionFilters extends QueryFilters
{
/**
* Filter based on search text
*
* @param string query filter
* @return Illuminate\Database\Query\Builder
* @deprecated
*
*/
public function filter(string $filter = '') : Builder
{
if (strlen($filter) == 0) {
return $this->builder;
}
return $this->builder->where(function ($query) use ($filter) {
$query->where('subscriptions.target_url', 'like', '%'.$filter.'%');
});
}
/**
* Filters the list based on the status
* archived, active, deleted
*
* @param string filter
* @return Illuminate\Database\Query\Builder
*/
public function status(string $filter = '') : Builder
{
if (strlen($filter) == 0) {
return $this->builder;
}
$table = 'subscriptions';
$filters = explode(',', $filter);
return $this->builder->where(function ($query) use ($filters, $table) {
$query->whereNull($table . '.id');
if (in_array(parent::STATUS_ACTIVE, $filters)) {
$query->orWhereNull($table . '.deleted_at');
}
if (in_array(parent::STATUS_ARCHIVED, $filters)) {
$query->orWhere(function ($query) use ($table) {
$query->whereNotNull($table . '.deleted_at');
if (! in_array($table, ['users'])) {
$query->where($table . '.is_deleted', '=', 0);
}
});
}
if (in_array(parent::STATUS_DELETED, $filters)) {
$query->orWhere($table . '.is_deleted', '=', 1);
}
});
}
/**
* Sorts the list based on $sort
*
* @param string sort formatted as column|asc
* @return Illuminate\Database\Query\Builder
*/
public function sort(string $sort) : Builder
{
$sort_col = explode("|", $sort);
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
}
/**
* Returns the base query
*
* @param int company_id
* @return Illuminate\Database\Query\Builder
* @deprecated
*/
public function baseQuery(int $company_id, User $user) : Builder
{
$query = DB::table('subscriptions')
->join('companies', 'companies.id', '=', 'subscriptions.company_id')
->where('subscriptions.company_id', '=', $company_id)
//->whereRaw('(designs.name != "" or contacts.first_name != "" or contacts.last_name != "" or contacts.email != "")') // filter out buy now invoices
->select(
'subscriptions.id',
'subscriptions.target_url',
'subscriptions.event_id',
'subscriptions.created_at',
'subscriptions.created_at as token_created_at',
'subscriptions.deleted_at',
'subscriptions.format',
'subscriptions.user_id',
);
/**
* If the user does not have permissions to view all invoices
* limit the user to only the invoices they have created
*/
if (Gate::denies('view-list', Subscription::class)) {
$query->where('subscriptions.user_id', '=', $user->id);
}
return $query;
}
/**
* Filters the query by the users company ID
*
* @param $company_id The company Id
* @return Illuminate\Database\Query\Builder
*/
public function entityFilter()
{
return $this->builder->company();
}
}

View File

@ -0,0 +1,143 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Filters;
use App\Models\Vendor;
use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Gate;
/**
* TokenFilters
*/
class TokenFilters extends QueryFilters
{
/**
* Filter based on search text
*
* @param string query filter
* @return Illuminate\Database\Query\Builder
* @deprecated
*
*/
public function filter(string $filter = '') : Builder
{
if (strlen($filter) == 0) {
return $this->builder;
}
return $this->builder->where(function ($query) use ($filter) {
$query->where('company_tokens.name', 'like', '%'.$filter.'%');
});
}
/**
* Filters the list based on the status
* archived, active, deleted
*
* @param string filter
* @return Illuminate\Database\Query\Builder
*/
public function status(string $filter = '') : Builder
{
if (strlen($filter) == 0) {
return $this->builder;
}
$table = 'company_tokens';
$filters = explode(',', $filter);
return $this->builder->where(function ($query) use ($filters, $table) {
$query->whereNull($table . '.id');
if (in_array(parent::STATUS_ACTIVE, $filters)) {
$query->orWhereNull($table . '.deleted_at');
}
if (in_array(parent::STATUS_ARCHIVED, $filters)) {
$query->orWhere(function ($query) use ($table) {
$query->whereNotNull($table . '.deleted_at');
if (! in_array($table, ['users'])) {
$query->where($table . '.is_deleted', '=', 0);
}
});
}
if (in_array(parent::STATUS_DELETED, $filters)) {
$query->orWhere($table . '.is_deleted', '=', 1);
}
});
}
/**
* Sorts the list based on $sort
*
* @param string sort formatted as column|asc
* @return Illuminate\Database\Query\Builder
*/
public function sort(string $sort) : Builder
{
$sort_col = explode("|", $sort);
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
}
/**
* Returns the base query
*
* @param int company_id
* @return Illuminate\Database\Query\Builder
* @deprecated
*/
public function baseQuery(int $company_id, User $user) : Builder
{
$query = DB::table('company_tokens')
->join('companies', 'companies.id', '=', 'company_tokens.company_id')
->where('company_tokens.company_id', '=', $company_id)
//->whereRaw('(designs.name != "" or contacts.first_name != "" or contacts.last_name != "" or contacts.email != "")') // filter out buy now invoices
->select(
'company_tokens.id',
'company_tokens.name',
'company_tokens.token',
'company_tokens.created_at',
'company_tokens.created_at as token_created_at',
'company_tokens.deleted_at',
'company_tokens.is_deleted',
'company_tokens.user_id',
);
/**
* If the user does not have permissions to view all invoices
* limit the user to only the invoices they have created
*/
if (Gate::denies('view-list', CompanyToken::class)) {
$query->where('company_tokens.user_id', '=', $user->id);
}
return $query;
}
/**
* Filters the query by the users company ID
*
* @param $company_id The company Id
* @return Illuminate\Database\Query\Builder
*/
public function entityFilter()
{
return $this->builder->company();
}
}

View File

@ -262,7 +262,7 @@ class CreditController extends BaseController
*
* @OA\Get(
* path="/api/v1/credits/{id}/edit",
* operationId="editInvoice",
* operationId="editCredit",
* tags={"credits"},
* summary="Shows an credit for editting",
* description="Displays an credit by id",

View File

@ -0,0 +1,11 @@
<?php
/**
* @OA\Schema(
* schema="Subscription",
* type="object",
* @OA\Property(property="id", type="string", example="AS3df3A", description="The subscription hashed id"),
* @OA\Property(property="event_id", type="string", example="AS3df3A", description="The subscription event id"),
* @OA\Property(property="target_url", type="string", example="AS3df3A", description="The api endpoint"),
* @OA\Property(property="format", type="string", example="JSON", description="JSON or UBL"),
* )
*/

View File

@ -14,6 +14,7 @@ namespace App\Http\Controllers;
use App\Factory\ProductFactory;
use App\Filters\ProductFilters;
use App\Http\Requests\Product\CreateProductRequest;
use App\Http\Requests\Product\DestroyProductRequest;
use App\Http\Requests\Product\EditProductRequest;
use App\Http\Requests\Product\ShowProductRequest;
use App\Http\Requests\Product\StoreProductRequest;
@ -403,11 +404,11 @@ class ProductController extends BaseController
* )
*
*/
public function destroy(Product $product)
public function destroy(DestroyProductRequest $request, Product $product)
{
$product->delete();
return response()->json([], 200);
return $this->itemResponse($product);
}
/**

View File

@ -0,0 +1,598 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Controllers;
use App\Factory\SubscriptionFactory;
use App\Filters\SubscriptionFilters;
use App\Http\Requests\Subscription\CreateSubscriptionRequest;
use App\Http\Requests\Subscription\DestroySubscriptionRequest;
use App\Http\Requests\Subscription\EditSubscriptionRequest;
use App\Http\Requests\Subscription\ShowSubscriptionRequest;
use App\Http\Requests\Subscription\StoreSubscriptionRequest;
use App\Http\Requests\Subscription\UpdateSubscriptionRequest;
use App\Models\Subscription;
use App\Repositories\BaseRepository;
use App\Transformers\SubscriptionTransformer;
use App\Utils\Traits\MakesHash;
use Illuminate\Http\Request;
class SubscriptionController extends BaseController
{
use MakesHash;
protected $entity_type = Subscription::class;
protected $entity_transformer = SubscriptionTransformer::class;
public $base_repo;
public function __construct(BaseRepository $base_repo)
{
parent::__construct();
$this->base_repo = $base_repo;
}
/**
* @OA\Get(
* path="/api/v1/subscriptions",
* operationId="getSubscriptions",
* tags={"subscriptions"},
* summary="Gets a list of subscriptions",
* description="Lists subscriptions, search and filters allow fine grained lists to be generated.
*
* Query parameters can be added to performed more fine grained filtering of the subscriptions, these are handled by the SubscriptionFilters class which defines the methods available",
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
* @OA\Parameter(ref="#/components/parameters/include"),
* @OA\Parameter(ref="#/components/parameters/index"),
* @OA\Response(
* response=200,
* description="A list of subscriptions",
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
* @OA\JsonContent(ref="#/components/schemas/Subscription"),
* ),
* @OA\Response(
* response=422,
* description="Validation error",
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
* ),
* @OA\Response(
* response="default",
* description="Unexpected Error",
* @OA\JsonContent(ref="#/components/schemas/Error"),
* ),
* )
*
*/
public function index(SubscriptionFilters $filters)
{
$subscriptions = Subscription::filter($filters);
return $this->listResponse($subscriptions);
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*
*
* @OA\Get(
* path="/api/v1/subscriptions/{id}",
* operationId="showSubscription",
* tags={"subscriptions"},
* summary="Shows a subscription",
* description="Displays a subscription by id",
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
* @OA\Parameter(ref="#/components/parameters/include"),
* @OA\Parameter(
* name="id",
* in="path",
* description="The Subscription Hashed ID",
* example="D2J234DFA",
* required=true,
* @OA\Schema(
* type="string",
* format="string",
* ),
* ),
* @OA\Response(
* response=200,
* description="Returns the subscription object",
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
* @OA\JsonContent(ref="#/components/schemas/Subscription"),
* ),
* @OA\Response(
* response=422,
* description="Validation error",
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
*
* ),
* @OA\Response(
* response="default",
* description="Unexpected Error",
* @OA\JsonContent(ref="#/components/schemas/Error"),
* ),
* )
*
*/
public function show(ShowSubscriptionRequest $request, Subscription $subscription)
{
return $this->itemResponse($subscription);
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*
*
* @OA\Get(
* path="/api/v1/subscriptions/{id}/edit",
* operationId="editSubscription",
* tags={"subscriptions"},
* summary="Shows a subscription for editting",
* description="Displays a subscription by id",
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
* @OA\Parameter(ref="#/components/parameters/include"),
* @OA\Parameter(
* name="id",
* in="path",
* description="The Subscription Hashed ID",
* example="D2J234DFA",
* required=true,
* @OA\Schema(
* type="string",
* format="string",
* ),
* ),
* @OA\Response(
* response=200,
* description="Returns the subscription object",
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
* @OA\JsonContent(ref="#/components/schemas/Subscription"),
* ),
* @OA\Response(
* response=422,
* description="Validation error",
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
*
* ),
* @OA\Response(
* response="default",
* description="Unexpected Error",
* @OA\JsonContent(ref="#/components/schemas/Error"),
* ),
* )
*
*/
public function edit(EditSubscriptionRequest $request, Subscription $subscription)
{
return $this->itemResponse($subscription);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param App\Models\Subscription $subscription
* @return \Illuminate\Http\Response
*
*
*
* @OA\Put(
* path="/api/v1/subscriptions/{id}",
* operationId="updateSubscription",
* tags={"subscriptions"},
* summary="Updates a subscription",
* description="Handles the updating of a subscription by id",
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
* @OA\Parameter(ref="#/components/parameters/include"),
* @OA\Parameter(
* name="id",
* in="path",
* description="The Subscription Hashed ID",
* example="D2J234DFA",
* required=true,
* @OA\Schema(
* type="string",
* format="string",
* ),
* ),
* @OA\Response(
* response=200,
* description="Returns the subscription object",
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
* @OA\JsonContent(ref="#/components/schemas/Subscription"),
* ),
* @OA\Response(
* response=422,
* description="Validation error",
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
*
* ),
* @OA\Response(
* response="default",
* description="Unexpected Error",
* @OA\JsonContent(ref="#/components/schemas/Error"),
* ),
* )
*
*/
public function update(UpdateSubscriptionRequest $request, Subscription $subscription)
{
if ($request->entityIsDeleted($subscription)) {
return $request->disallowUpdate();
}
$subscription->fill($request->all());
$subscription->save();
return $this->itemResponse($subscription);
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*
*
*
* @OA\Get(
* path="/api/v1/subscriptions/create",
* operationId="getSubscriptionsCreate",
* tags={"subscriptions"},
* summary="Gets a new blank subscription object",
* description="Returns a blank object with default values",
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
* @OA\Parameter(ref="#/components/parameters/include"),
* @OA\Response(
* response=200,
* description="A blank subscription object",
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
* @OA\JsonContent(ref="#/components/schemas/Subscription"),
* ),
* @OA\Response(
* response=422,
* description="Validation error",
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
*
* ),
* @OA\Response(
* response="default",
* description="Unexpected Error",
* @OA\JsonContent(ref="#/components/schemas/Error"),
* ),
* )
*
*/
public function create(CreateSubscriptionRequest $request)
{
$subscription = SubscriptionFactory::create(auth()->user()->company()->id, auth()->user()->id);
return $this->itemResponse($subscription);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*
*
*
* @OA\Post(
* path="/api/v1/subscriptions",
* operationId="storeSubscription",
* tags={"subscriptions"},
* summary="Adds a subscription",
* description="Adds an subscription to a company",
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
* @OA\Parameter(ref="#/components/parameters/include"),
* @OA\Response(
* response=200,
* description="Returns the saved subscription object",
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
* @OA\JsonContent(ref="#/components/schemas/Subscription"),
* ),
* @OA\Response(
* response=422,
* description="Validation error",
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
*
* ),
* @OA\Response(
* response="default",
* description="Unexpected Error",
* @OA\JsonContent(ref="#/components/schemas/Error"),
* ),
* )
*
*/
public function store(StoreSubscriptionRequest $request)
{
$subscription = SubscriptionFactory::create(auth()->user()->company()->id, auth()->user()->id);
$subscription->fill($request->all());
$subscription->save();
return $this->itemResponse($subscription);
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*
*
* @OA\Delete(
* path="/api/v1/subscriptions/{id}",
* operationId="deleteSubscription",
* tags={"subscriptions"},
* summary="Deletes a subscription",
* description="Handles the deletion of a subscription by id",
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
* @OA\Parameter(ref="#/components/parameters/include"),
* @OA\Parameter(
* name="id",
* in="path",
* description="The Subscription Hashed ID",
* example="D2J234DFA",
* required=true,
* @OA\Schema(
* type="string",
* format="string",
* ),
* ),
* @OA\Response(
* response=200,
* description="Returns a HTTP status",
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
* ),
* @OA\Response(
* response=422,
* description="Validation error",
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
*
* ),
* @OA\Response(
* response="default",
* description="Unexpected Error",
* @OA\JsonContent(ref="#/components/schemas/Error"),
* ),
* )
*
*/
public function destroy(DestroySubscriptionRequest $request, Subscription $subscription)
{
//may not need these destroy routes as we are using actions to 'archive/delete'
$subscription->delete();
return $this->itemResponse($subscription);
}
/**
* Perform bulk actions on the list view
*
* @param BulkSubscriptionRequest $request
* @return \Illuminate\Http\Response
*
*
* @OA\Post(
* path="/api/v1/subscriptions/bulk",
* operationId="bulkSubscriptions",
* tags={"subscriptions"},
* summary="Performs bulk actions on an array of subscriptions",
* description="",
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
* @OA\Parameter(ref="#/components/parameters/index"),
* @OA\RequestBody(
* description="User credentials",
* required=true,
* @OA\MediaType(
* mediaType="application/json",
* @OA\Schema(
* type="array",
* @OA\Items(
* type="integer",
* description="Array of hashed IDs to be bulk 'actioned",
* example="[0,1,2,3]",
* ),
* )
* )
* ),
* @OA\Response(
* response=200,
* description="The Subscription User response",
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
* @OA\JsonContent(ref="#/components/schemas/Subscription"),
* ),
* @OA\Response(
* response=422,
* description="Validation error",
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
* ),
* @OA\Response(
* response="default",
* description="Unexpected Error",
* @OA\JsonContent(ref="#/components/schemas/Error"),
* ),
* )
*/
public function bulk()
{
$action = request()->input('action');
$ids = request()->input('ids');
$subscriptions = Subscription::withTrashed()->find($this->transformKeys($ids));
$subscriptions->each(function ($subscription, $key) use ($action) {
if (auth()->user()->can('edit', $subscription)) {
$this->base_repo->{$action}($subscription);
}
});
return $this->listResponse(Subscription::withTrashed()->whereIn('id', $this->transformKeys($ids)));
}
/**
* Store a newly created resource in storage.
*
* @OA\Post(
* path="/api/v1/hooks",
* operationId="storeHook",
* tags={"hooks"},
* summary="Adds a hook",
* description="Adds a hooks to a company",
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
* @OA\Parameter(ref="#/components/parameters/include"),
* @OA\Response(
* response=200,
* description="Returns the saved hooks object",
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
* @OA\JsonContent(ref="#/components/schemas/Subscription"),
* ),
* @OA\Response(
* response=422,
* description="Validation error",
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
*
* ),
* @OA\Response(
* response="default",
* description="Unexpected Error",
* @OA\JsonContent(ref="#/components/schemas/Error"),
* ),
* )
*
*/
public function subscribe(StoreSubscriptionRequest $request)
{
$event_id = $request->input('event_id');
$target_url = $request->input('target_url');
if (! in_array($event_id, Subscription::$valid_events)) {
return response()->json("Invalid event",400);
}
$subscription = new Subscription;
$subscription->company_id = auth()->user()->company()->id;
$subscription->user_id = auth()->user()->id;
$subscription->event_id = $event_id;
$subscription->target_url = $target_url;
$subscription->save();
if (!$subscription->id) {
return response()->json('Failed to create subscription', 400);
}
return $this->itemResponse($subscription);
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*
*
* @OA\Delete(
* path="/api/v1/hooks/{subscription_id}",
* operationId="deleteHook",
* tags={"hooks"},
* summary="Deletes a hook",
* description="Handles the deletion of a hook by id",
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
* @OA\Parameter(ref="#/components/parameters/include"),
* @OA\Parameter(
* name="subscription_id",
* in="path",
* description="The Subscription Hashed ID",
* example="D2J234DFA",
* required=true,
* @OA\Schema(
* type="string",
* format="string",
* ),
* ),
* @OA\Response(
* response=200,
* description="Returns a HTTP status",
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
* ),
* @OA\Response(
* response=422,
* description="Validation error",
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
*
* ),
* @OA\Response(
* response="default",
* description="Unexpected Error",
* @OA\JsonContent(ref="#/components/schemas/Error"),
* ),
* )
*
*/
public function unsubscribe(DestroySubscriptionRequest $request, Subscription $subscription)
{
$subscription->delete();
return $this->itemResponse($subscription);
}
}

View File

@ -0,0 +1,495 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Controllers;
use App\Factory\CompanyTokenFactory;
use App\Filters\TokenFilters;
use App\Http\Requests\Token\CreateTokenRequest;
use App\Http\Requests\Token\DestroyTokenRequest;
use App\Http\Requests\Token\EditTokenRequest;
use App\Http\Requests\Token\ShowTokenRequest;
use App\Http\Requests\Token\StoreTokenRequest;
use App\Http\Requests\Token\UpdateTokenRequest;
use App\Jobs\Entity\ActionEntity;
use App\Models\CompanyToken;
use App\Repositories\BaseRepository;
use App\Repositories\TokenRepository;
use App\Transformers\CompanyTokenTransformer;
use App\Utils\Traits\ChecksEntityStatus;
use App\Utils\Traits\MakesHash;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
/**
* Class TokenController
* @package App\Http\Controllers
*/
class TokenController extends BaseController
{
use MakesHash;
use ChecksEntityStatus;
protected $entity_type = CompanyToken::class;
protected $entity_transformer = CompanyTokenTransformer::class;
public $token_repo;
/**
* TokenController constructor.
* @param TokenRepository $tokenRepo
*/
public function __construct(TokenRepository $token_repo)
{
parent::__construct();
$this->token_repo = $token_repo;
}
/**
* @OA\Get(
* path="/api/v1/tokens",
* operationId="getTokens",
* tags={"tokens"},
* summary="Gets a list of company tokens",
* description="Lists company tokens.
*
* Query parameters can be added to performed more fine grained filtering of the tokens, these are handled by the TokenFilters class which defines the methods available",
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
* @OA\Parameter(ref="#/components/parameters/include"),
* @OA\Parameter(ref="#/components/parameters/index"),
* @OA\Response(
* response=200,
* description="A list of tokens",
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
* @OA\JsonContent(ref="#/components/schemas/CompanyToken"),
* ),
* @OA\Response(
* response=422,
* description="Validation error",
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
* ),
* @OA\Response(
* response="default",
* description="Unexpected Error",
* @OA\JsonContent(ref="#/components/schemas/Error"),
* ),
* )
*
*/
public function index(TokenFilters $filters)
{
$tokens = CompanyToken::filter($filters);
return $this->listResponse($tokens);
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*
*
* @OA\Get(
* path="/api/v1/tokens/{id}",
* operationId="showToken",
* tags={"tokens"},
* summary="Shows a token",
* description="Displays a token by id",
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
* @OA\Parameter(ref="#/components/parameters/include"),
* @OA\Parameter(
* name="id",
* in="path",
* description="The Token Hashed ID",
* example="D2J234DFA",
* required=true,
* @OA\Schema(
* type="string",
* format="string",
* ),
* ),
* @OA\Response(
* response=200,
* description="Returns the token object",
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
* @OA\JsonContent(ref="#/components/schemas/CompanyToken"),
* ),
* @OA\Response(
* response=422,
* description="Validation error",
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
*
* ),
* @OA\Response(
* response="default",
* description="Unexpected Error",
* @OA\JsonContent(ref="#/components/schemas/Error"),
* ),
* )
*
*/
public function show(ShowTokenRequest $request, CompanyToken $token)
{
return $this->itemResponse($token);
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*
*
* @OA\Get(
* path="/api/v1/tokens/{id}/edit",
* operationId="editToken",
* tags={"tokens"},
* summary="Shows a token for editting",
* description="Displays a token by id",
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
* @OA\Parameter(ref="#/components/parameters/include"),
* @OA\Parameter(
* name="id",
* in="path",
* description="The Token Hashed ID",
* example="D2J234DFA",
* required=true,
* @OA\Schema(
* type="string",
* format="string",
* ),
* ),
* @OA\Response(
* response=200,
* description="Returns the token object",
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
* @OA\JsonContent(ref="#/components/schemas/CompanyToken"),
* ),
* @OA\Response(
* response=422,
* description="Validation error",
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
*
* ),
* @OA\Response(
* response="default",
* description="Unexpected Error",
* @OA\JsonContent(ref="#/components/schemas/Error"),
* ),
* )
*
*/
public function edit(EditTokenRequest $request, CompanyToken $token)
{
return $this->itemResponse($token);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param App\Models\Token $token
* @return \Illuminate\Http\Response
*
*
*
* @OA\Put(
* path="/api/v1/tokens/{id}",
* operationId="updateToken",
* tags={"tokens"},
* summary="Updates a token",
* description="Handles the updating of a token by id",
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
* @OA\Parameter(ref="#/components/parameters/include"),
* @OA\Parameter(
* name="id",
* in="path",
* description="The Token Hashed ID",
* example="D2J234DFA",
* required=true,
* @OA\Schema(
* type="string",
* format="string",
* ),
* ),
* @OA\Response(
* response=200,
* description="Returns the token object",
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
* @OA\JsonContent(ref="#/components/schemas/CompanyToken"),
* ),
* @OA\Response(
* response=422,
* description="Validation error",
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
*
* ),
* @OA\Response(
* response="default",
* description="Unexpected Error",
* @OA\JsonContent(ref="#/components/schemas/Error"),
* ),
* )
*
*/
public function update(UpdateTokenRequest $request, CompanyToken $token)
{
if ($request->entityIsDeleted($token)) {
return $request->disallowUpdate();
}
$token = $this->token_repo->save($request->all(), $token);
return $this->itemResponse($token->fresh());
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*
*
*
* @OA\Get(
* path="/api/v1/tokens/create",
* operationId="getTokensCreate",
* tags={"tokens"},
* summary="Gets a new blank token object",
* description="Returns a blank object with default values",
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
* @OA\Parameter(ref="#/components/parameters/include"),
* @OA\Response(
* response=200,
* description="A blank token object",
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
* @OA\JsonContent(ref="#/components/schemas/CompanyToken"),
* ),
* @OA\Response(
* response=422,
* description="Validation error",
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
*
* ),
* @OA\Response(
* response="default",
* description="Unexpected Error",
* @OA\JsonContent(ref="#/components/schemas/Error"),
* ),
* )
*
*/
public function create(CreateTokenRequest $request)
{
$token = CompanyTokenFactory::create(auth()->user()->company()->id, auth()->user()->id, auth()->user()->account_id);
return $this->itemResponse($token);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*
*
*
* @OA\Post(
* path="/api/v1/tokens",
* operationId="storeToken",
* tags={"tokens"},
* summary="Adds a token",
* description="Adds an token to a company",
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
* @OA\Parameter(ref="#/components/parameters/include"),
* @OA\Response(
* response=200,
* description="Returns the saved token object",
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
* @OA\JsonContent(ref="#/components/schemas/CompanyToken"),
* ),
* @OA\Response(
* response=422,
* description="Validation error",
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
*
* ),
* @OA\Response(
* response="default",
* description="Unexpected Error",
* @OA\JsonContent(ref="#/components/schemas/Error"),
* ),
* )
*
*/
public function store(StoreTokenRequest $request)
{
$company_token = CompanyTokenFactory::create(auth()->user()->company()->id, auth()->user()->id, auth()->user()->account_id);
$token = $this->token_repo->save($request->all(), $company_token);
return $this->itemResponse($token);
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*
*
* @OA\Delete(
* path="/api/v1/tokens/{id}",
* operationId="deleteToken",
* tags={"tokens"},
* summary="Deletes a token",
* description="Handles the deletion of a token by id",
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
* @OA\Parameter(ref="#/components/parameters/include"),
* @OA\Parameter(
* name="id",
* in="path",
* description="The Token Hashed ID",
* example="D2J234DFA",
* required=true,
* @OA\Schema(
* type="string",
* format="string",
* ),
* ),
* @OA\Response(
* response=200,
* description="Returns a HTTP status",
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
* ),
* @OA\Response(
* response=422,
* description="Validation error",
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
*
* ),
* @OA\Response(
* response="default",
* description="Unexpected Error",
* @OA\JsonContent(ref="#/components/schemas/Error"),
* ),
* )
*
*/
public function destroy(DestroyTokenRequest $request, CompanyToken $token)
{
//may not need these destroy routes as we are using actions to 'archive/delete'
$token->delete();
return $this->itemResponse($token);
}
/**
* Perform bulk actions on the list view
*
* @param BulkTokenRequest $request
* @return \Illuminate\Http\Response
*
*
* @OA\Post(
* path="/api/v1/tokens/bulk",
* operationId="bulkTokens",
* tags={"tokens"},
* summary="Performs bulk actions on an array of tokens",
* description="",
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
* @OA\Parameter(ref="#/components/parameters/index"),
* @OA\RequestBody(
* description="Token ids",
* required=true,
* @OA\MediaType(
* mediaType="application/json",
* @OA\Schema(
* type="array",
* @OA\Items(
* type="integer",
* description="Array of hashed IDs to be bulk 'actioned",
* example="[0,1,2,3]",
* ),
* )
* )
* ),
* @OA\Response(
* response=200,
* description="The Token response",
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
* @OA\JsonContent(ref="#/components/schemas/CompanyToken"),
* ),
* @OA\Response(
* response=422,
* description="Validation error",
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
* ),
* @OA\Response(
* response="default",
* description="Unexpected Error",
* @OA\JsonContent(ref="#/components/schemas/Error"),
* ),
* )
*/
public function bulk()
{
$action = request()->input('action');
$ids = request()->input('ids');
$tokens = CompanyToken::withTrashed()->find($this->transformKeys($ids));
$tokens->each(function ($token, $key) use ($action) {
if (auth()->user()->can('edit', $token)) {
$this->token_repo->{$action}($token);
}
});
return $this->listResponse(CompanyToken::withTrashed()->whereIn('id', $this->transformKeys($ids)));
}
}

View File

@ -322,11 +322,6 @@ class UserController extends BaseController
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*
*
* @OA\Put(
* path="/api/v1/users/{id}",
* operationId="updateUser",
@ -349,7 +344,7 @@ class UserController extends BaseController
* ),
* ),
* @OA\Response(
f * response=200,
* response=200,
* description="Returns the User object",
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),

View File

@ -0,0 +1,29 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Requests\Product;
use App\Http\Requests\Request;
use App\Models\Payment;
class DestroyProductRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize() : bool
{
return auth()->user()->can('edit', $this->product);
}
}

View File

@ -0,0 +1,47 @@
<?php
namespace App\Http\Requests\Subscription;
use App\Utils\Traits\BulkOptions;
use Illuminate\Foundation\Http\FormRequest;
use App\Models\Vendor;
class BulkSubscriptionRequest extends FormRequest
{
use BulkOptions;
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
if (!$this->has('action')) {
return false;
}
if (!in_array($this->action, $this->getBulkOptions(), true)) {
return false;
}
return auth()->user()->isAdmin();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$rules = $this->getGlobalRules();
/** We don't require IDs on bulk storing. */
if ($this->action !== self::$STORE_METHOD) {
$rules['ids'] = ['required'];
}
return $rules;
}
}

View File

@ -0,0 +1,29 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Requests\Subscription;
use App\Http\Requests\Request;
use App\Models\Vendor;
class CreateSubscriptionRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize() : bool
{
return auth()->user()->isAdmin();
}
}

View File

@ -0,0 +1,31 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Requests\Subscription;
use App\Http\Requests\Request;
class DestroySubscriptionRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize() : bool
{
return auth()->user()->isAdmin();
}
}

View File

@ -0,0 +1,30 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Requests\Subscription;
use App\Http\Requests\Request;
use App\Models\Vendor;
class EditSubscriptionRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize() : bool
{
return auth()->user()->isAdmin();
}
}

View File

@ -0,0 +1,29 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Requests\Subscription;
use App\Http\Requests\Request;
use App\Models\Vendor;
class ShowSubscriptionRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize() : bool
{
return auth()->user()->isAdmin();
}
}

View File

@ -0,0 +1,45 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Requests\Subscription;
use App\Http\Requests\Request;
class StoreSubscriptionRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize() : bool
{
return auth()->user()->isAdmin();
}
public function rules()
{
return [
'target_url' => 'required',
'event_id' => 'required',
];
}
protected function prepareForValidation()
{
$input = $this->all();
$this->replace($input);
}
}

View File

@ -0,0 +1,46 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Requests\Subscription;
use App\Http\Requests\Request;
use App\Utils\Traits\ChecksEntityStatus;
use App\Utils\Traits\MakesHash;
use Illuminate\Validation\Rule;
class UpdateSubscriptionRequest extends Request
{
use MakesHash;
use ChecksEntityStatus;
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize() : bool
{
return auth()->user()->isAdmin();
}
public function rules()
{
return [
];
}
protected function prepareForValidation()
{
$input = $this->all();
$this->replace($input);
}
}

View File

@ -0,0 +1,46 @@
<?php
namespace App\Http\Requests\Token;
use App\Utils\Traits\BulkOptions;
use Illuminate\Foundation\Http\FormRequest;
class BulkTokenRequest extends FormRequest
{
use BulkOptions;
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
if (!$this->has('action')) {
return false;
}
if (!in_array($this->action, $this->getBulkOptions(), true)) {
return false;
}
return auth()->user()->isAdmin();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$rules = $this->getGlobalRules();
/** We don't require IDs on bulk storing. */
if ($this->action !== self::$STORE_METHOD) {
$rules['ids'] = ['required'];
}
return $rules;
}
}

View File

@ -0,0 +1,28 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Requests\Token;
use App\Http\Requests\Request;
class CreateTokenRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize() : bool
{
return auth()->user()->isAdmin();
}
}

View File

@ -0,0 +1,28 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Requests\Token;
use App\Http\Requests\Request;
class DestroyTokenRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize() : bool
{
return auth()->user()->isAdmin();
}
}

View File

@ -0,0 +1,29 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Requests\Token;
use App\Http\Requests\Request;
class EditTokenRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize() : bool
{
return auth()->user()->isAdmin();
}
}

View File

@ -0,0 +1,28 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Requests\Token;
use App\Http\Requests\Request;
class ShowTokenRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize() : bool
{
return auth()->user()->isAdmin();
}
}

View File

@ -0,0 +1,38 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Requests\Token;
use App\Http\Requests\Request;
class StoreTokenRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize() : bool
{
return auth()->user()->isAdmin();
}
public function rules()
{
return [
'name' => 'required',
];
}
}

View File

@ -0,0 +1,34 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Requests\Token;
use App\Http\Requests\Request;
use App\Utils\Traits\ChecksEntityStatus;
class UpdateTokenRequest extends Request
{
use ChecksEntityStatus;
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize() : bool
{
return auth()->user()->isAdmin();
}
}

View File

@ -53,14 +53,15 @@ class CreateCompanyToken implements ShouldQueue
{
$this->custom_token_name = $this->custom_token_name ?: $this->user->first_name. ' '. $this->user->last_name;
$ct = CompanyToken::create([
'user_id' => $this->user->id,
'account_id' => $this->user->account->id,
'token' => Str::random(64),
'name' => $this->custom_token_name ?: $this->user->first_name. ' '. $this->user->last_name,
'company_id' => $this->company->id,
]);
$company_token = new CompanyToken;
$company_token->user_id = $this->user->id;
$company_token->company_id = $this->company->id;
$company_token->account_id = $this->user->account->id;
$company_token->name = $this->custom_token_name ?: $this->user->first_name. ' '. $this->user->last_name;
$company_token->token = Str::random(64);
$company_token->save();
return $ct;
return $company_token;
}
}

View File

@ -11,33 +11,22 @@
namespace App\Models;
use App\Models\Filterable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class CompanyToken extends Model
class CompanyToken extends BaseModel
{
use SoftDeletes;
/**
* @var bool
*/
public $timestamps = false;
use Filterable;
protected $guarded = [
'id',
protected $fillable = [
'name'
];
protected $with = [
// 'user',
// 'company',
];
protected $casts = [
'updated_at' => 'timestamp',
'created_at' => 'timestamp',
'deleted_at' => 'timestamp',
];
public function account()
{
return $this->belongsTo(Account::class);

View File

@ -0,0 +1,69 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Models;
use App\Models\Filterable;
use Illuminate\Database\Eloquent\SoftDeletes;
class Subscription extends BaseModel
{
use SoftDeletes;
use Filterable;
const EVENT_CREATE_CLIENT = 1;
const EVENT_CREATE_INVOICE = 2;
const EVENT_CREATE_QUOTE = 3;
const EVENT_CREATE_PAYMENT = 4;
const EVENT_CREATE_VENDOR = 5;
const EVENT_UPDATE_QUOTE = 6;
const EVENT_DELETE_QUOTE = 7;
const EVENT_UPDATE_INVOICE = 8;
const EVENT_DELETE_INVOICE = 9;
const EVENT_UPDATE_CLIENT = 10;
const EVENT_DELETE_CLIENT = 11;
const EVENT_DELETE_PAYMENT = 12;
const EVENT_UPDATE_VENDOR = 13;
const EVENT_DELETE_VENDOR = 14;
const EVENT_CREATE_EXPENSE = 15;
const EVENT_UPDATE_EXPENSE = 16;
const EVENT_DELETE_EXPENSE = 17;
const EVENT_CREATE_TASK = 18;
const EVENT_UPDATE_TASK = 19;
const EVENT_DELETE_TASK = 20;
const EVENT_APPROVE_QUOTE = 21;
public static $valid_events = [
self::EVENT_CREATE_CLIENT,
self::EVENT_CREATE_PAYMENT,
self::EVENT_CREATE_QUOTE,
self::EVENT_CREATE_INVOICE,
self::EVENT_CREATE_VENDOR,
self::EVENT_CREATE_EXPENSE,
self::EVENT_CREATE_TASK,
];
protected $fillable = [
'target_url',
'format',
'event_id'
];
public function user()
{
return $this->belongsTo(User::class);
}
public function company()
{
return $this->belongsTo(Company::class);
}
}

View File

@ -0,0 +1,22 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Policies;
use App\Models\User;
/**
* Class CompanyTokenPolicy
* @package App\Policies
*/
class CompanyTokenPolicy extends EntityPolicy
{
}

View File

@ -0,0 +1,20 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Policies;
/**
* Class SubscriptionPolicy
* @package App\Policies
*/
class SubscriptionPolicy extends EntityPolicy
{
}

View File

@ -15,6 +15,7 @@ use App\Models\Activity;
use App\Models\Client;
use App\Models\Company;
use App\Models\CompanyGateway;
use App\Models\CompanyToken;
use App\Models\Credit;
use App\Models\Design;
use App\Models\Expense;
@ -25,6 +26,7 @@ use App\Models\Product;
use App\Models\Quote;
use App\Models\RecurringInvoice;
use App\Models\RecurringQuote;
use App\Models\Subscription;
use App\Models\TaxRate;
use App\Models\User;
use App\Models\Vendor;
@ -32,6 +34,7 @@ use App\Policies\ActivityPolicy;
use App\Policies\ClientPolicy;
use App\Policies\CompanyGatewayPolicy;
use App\Policies\CompanyPolicy;
use App\Policies\CompanyTokenPolicy;
use App\Policies\CreditPolicy;
use App\Policies\DesignPolicy;
use App\Policies\ExpensePolicy;
@ -42,6 +45,7 @@ use App\Policies\ProductPolicy;
use App\Policies\QuotePolicy;
use App\Policies\RecurringInvoicePolicy;
use App\Policies\RecurringQuotePolicy;
use App\Policies\SubscriptionPolicy;
use App\Policies\TaxRatePolicy;
use App\Policies\UserPolicy;
use App\Policies\VendorPolicy;
@ -60,20 +64,22 @@ class AuthServiceProvider extends ServiceProvider
Activity::class => ActivityPolicy::class,
Client::class => ClientPolicy::class,
Company::class => CompanyPolicy::class,
Design::class => DesignPolicy::class,
Product::class => ProductPolicy::class,
Invoice::class => InvoicePolicy::class,
CompanyToken::class => CompanyTokenPolicy::class,
CompanyGateway::class => CompanyGatewayPolicy::class,
Credit::class => CreditPolicy::class,
Design::class => DesignPolicy::class,
Expense::class => ExpensePolicy::class,
GroupSetting::class => GroupSettingPolicy::class,
Invoice::class => InvoicePolicy::class,
Payment::class => PaymentPolicy::class,
Product::class => ProductPolicy::class,
Quote::class => QuotePolicy::class,
RecurringInvoice::class => RecurringInvoicePolicy::class,
RecurringQuote::class => RecurringQuotePolicy::class,
Quote::class => QuotePolicy::class,
User::class => UserPolicy::class,
GroupSetting::class => GroupSettingPolicy::class,
CompanyGateway::class => CompanyGatewayPolicy::class,
Subscription::class => SubscriptionPolicy::class,
TaxRate::class => TaxRatePolicy::class,
User::class => UserPolicy::class,
Vendor::class => VendorPolicy::class,
Expense::class => ExpensePolicy::class,
];
/**

View File

@ -0,0 +1,45 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Repositories;
use App\Models\CompanyToken;
class TokenRepository extends BaseRepository
{
/**
* Gets the class name.
*
* @return string The class name.
*/
public function getClassName()
{
return CompanyToken::class;
}
/**
* Saves the companytoken
*
* @param array $data The data
* @param \App\Models\CompanyToken $company_token The company_token
*
* @return CompanyToken|\App\Models\CompanyToken|null CompanyToken Object
*
*/
public function save(array $data, CompanyToken $company_token)
{
$company_token->fill($data);
$company_token->save();
return $company_token;
}
}

View File

@ -47,6 +47,7 @@ class CompanyTokenTransformer extends EntityTransformer
'updated_at' => (int)$company_token->updated_at,
'archived_at' => (int)$company_token->deleted_at,
'created_at' => (int)$company_token->created_at,
'is_deleted' => (bool)$company_token->is_deleted,
];
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace App\Transformers;
use App\Models\Subscription;
use App\Utils\Traits\MakesHash;
class SubscriptionTransformer extends EntityTransformer
{
use MakesHash;
protected $defaultIncludes = [];
/**
* @var array
*/
protected $availableIncludes = [];
/**
* @param Activity $subscription
*
* @return array
*/
public function transform(Subscription $subscription)
{
return [
'id' => (string) $this->encodePrimaryKey($subscription->id),
'company_id' => (string) $this->encodePrimaryKey($subscription->company_id),
'user_id' => (string) $this->encodePrimaryKey($subscription->user_id),
'archived_at' => (int)$subscription->deleted_at,
'updated_at' => (int)$subscription->updated_at,
'created_at' => (int)$subscription->created_at,
'is_deleted' => (bool)$subscription->is_deleted,
'target_url' => $subscription->target_url ? (string) $subscription->target_url : '',
'event_id' => (string) $subscription->event_id,
'format' => (string) $subscription->format,
];
}
}

View File

@ -0,0 +1,46 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddIsDeletedColumnToCompanyTokensTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
/* add ability of companytokens to be deleted.*/
Schema::table('company_tokens', function (Blueprint $table) {
$table->boolean('is_deleted')->default(0);
});
/* add ability of external APIs to be triggered after a model has been created nor updated */
Schema::create('subscriptions', function ($table) {
$table->increments('id');
$table->unsignedInteger('company_id')->nullable();
$table->unsignedInteger('user_id')->nullable();
$table->unsignedInteger('event_id')->nullable();
$table->boolean('is_deleted')->default(0);
$table->string('target_url');
$table->enum('format', ['JSON', 'UBL'])->default('JSON');
$table->timestamps(6);
$table->softDeletes('deleted_at', 6);
$table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
}
}

View File

@ -93,6 +93,8 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a
Route::post('migration/start/{company}', 'MigrationController@startMigration');
Route::resource('companies', 'CompanyController');// name = (companies. index / create / show / update / destroy / edit
Route::resource('tokens', 'TokenController');// name = (tokens. index / create / show / update / destroy / edit
Route::resource('company_gateways', 'CompanyGatewayController');
@ -116,6 +118,12 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a
Route::post('emails', 'EmailController@send')->name('email.send');
/*Subscription and Webhook routes */
Route::post('hooks', 'SubscriptionController@subscribe')->name('hooks.subscribe');
Route::delete('hooks/{subscription_id}', 'SubscriptionController@unsubscribe')->name('hooks.unsubscribe');
Route::resource('subscriptions', 'SubscriptionController');
Route::post('subscriptions/bulk', 'SubscriptionController@bulk')->name('subscriptions.bulk');
/*
Route::resource('tasks', 'TaskController'); // name = (tasks. index / create / show / update / destroy / edit

View File

@ -17,11 +17,12 @@ use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Http\Request;
use Illuminate\Routing\Middleware\ThrottleRequests;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Session;
use Illuminate\Validation\ValidationException;
use Illuminate\Support\Str;
use Tests\TestCase;
use Illuminate\Routing\Middleware\ThrottleRequests;
/**
* @test
@ -295,15 +296,16 @@ class ClientTest extends TestCase
'is_locked' => 0,
]);
$ct = CompanyToken::create([
'account_id' => $account->id,
'company_id' => $company->id,
'user_id' => $user->id,
'token' => \Illuminate\Support\Str::random(64),
'name' => $user->first_name. ' '. $user->last_name,
]);
$token = $ct->token;
$company_token = new CompanyToken;
$company_token->user_id = $user->id;
$company_token->company_id = $company->id;
$company_token->account_id = $account->id;
$company_token->name = $user->first_name. ' '. $user->last_name;
$company_token->token = Str::random(64);
$company_token->save();
$token = $company_token->token;
$data = [
'name' => 'A loyal Client',

View File

@ -0,0 +1,129 @@
<?php
namespace Tests\Feature;
use App\DataMapper\DefaultSettings;
use App\Models\Account;
use App\Models\CompanyToken;
use App\Models\Company;
use App\Models\User;
use App\Utils\Traits\MakesHash;
use Faker\Factory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Session;
use Tests\MockAccountData;
use Tests\TestCase;
use Illuminate\Routing\Middleware\ThrottleRequests;
/**
* @test
* @covers App\Http\Controllers\TokenController
*/
class CompanyTokenApiTest extends TestCase
{
use MakesHash;
use DatabaseTransactions;
use MockAccountData;
public function setUp() :void
{
parent::setUp();
$this->makeTestData();
Session::start();
$this->faker = \Faker\Factory::create();
Model::reguard();
$this->withoutMiddleware(
ThrottleRequests::class
);
}
public function testCompanyTokenList()
{
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token
])->get('/api/v1/tokens');
$response->assertStatus(200);
}
public function testCompanyTokenPost()
{
$data = [
'name' => $this->faker->firstName,
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token
])->post('/api/v1/tokens', $data);
$response->assertStatus(200);
}
public function testCompanyTokenPut()
{
$company_token = CompanyToken::whereCompanyId($this->company->id)->first();
$data = [
'name' => "newname",
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token
])->put('/api/v1/tokens/'.$this->encodePrimaryKey($company_token->id), $data);
$response->assertStatus(200);
$arr = $response->json();
$this->assertEquals('newname', $arr['data']['name']);
}
public function testCompanyTokenGet()
{
$company_token = CompanyToken::whereCompanyId($this->company->id)->first();
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token
])->get('/api/v1/tokens/'.$this->encodePrimaryKey($company_token->id));
$response->assertStatus(200);
}
public function testCompanyTokenNotArchived()
{
$company_token = CompanyToken::whereCompanyId($this->company->id)->first();
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token
])->get('/api/v1/tokens/'.$this->encodePrimaryKey($company_token->id));
$arr = $response->json();
$this->assertEquals(0, $arr['data']['archived_at']);
}
}

View File

@ -145,14 +145,14 @@ class LoginTest extends TestCase
$account->default_company_id = $company->id;
$account->save();
$company_token = new CompanyToken;
$company_token->user_id = $user->id;
$company_token->company_id = $company->id;
$company_token->account_id = $account->id;
$company_token->name = $user->first_name. ' '. $user->last_name;
$company_token->token = \Illuminate\Support\Str::random(64);
$company_token->save();
$ct = CompanyToken::create([
'user_id' => $user->id,
'account_id' => $account->id,
'token' => \Illuminate\Support\Str::random(64),
'name' => $user->first_name. ' '. $user->last_name,
'company_id' => $company->id,
]);
$user->companies()->attach($company->id, [
'account_id' => $account->id,

View File

@ -0,0 +1,127 @@
<?php
namespace Tests\Feature;
use App\Utils\Traits\MakesHash;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Routing\Middleware\ThrottleRequests;
use Illuminate\Support\Carbon;
use Illuminate\Validation\ValidationException;
use Tests\MockAccountData;
use Tests\TestCase;
/**
* @test
* @covers App\Http\Controllers\SubscriptionController
*/
class SubscriptionAPITest extends TestCase
{
use MakesHash;
use DatabaseTransactions;
use MockAccountData;
public function setUp() :void
{
parent::setUp();
$this->withoutMiddleware(
ThrottleRequests::class
);
$this->faker = \Faker\Factory::create();
Model::reguard();
$this->makeTestData();
$this->withoutExceptionHandling();
}
public function testSubscriptionGetRoute()
{
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->get('/api/v1/subscriptions');
$response->assertStatus(200);
}
public function testSubscriptionPostRoute()
{
$data = [
'target_url' => 'http://hook.com',
'event_id' => 1,
'format' => 'JSON'
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/subscriptions', $data);
$response->assertStatus(200);
$arr = $response->json();
$this->assertEquals(1, $arr['data']['event_id']);
$data = [
'event_id' => 2,
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->put('/api/v1/subscriptions/'.$arr['data']['id'], $data);
$response->assertStatus(200);
$arr = $response->json();
$this->assertEquals(2, $arr['data']['event_id']);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->delete('/api/v1/subscriptions/'.$arr['data']['id']);
$arr = $response->json();
$this->assertNotNull($arr['data']['archived_at']);
$data = [
'ids' => [$arr['data']['id']],
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token
])->post('/api/v1/subscriptions/bulk?action=restore', $data);
$arr = $response->json();
\Log::error(print_r($arr,1));
$this->assertEquals(0,$arr['data'][0]['archived_at']);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token
])->post('/api/v1/subscriptions/bulk?action=delete', $data);
$arr = $response->json();
$this->assertNotNull($arr['data'][0]['archived_at']);
$this->assertTrue($arr['data'][0]['is_deleted']);
}
}

View File

@ -132,15 +132,15 @@ class UserTest extends TestCase
$company2 = factory(\App\Models\Company::class)->create([
'account_id' => $this->account->id,
]);
$company_token = new CompanyToken;
$company_token->user_id = $this->user->id;
$company_token->company_id = $company2->id;
$company_token->account_id = $this->account->id;
$company_token->name = 'test token';
$company_token->token = \Illuminate\Support\Str::random(64);
$company_token->save();
/* Create New Company Token*/
$user_1_company_token = CompanyToken::create([
'user_id' => $this->user->id,
'company_id' => $company2->id,
'account_id' => $this->account->id,
'name' => 'test token',
'token' => \Illuminate\Support\Str::random(64),
]);
/*Manually link this user to the company*/
$cu = CompanyUserFactory::create($this->user->id, $company2->id, $this->account->id);
@ -156,7 +156,7 @@ class UserTest extends TestCase
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $user_1_company_token->token,
'X-API-TOKEN' => $company_token->token,
])->post('/api/v1/users/'.$this->encodePrimaryKey($new_user->id).'/attach_to_company?include=company_user');
$response->assertStatus(200);
@ -179,7 +179,7 @@ class UserTest extends TestCase
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $user_1_company_token->token,
'X-API-TOKEN' => $company_token->token,
])->post('/api/v1/users?include=company_user', $data);
$response->assertStatus(200);
@ -215,7 +215,7 @@ class UserTest extends TestCase
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $user_1_company_token->token,
'X-API-TOKEN' => $company_token->token,
'X-API-PASSWORD' => 'ALongAndBriliantPassword',
])->put('/api/v1/users/'.$this->encodePrimaryKey($user->id).'?include=company_user', $data);

View File

@ -115,13 +115,13 @@ class CompanyLedgerTest extends TestCase
$this->token = \Illuminate\Support\Str::random(64);
$company_token = CompanyToken::create([
'user_id' => $this->user->id,
'company_id' => $this->company->id,
'account_id' => $this->account->id,
'name' => 'test token',
'token' => $this->token,
]);
$company_token = new CompanyToken;
$company_token->user_id = $this->user->id;
$company_token->company_id = $this->company->id;
$company_token->account_id = $this->account->id;
$company_token->name = 'test token';
$company_token->token = $this->token;
$company_token->save();
$this->client = factory(\App\Models\Client::class)->create([
'user_id' => $this->user->id,

View File

@ -132,25 +132,14 @@ trait MockAccountData
$this->token = \Illuminate\Support\Str::random(64);
$company_token = CompanyToken::create([
'user_id' => $this->user->id,
'company_id' => $this->company->id,
'account_id' => $this->account->id,
'name' => 'test token',
'token' => $this->token,
]);
$company_token = new CompanyToken;
$company_token->user_id = $this->user->id;
$company_token->company_id = $this->company->id;
$company_token->account_id = $this->account->id;
$company_token->name = 'test token';
$company_token->token = $this->token;
$company_token->save();
// $this->user->companies()->attach($this->company->id, [
// 'account_id' => $this->account->id,
// 'is_owner' => 1,
// 'is_admin' => 1,
// 'is_locked' => 0,
// 'permissions' => '',
// 'settings' => json_encode(DefaultSettings::userSettings()),
// ]);
// $this->client = ClientFactory::create($this->company->id, $this->user->id);
// $this->client->save();
$this->client = factory(\App\Models\Client::class)->create([
'user_id' => $this->user->id,