mirror of
https://github.com/cedar2025/Xboard.git
synced 2025-01-22 10:38:14 -05:00
upgrade to lararvel 11 and fixcorrect know file issues
This commit is contained in:
parent
9cd3859def
commit
e7745cb4d9
3
.gitignore
vendored
3
.gitignore
vendored
@ -29,4 +29,5 @@ cli-php.ini
|
||||
frontend
|
||||
docker-compose.yaml
|
||||
bun.lockb
|
||||
compose.yaml
|
||||
compose.yaml
|
||||
.scribe
|
@ -180,7 +180,7 @@ class AuthController extends Controller
|
||||
|
||||
$authService = new AuthService($user);
|
||||
|
||||
$data = $authService->generateAuthData($request);
|
||||
$data = $authService->generateAuthData();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
@ -223,48 +223,70 @@ class AuthController extends Controller
|
||||
}
|
||||
|
||||
$authService = new AuthService($user);
|
||||
return $this->success($authService->generateAuthData($request));
|
||||
return $this->success($authService->generateAuthData());
|
||||
}
|
||||
|
||||
public function token2Login(Request $request)
|
||||
{
|
||||
if ($request->input('token')) {
|
||||
$redirect = '/#/login?verify=' . $request->input('token') . '&redirect=' . ($request->input('redirect') ? $request->input('redirect') : 'dashboard');
|
||||
if (admin_setting('app_url')) {
|
||||
$location = admin_setting('app_url') . $redirect;
|
||||
} else {
|
||||
$location = url($redirect);
|
||||
}
|
||||
return redirect()->to($location)->send();
|
||||
if ($token = $request->input('token')) {
|
||||
$redirect = '/#/login?verify=' . $token . '&redirect=' . ($request->input('redirect', 'dashboard'));
|
||||
|
||||
return redirect()->to(
|
||||
admin_setting('app_url')
|
||||
? admin_setting('app_url') . $redirect
|
||||
: url($redirect)
|
||||
);
|
||||
}
|
||||
|
||||
if ($request->input('verify')) {
|
||||
$key = CacheKey::get('TEMP_TOKEN', $request->input('verify'));
|
||||
if ($verify = $request->input('verify')) {
|
||||
$key = CacheKey::get('TEMP_TOKEN', $verify);
|
||||
$userId = Cache::get($key);
|
||||
|
||||
if (!$userId) {
|
||||
return $this->fail([400,__('Token error')]);
|
||||
}
|
||||
$user = User::find($userId);
|
||||
if (!$user) {
|
||||
return $this->fail([400,__('The user does not ')]);
|
||||
return response()->json([
|
||||
'message' => __('Token error')
|
||||
], 400);
|
||||
}
|
||||
|
||||
$user = User::findOrFail($userId);
|
||||
|
||||
if ($user->banned) {
|
||||
return $this->fail([400,__('Your account has been suspended')]);
|
||||
return response()->json([
|
||||
'message' => __('Your account has been suspended')
|
||||
], 400);
|
||||
}
|
||||
|
||||
Cache::forget($key);
|
||||
$authService = new AuthService($user);
|
||||
return $this->success($authService->generateAuthData($request));
|
||||
|
||||
return response()->json([
|
||||
'data' => $authService->generateAuthData()
|
||||
]);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'message' => __('Invalid request')
|
||||
], 400);
|
||||
}
|
||||
|
||||
public function getQuickLoginUrl(Request $request)
|
||||
{
|
||||
$authorization = $request->input('auth_data') ?? $request->header('authorization');
|
||||
if (!$authorization) return $this->fail(ResponseEnum::CLIENT_HTTP_UNAUTHORIZED);
|
||||
|
||||
$user = AuthService::decryptAuthData($authorization);
|
||||
if (!$user) return $this->fail(ResponseEnum::CLIENT_HTTP_UNAUTHORIZED_EXPIRED);
|
||||
|
||||
if (!$authorization) {
|
||||
return response()->json([
|
||||
'message' => ResponseEnum::CLIENT_HTTP_UNAUTHORIZED
|
||||
], 401);
|
||||
}
|
||||
|
||||
$user = AuthService::findUserByBearerToken($authorization);
|
||||
|
||||
if (!$user) {
|
||||
return response()->json([
|
||||
'message' => ResponseEnum::CLIENT_HTTP_UNAUTHORIZED_EXPIRED
|
||||
], 401);
|
||||
}
|
||||
|
||||
$code = Helper::guid();
|
||||
$key = CacheKey::get('TEMP_TOKEN', $code);
|
||||
Cache::put($key, $user['id'], 60);
|
||||
|
@ -35,47 +35,47 @@ class OrderController extends Controller
|
||||
$current = $request->input('current', 1);
|
||||
$pageSize = $request->input('pageSize', 10);
|
||||
$orderModel = Order::with('plan:id,name');
|
||||
if ($request->input('is_commission')) {
|
||||
|
||||
if ($request->boolean('is_commission')) {
|
||||
$orderModel->whereNotNull('invite_user_id')
|
||||
->whereNotIn('status', [0, 2])
|
||||
->where('commission_balance', '>', 0);
|
||||
}
|
||||
|
||||
$this->applyFiltersAndSorts($request, $orderModel);
|
||||
$orders = $orderModel
|
||||
->orderBy('created_at', 'desc')
|
||||
->paginate($pageSize, ['*'], 'page', $current);
|
||||
return response([
|
||||
'data' => $orders->transform(function ($order) {
|
||||
$order['period'] = PlanService::getLegacyPeriod($order->period);
|
||||
return $order;
|
||||
}),
|
||||
'total' => $orders->total()
|
||||
]);
|
||||
|
||||
return response()->json(
|
||||
$orderModel
|
||||
->latest('created_at')
|
||||
->paginate(
|
||||
perPage: $pageSize,
|
||||
page: $current
|
||||
)->through(fn($order) => [
|
||||
...$order->toArray(),
|
||||
'period' => PlanService::getLegacyPeriod($order->period)
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
private function applyFiltersAndSorts(Request $request, $builder)
|
||||
{
|
||||
if ($request->has('filter')) {
|
||||
collect($request->input('filter'))->each(callback: function ($filter) use ($builder) {
|
||||
$key = $filter['id'];
|
||||
$value = $filter['value'];
|
||||
$builder->where(function ($query) use ($key, $value) {
|
||||
if (is_array($value)) {
|
||||
$query->whereIn($key, $value);
|
||||
} else {
|
||||
$query->where($key, 'like', "%{$value}%");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
$request->collect('filter')->each(function ($filter) use ($builder) {
|
||||
$key = $filter['id'];
|
||||
$value = $filter['value'];
|
||||
|
||||
if ($request->has('sort')) {
|
||||
collect($request->input('sort'))->each(function ($sort) use ($builder) {
|
||||
$key = $sort['id'];
|
||||
$value = $sort['desc'] ? 'DESC' : 'ASC';
|
||||
$builder->orderBy($key, $value);
|
||||
$builder->where(function ($query) use ($key, $value) {
|
||||
is_array($value)
|
||||
? $query->whereIn($key, $value)
|
||||
: $query->where($key, 'like', "%{$value}%");
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$request->collect('sort')->each(function ($sort) use ($builder) {
|
||||
$builder->orderBy(
|
||||
$sort['id'],
|
||||
$sort['desc'] ? 'DESC' : 'ASC'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function paid(Request $request)
|
||||
|
@ -2,11 +2,8 @@
|
||||
|
||||
namespace App\Http\Controllers\V2\Admin;
|
||||
|
||||
use App\Exceptions\ApiException;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Ticket;
|
||||
use App\Models\TicketMessage;
|
||||
use App\Models\User;
|
||||
use App\Services\TicketService;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Http\Request;
|
||||
@ -54,15 +51,15 @@ class TicketController extends Controller
|
||||
private function fetchTicketById(Request $request)
|
||||
{
|
||||
$ticket = Ticket::with('messages', 'user')->find($request->input('id'));
|
||||
|
||||
|
||||
if (!$ticket) {
|
||||
return $this->fail([400202, '工单不存在']);
|
||||
}
|
||||
|
||||
|
||||
$ticket->messages->each(function ($message) use ($ticket) {
|
||||
$message->is_me = $message->user_id !== $ticket->user_id;
|
||||
});
|
||||
|
||||
|
||||
return $this->success($ticket);
|
||||
}
|
||||
|
||||
@ -73,35 +70,27 @@ class TicketController extends Controller
|
||||
*/
|
||||
private function fetchTickets(Request $request)
|
||||
{
|
||||
$current = $request->input('current') ?? 1;
|
||||
$pageSize = $request->input('pageSize') >= 10 ? $request->input('pageSize') : 10;
|
||||
$ticketModel = Ticket::query()
|
||||
->when($request->has('status'), function ($query) use ($request) {
|
||||
$query->where('status', $request->input('status'));
|
||||
})
|
||||
->when($request->has('reply_status'), function ($query) use ($request) {
|
||||
$query->whereIn('reply_status', $request->input('reply_status'));
|
||||
})
|
||||
->when($request->has('email'), function ($query) use ($request) {
|
||||
$query->whereHas('user', function ($q) use ($request) {
|
||||
$q->where('email', $request->input('email'));
|
||||
});
|
||||
});
|
||||
|
||||
$ticketModel = Ticket::query();
|
||||
$this->applyFiltersAndSorts($request, $ticketModel);
|
||||
$ticketModel->orderBy('updated_at', 'DESC');
|
||||
|
||||
if ($request->has('status')) {
|
||||
$ticketModel->where('status', $request->input('status'));
|
||||
}
|
||||
|
||||
if ($request->has('reply_status')) {
|
||||
$ticketModel->whereIn('reply_status', $request->input('reply_status'));
|
||||
}
|
||||
|
||||
if ($request->has('email')) {
|
||||
$user = User::where('email', $request->input('email'))->first();
|
||||
if ($user) {
|
||||
$ticketModel->where('user_id', $user->id);
|
||||
}
|
||||
}
|
||||
|
||||
$total = $ticketModel->count();
|
||||
$res = $ticketModel->forPage($current, $pageSize)->get();
|
||||
|
||||
return response([
|
||||
'data' => $res,
|
||||
'total' => $total
|
||||
]);
|
||||
return response()->json($ticketModel
|
||||
->latest('updated_at')
|
||||
->paginate(
|
||||
perPage: $request->integer('pageSize', 10),
|
||||
page: $request->integer('current', 1)
|
||||
));
|
||||
}
|
||||
|
||||
public function reply(Request $request)
|
||||
|
@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use App\Models\Server;
|
||||
@ -7,15 +9,56 @@ use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ServerSave extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
private const PROTOCOL_RULES = [
|
||||
'shadowsocks' => [
|
||||
'cipher' => 'required|string',
|
||||
'obfs' => 'nullable|string',
|
||||
'obfs_settings.path' => 'nullable|string',
|
||||
'obfs_settings.host' => 'nullable|string',
|
||||
],
|
||||
'vmess' => [
|
||||
'tls' => 'required|integer',
|
||||
'network' => 'required|string',
|
||||
'network_settings' => 'nullable|array',
|
||||
'tls_settings.server_name' => 'nullable|string',
|
||||
'tls_settings.allow_insecure' => 'nullable|boolean',
|
||||
],
|
||||
'trojan' => [
|
||||
'network' => 'required|string',
|
||||
'network_settings' => 'nullable|array',
|
||||
'server_name' => 'nullable|string',
|
||||
'allow_insecure' => 'nullable|boolean',
|
||||
],
|
||||
'hysteria' => [
|
||||
'version' => 'required|integer',
|
||||
'alpn' => 'nullable|string',
|
||||
'obfs.open' => 'nullable|boolean',
|
||||
'obfs.type' => 'string|nullable',
|
||||
'obfs.password' => 'string|nullable',
|
||||
'tls.server_name' => 'nullable|string',
|
||||
'tls.allow_insecure' => 'nullable|boolean',
|
||||
'bandwidth.up' => 'nullable|integer',
|
||||
'bandwidth.down' => 'nullable|integer',
|
||||
],
|
||||
'vless' => [
|
||||
'tls' => 'required|integer',
|
||||
'network' => 'required|string',
|
||||
'network_settings' => 'nullable|array',
|
||||
'flow' => 'nullable|string',
|
||||
'tls_settings.server_name' => 'nullable|string',
|
||||
'tls_settings.allow_insecure' => 'nullable|boolean',
|
||||
'reality_settings.allow_insecure' => 'nullable|boolean',
|
||||
'reality_settings.server_name' => 'nullable|string',
|
||||
'reality_settings.server_port' => 'nullable|integer',
|
||||
'reality_settings.public_key' => 'nullable|string',
|
||||
'reality_settings.private_key' => 'nullable|string',
|
||||
'reality_settings.short_id' => 'nullable|string',
|
||||
]
|
||||
];
|
||||
|
||||
private function getBaseRules(): array
|
||||
{
|
||||
$type = $this->input('type');
|
||||
$protocolRules = [
|
||||
return [
|
||||
'type' => 'required|in:' . implode(',', Server::VALID_TYPES),
|
||||
'spectific_key' => 'nullable|string',
|
||||
'code' => 'nullable|string',
|
||||
@ -33,56 +76,14 @@ class ServerSave extends FormRequest
|
||||
'rate' => 'required|numeric',
|
||||
'protocol_settings' => 'array',
|
||||
];
|
||||
}
|
||||
|
||||
$protocolSpecificRules = [
|
||||
'shadowsocks' => [
|
||||
'cipher' => 'required|string',
|
||||
'obfs' => 'nullable|string',
|
||||
'obfs_settings.path' => 'nullable|string',
|
||||
'obfs_settings.host' => 'nullable|string',
|
||||
],
|
||||
'vmess' => [
|
||||
'tls' => 'required|integer',
|
||||
'network' => 'required|string',
|
||||
'network_settings' => 'nullable|array',
|
||||
'tls_settings.server_name' => 'nullable|string',
|
||||
'tls_settings.allow_insecure' => 'nullable|boolean',
|
||||
],
|
||||
'trojan' => [
|
||||
'network' => 'required|string',
|
||||
'network_settings' => 'nullable|array',
|
||||
'server_name' => 'nullable|string',
|
||||
'allow_insecure' => 'nullable|boolean',
|
||||
],
|
||||
'hysteria' => [
|
||||
'version' => 'required|integer',
|
||||
'alpn' => 'nullable|string',
|
||||
'obfs.open' => 'nullable|boolean',
|
||||
'obfs.type' => 'string|nullable',
|
||||
'obfs.password' => 'string|nullable',
|
||||
'tls.server_name' => 'nullable|string',
|
||||
'tls.allow_insecure' => 'nullable|boolean',
|
||||
'bandwidth.up' => 'nullable|integer',
|
||||
'bandwidth.down' => 'nullable|integer',
|
||||
],
|
||||
'vless' => [
|
||||
'tls' => 'required|integer',
|
||||
'network' => 'required|string',
|
||||
'network_settings' => 'nullable|array',
|
||||
'flow' => 'nullable|string',
|
||||
'tls_settings.server_name' => 'nullable|string',
|
||||
'tls_settings.allow_insecure' => 'nullable|boolean',
|
||||
'reality_settings.allow_insecure' => 'nullable|boolean',
|
||||
'reality_settings.server_name' => 'nullable|string',
|
||||
'reality_settings.server_port' => 'nullable|integer',
|
||||
'reality_settings.public_key' => 'nullable|string',
|
||||
'reality_settings.private_key' => 'nullable|string',
|
||||
'reality_settings.short_id' => 'nullable|string',
|
||||
]
|
||||
];
|
||||
|
||||
$rules = $protocolRules;
|
||||
foreach ($protocolSpecificRules[$type] as $field => $rule) {
|
||||
public function rules(): array
|
||||
{
|
||||
$type = $this->input('type');
|
||||
$rules = $this->getBaseRules();
|
||||
|
||||
foreach (self::PROTOCOL_RULES[$type] ?? [] as $field => $rule) {
|
||||
$rules['protocol_settings.' . $field] = $rule;
|
||||
}
|
||||
|
||||
|
@ -3,11 +3,8 @@
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Utils\CacheKey;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Laravel\Sanctum\NewAccessToken;
|
||||
use Illuminate\Support\Str;
|
||||
use Laravel\Sanctum\PersonalAccessToken;
|
||||
|
||||
class AuthService
|
||||
{
|
||||
@ -47,4 +44,13 @@ class AuthService
|
||||
$this->user->tokens()->delete();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function findUserByBearerToken(string $bearerToken): ?User
|
||||
{
|
||||
$token = str_replace('Bearer ', '', $bearerToken);
|
||||
|
||||
$accessToken = PersonalAccessToken::findToken($token);
|
||||
|
||||
return $accessToken?->tokenable;
|
||||
}
|
||||
}
|
||||
|
@ -11,17 +11,17 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^8.1",
|
||||
"php": "^8.2",
|
||||
"doctrine/dbal": "^3.7",
|
||||
"google/cloud-storage": "^1.35",
|
||||
"google/recaptcha": "^1.2",
|
||||
"guzzlehttp/guzzle": "^7.4.3",
|
||||
"laravel/framework": "10.*",
|
||||
"laravel/horizon": "^5.9.6",
|
||||
"laravel/octane": "*",
|
||||
"laravel/prompts": "^0.1.22",
|
||||
"laravel/sanctum": "^3.3",
|
||||
"laravel/tinker": "^2.5",
|
||||
"guzzlehttp/guzzle": "^7.8",
|
||||
"laravel/framework": "^11.0",
|
||||
"laravel/horizon": "^5.21",
|
||||
"laravel/octane": "^2.3",
|
||||
"laravel/prompts": "^0.1.13",
|
||||
"laravel/sanctum": "^4.0",
|
||||
"laravel/tinker": "^2.9",
|
||||
"linfo/linfo": "^4.0",
|
||||
"paragonie/sodium_compat": "^1.20",
|
||||
"php-curl-class/php-curl-class": "^8.6",
|
||||
@ -35,11 +35,11 @@
|
||||
"require-dev": {
|
||||
"barryvdh/laravel-debugbar": "^3.9",
|
||||
"fakerphp/faker": "^1.9.1",
|
||||
"mockery/mockery": "^1.3.1",
|
||||
"nunomaduro/collision": "^7.10",
|
||||
"mockery/mockery": "^1.6",
|
||||
"nunomaduro/collision": "^8.0",
|
||||
"orangehill/iseed": "^3.0",
|
||||
"phpunit/phpunit": "^10.0",
|
||||
"spatie/laravel-ignition": "^2.0"
|
||||
"phpunit/phpunit": "^10.5",
|
||||
"spatie/laravel-ignition": "^2.4"
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
|
@ -180,57 +180,6 @@ return [
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Class Aliases
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This array of class aliases will be registered when this application
|
||||
| is started. However, feel free to register as many as you wish as
|
||||
| the aliases are "lazy" loaded so they don't hinder performance.
|
||||
|
|
||||
*/
|
||||
|
||||
'aliases' => [
|
||||
|
||||
'App' => Illuminate\Support\Facades\App::class,
|
||||
'Arr' => Illuminate\Support\Arr::class,
|
||||
'Artisan' => Illuminate\Support\Facades\Artisan::class,
|
||||
'Auth' => Illuminate\Support\Facades\Auth::class,
|
||||
'Blade' => Illuminate\Support\Facades\Blade::class,
|
||||
'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
|
||||
'Bus' => Illuminate\Support\Facades\Bus::class,
|
||||
'Cache' => Illuminate\Support\Facades\Cache::class,
|
||||
'Config' => Illuminate\Support\Facades\Config::class,
|
||||
'Cookie' => Illuminate\Support\Facades\Cookie::class,
|
||||
'Crypt' => Illuminate\Support\Facades\Crypt::class,
|
||||
'DB' => Illuminate\Support\Facades\DB::class,
|
||||
'Eloquent' => Illuminate\Database\Eloquent\Model::class,
|
||||
'Event' => Illuminate\Support\Facades\Event::class,
|
||||
'File' => Illuminate\Support\Facades\File::class,
|
||||
'Gate' => Illuminate\Support\Facades\Gate::class,
|
||||
'Hash' => Illuminate\Support\Facades\Hash::class,
|
||||
'Lang' => Illuminate\Support\Facades\Lang::class,
|
||||
'Log' => Illuminate\Support\Facades\Log::class,
|
||||
'Mail' => Illuminate\Support\Facades\Mail::class,
|
||||
'Notification' => Illuminate\Support\Facades\Notification::class,
|
||||
'Password' => Illuminate\Support\Facades\Password::class,
|
||||
'Queue' => Illuminate\Support\Facades\Queue::class,
|
||||
'Redirect' => Illuminate\Support\Facades\Redirect::class,
|
||||
'Redis' => Illuminate\Support\Facades\Redis::class,
|
||||
'Request' => Illuminate\Support\Facades\Request::class,
|
||||
'Response' => Illuminate\Support\Facades\Response::class,
|
||||
'Route' => Illuminate\Support\Facades\Route::class,
|
||||
'Schema' => Illuminate\Support\Facades\Schema::class,
|
||||
'Session' => Illuminate\Support\Facades\Session::class,
|
||||
'Storage' => Illuminate\Support\Facades\Storage::class,
|
||||
'Str' => Illuminate\Support\Str::class,
|
||||
'URL' => Illuminate\Support\Facades\URL::class,
|
||||
'Validator' => Illuminate\Support\Facades\Validator::class,
|
||||
'View' => Illuminate\Support\Facades\View::class,
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| V2board version
|
||||
|
270
config/scribe.php
Normal file
270
config/scribe.php
Normal file
@ -0,0 +1,270 @@
|
||||
<?php
|
||||
|
||||
use Knuckles\Scribe\Extracting\Strategies;
|
||||
|
||||
return [
|
||||
// The HTML <title> for the generated documentation. If this is empty, Scribe will infer it from config('app.name').
|
||||
'title' => null,
|
||||
|
||||
// A short description of your API. Will be included in the docs webpage, Postman collection and OpenAPI spec.
|
||||
'description' => '',
|
||||
|
||||
// The base URL displayed in the docs. If this is empty, Scribe will use the value of config('app.url') at generation time.
|
||||
// If you're using `laravel` type, you can set this to a dynamic string, like '{{ config("app.tenant_url") }}' to get a dynamic base URL.
|
||||
'base_url' => null,
|
||||
|
||||
'routes' => [
|
||||
[
|
||||
// Routes that match these conditions will be included in the docs
|
||||
'match' => [
|
||||
// Match only routes whose paths match this pattern (use * as a wildcard to match any characters). Example: 'users/*'.
|
||||
'prefixes' => ['api/*'],
|
||||
|
||||
// Match only routes whose domains match this pattern (use * as a wildcard to match any characters). Example: 'api.*'.
|
||||
'domains' => ['*'],
|
||||
|
||||
// [Dingo router only] Match only routes registered under this version. Wildcards are NOT supported.
|
||||
'versions' => ['v1'],
|
||||
],
|
||||
|
||||
// Include these routes even if they did not match the rules above.
|
||||
'include' => [
|
||||
// 'users.index', 'POST /new', '/auth/*'
|
||||
],
|
||||
|
||||
// Exclude these routes even if they matched the rules above.
|
||||
'exclude' => [
|
||||
// 'GET /health', 'admin.*'
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
// The type of documentation output to generate.
|
||||
// - "static" will generate a static HTMl page in the /public/docs folder,
|
||||
// - "laravel" will generate the documentation as a Blade view, so you can add routing and authentication.
|
||||
// - "external_static" and "external_laravel" do the same as above, but generate a basic template,
|
||||
// passing the OpenAPI spec as a URL, allowing you to easily use the docs with an external generator
|
||||
'type' => 'static',
|
||||
|
||||
// See https://scribe.knuckles.wtf/laravel/reference/config#theme for supported options
|
||||
'theme' => 'default',
|
||||
|
||||
'static' => [
|
||||
// HTML documentation, assets and Postman collection will be generated to this folder.
|
||||
// Source Markdown will still be in resources/docs.
|
||||
'output_path' => 'public/docs',
|
||||
],
|
||||
|
||||
'laravel' => [
|
||||
// Whether to automatically create a docs endpoint for you to view your generated docs.
|
||||
// If this is false, you can still set up routing manually.
|
||||
'add_routes' => true,
|
||||
|
||||
// URL path to use for the docs endpoint (if `add_routes` is true).
|
||||
// By default, `/docs` opens the HTML page, `/docs.postman` opens the Postman collection, and `/docs.openapi` the OpenAPI spec.
|
||||
'docs_url' => '/docs',
|
||||
|
||||
// Directory within `public` in which to store CSS and JS assets.
|
||||
// By default, assets are stored in `public/vendor/scribe`.
|
||||
// If set, assets will be stored in `public/{{assets_directory}}`
|
||||
'assets_directory' => null,
|
||||
|
||||
// Middleware to attach to the docs endpoint (if `add_routes` is true).
|
||||
'middleware' => [],
|
||||
],
|
||||
|
||||
'external' => [
|
||||
'html_attributes' => []
|
||||
],
|
||||
|
||||
'try_it_out' => [
|
||||
// Add a Try It Out button to your endpoints so consumers can test endpoints right from their browser.
|
||||
// Don't forget to enable CORS headers for your endpoints.
|
||||
'enabled' => true,
|
||||
|
||||
// The base URL for the API tester to use (for example, you can set this to your staging URL).
|
||||
// Leave as null to use the current app URL when generating (config("app.url")).
|
||||
'base_url' => null,
|
||||
|
||||
// [Laravel Sanctum] Fetch a CSRF token before each request, and add it as an X-XSRF-TOKEN header.
|
||||
'use_csrf' => false,
|
||||
|
||||
// The URL to fetch the CSRF token from (if `use_csrf` is true).
|
||||
'csrf_url' => '/sanctum/csrf-cookie',
|
||||
],
|
||||
|
||||
// How is your API authenticated? This information will be used in the displayed docs, generated examples and response calls.
|
||||
'auth' => [
|
||||
// Set this to true if ANY endpoints in your API use authentication.
|
||||
'enabled' => false,
|
||||
|
||||
// Set this to true if your API should be authenticated by default. If so, you must also set `enabled` (above) to true.
|
||||
// You can then use @unauthenticated or @authenticated on individual endpoints to change their status from the default.
|
||||
'default' => false,
|
||||
|
||||
// Where is the auth value meant to be sent in a request?
|
||||
// Options: query, body, basic, bearer, header (for custom header)
|
||||
'in' => 'bearer',
|
||||
|
||||
// The name of the auth parameter (e.g. token, key, apiKey) or header (e.g. Authorization, Api-Key).
|
||||
'name' => 'key',
|
||||
|
||||
// The value of the parameter to be used by Scribe to authenticate response calls.
|
||||
// This will NOT be included in the generated documentation. If empty, Scribe will use a random value.
|
||||
'use_value' => env('SCRIBE_AUTH_KEY'),
|
||||
|
||||
// Placeholder your users will see for the auth parameter in the example requests.
|
||||
// Set this to null if you want Scribe to use a random value as placeholder instead.
|
||||
'placeholder' => '{YOUR_AUTH_KEY}',
|
||||
|
||||
// Any extra authentication-related info for your users. Markdown and HTML are supported.
|
||||
'extra_info' => 'You can retrieve your token by visiting your dashboard and clicking <b>Generate API token</b>.',
|
||||
],
|
||||
|
||||
// Text to place in the "Introduction" section, right after the `description`. Markdown and HTML are supported.
|
||||
'intro_text' => <<<INTRO
|
||||
This documentation aims to provide all the information you need to work with our API.
|
||||
|
||||
<aside>As you scroll, you'll see code examples for working with the API in different programming languages in the dark area to the right (or as part of the content on mobile).
|
||||
You can switch the language used with the tabs at the top right (or from the nav menu at the top left on mobile).</aside>
|
||||
INTRO
|
||||
,
|
||||
|
||||
// Example requests for each endpoint will be shown in each of these languages.
|
||||
// Supported options are: bash, javascript, php, python
|
||||
// To add a language of your own, see https://scribe.knuckles.wtf/laravel/advanced/example-requests
|
||||
'example_languages' => [
|
||||
'bash',
|
||||
'javascript',
|
||||
],
|
||||
|
||||
// Generate a Postman collection (v2.1.0) in addition to HTML docs.
|
||||
// For 'static' docs, the collection will be generated to public/docs/collection.json.
|
||||
// For 'laravel' docs, it will be generated to storage/app/scribe/collection.json.
|
||||
// Setting `laravel.add_routes` to true (above) will also add a route for the collection.
|
||||
'postman' => [
|
||||
'enabled' => true,
|
||||
|
||||
'overrides' => [
|
||||
// 'info.version' => '2.0.0',
|
||||
],
|
||||
],
|
||||
|
||||
// Generate an OpenAPI spec (v3.0.1) in addition to docs webpage.
|
||||
// For 'static' docs, the collection will be generated to public/docs/openapi.yaml.
|
||||
// For 'laravel' docs, it will be generated to storage/app/scribe/openapi.yaml.
|
||||
// Setting `laravel.add_routes` to true (above) will also add a route for the spec.
|
||||
'openapi' => [
|
||||
'enabled' => true,
|
||||
|
||||
'overrides' => [
|
||||
// 'info.version' => '2.0.0',
|
||||
],
|
||||
],
|
||||
|
||||
'groups' => [
|
||||
// Endpoints which don't have a @group will be placed in this default group.
|
||||
'default' => 'Endpoints',
|
||||
|
||||
// By default, Scribe will sort groups alphabetically, and endpoints in the order their routes are defined.
|
||||
// You can override this by listing the groups, subgroups and endpoints here in the order you want them.
|
||||
// See https://scribe.knuckles.wtf/blog/laravel-v4#easier-sorting and https://scribe.knuckles.wtf/laravel/reference/config#order for details
|
||||
'order' => [],
|
||||
],
|
||||
|
||||
// Custom logo path. This will be used as the value of the src attribute for the <img> tag,
|
||||
// so make sure it points to an accessible URL or path. Set to false to not use a logo.
|
||||
// For example, if your logo is in public/img:
|
||||
// - 'logo' => '../img/logo.png' // for `static` type (output folder is public/docs)
|
||||
// - 'logo' => 'img/logo.png' // for `laravel` type
|
||||
'logo' => false,
|
||||
|
||||
// Customize the "Last updated" value displayed in the docs by specifying tokens and formats.
|
||||
// Examples:
|
||||
// - {date:F j Y} => March 28, 2022
|
||||
// - {git:short} => Short hash of the last Git commit
|
||||
// Available tokens are `{date:<format>}` and `{git:<format>}`.
|
||||
// The format you pass to `date` will be passed to PHP's `date()` function.
|
||||
// The format you pass to `git` can be either "short" or "long".
|
||||
'last_updated' => 'Last updated: {date:F j, Y}',
|
||||
|
||||
'examples' => [
|
||||
// Set this to any number (e.g. 1234) to generate the same example values for parameters on each run,
|
||||
'faker_seed' => null,
|
||||
|
||||
// With API resources and transformers, Scribe tries to generate example models to use in your API responses.
|
||||
// By default, Scribe will try the model's factory, and if that fails, try fetching the first from the database.
|
||||
// You can reorder or remove strategies here.
|
||||
'models_source' => ['factoryCreate', 'factoryMake', 'databaseFirst'],
|
||||
],
|
||||
|
||||
// The strategies Scribe will use to extract information about your routes at each stage.
|
||||
// If you create or install a custom strategy, add it here.
|
||||
'strategies' => [
|
||||
'metadata' => [
|
||||
Strategies\Metadata\GetFromDocBlocks::class,
|
||||
Strategies\Metadata\GetFromMetadataAttributes::class,
|
||||
],
|
||||
'urlParameters' => [
|
||||
Strategies\UrlParameters\GetFromLaravelAPI::class,
|
||||
Strategies\UrlParameters\GetFromUrlParamAttribute::class,
|
||||
Strategies\UrlParameters\GetFromUrlParamTag::class,
|
||||
],
|
||||
'queryParameters' => [
|
||||
Strategies\QueryParameters\GetFromFormRequest::class,
|
||||
Strategies\QueryParameters\GetFromInlineValidator::class,
|
||||
Strategies\QueryParameters\GetFromQueryParamAttribute::class,
|
||||
Strategies\QueryParameters\GetFromQueryParamTag::class,
|
||||
],
|
||||
'headers' => [
|
||||
Strategies\Headers\GetFromHeaderAttribute::class,
|
||||
Strategies\Headers\GetFromHeaderTag::class,
|
||||
[
|
||||
'override',
|
||||
[
|
||||
'Content-Type' => 'application/json',
|
||||
'Accept' => 'application/json',
|
||||
]
|
||||
]
|
||||
],
|
||||
'bodyParameters' => [
|
||||
Strategies\BodyParameters\GetFromFormRequest::class,
|
||||
Strategies\BodyParameters\GetFromInlineValidator::class,
|
||||
Strategies\BodyParameters\GetFromBodyParamAttribute::class,
|
||||
Strategies\BodyParameters\GetFromBodyParamTag::class,
|
||||
],
|
||||
'responses' => [
|
||||
Strategies\Responses\UseResponseAttributes::class,
|
||||
Strategies\Responses\UseTransformerTags::class,
|
||||
Strategies\Responses\UseApiResourceTags::class,
|
||||
Strategies\Responses\UseResponseTag::class,
|
||||
Strategies\Responses\UseResponseFileTag::class,
|
||||
[
|
||||
Strategies\Responses\ResponseCalls::class,
|
||||
[
|
||||
'only' => ['GET *'],
|
||||
// Disable debug mode when generating response calls to avoid error stack traces in responses
|
||||
'config' => [
|
||||
'app.debug' => false,
|
||||
],
|
||||
]
|
||||
]
|
||||
],
|
||||
'responseFields' => [
|
||||
Strategies\ResponseFields\GetFromResponseFieldAttribute::class,
|
||||
Strategies\ResponseFields\GetFromResponseFieldTag::class,
|
||||
],
|
||||
],
|
||||
|
||||
// For response calls, API resource responses and transformer responses,
|
||||
// Scribe will try to start database transactions, so no changes are persisted to your database.
|
||||
// Tell Scribe which connections should be transacted here. If you only use one db connection, you can leave this as is.
|
||||
'database_connections_to_transact' => [config('database.default')],
|
||||
|
||||
'fractal' => [
|
||||
// If you are using a custom serializer with league/fractal, you can specify it here.
|
||||
'serializer' => null,
|
||||
],
|
||||
|
||||
'routeMatcher' => \Knuckles\Scribe\Matching\RouteMatcher::class,
|
||||
];
|
41
phpunit.xml
41
phpunit.xml
@ -1,41 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
bootstrap="vendor/autoload.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false">
|
||||
<testsuites>
|
||||
<testsuite name="Unit">
|
||||
<directory suffix="Test.php">./tests/Unit</directory>
|
||||
</testsuite>
|
||||
|
||||
<testsuite name="Feature">
|
||||
<directory suffix="Test.php">./tests/Feature</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<whitelist processUncoveredFilesFromWhitelist="true">
|
||||
<directory suffix=".php">./app</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
<extensions>
|
||||
<extension class="Tests\Bootstrap"/>
|
||||
</extensions>
|
||||
<php>
|
||||
<server name="APP_ENV" value="testing"/>
|
||||
<server name="BCRYPT_ROUNDS" value="4"/>
|
||||
<server name="CACHE_DRIVER" value="array"/>
|
||||
<server name="MAIL_DRIVER" value="array"/>
|
||||
<server name="QUEUE_CONNECTION" value="sync"/>
|
||||
<server name="SESSION_DRIVER" value="array"/>
|
||||
<server name="APP_CONFIG_CACHE" value="bootstrap/cache/config.phpunit.php"/>
|
||||
<server name="APP_SERVICES_CACHE" value="bootstrap/cache/services.phpunit.php"/>
|
||||
<server name="APP_PACKAGES_CACHE" value="bootstrap/cache/packages.phpunit.php"/>
|
||||
<server name="APP_ROUTES_CACHE" value="bootstrap/cache/routes.phpunit.php"/>
|
||||
<server name="APP_EVENTS_CACHE" value="bootstrap/cache/events.phpunit.php"/>
|
||||
</php>
|
||||
</phpunit>
|
Loading…
Reference in New Issue
Block a user