1
0
mirror of https://github.com/Kovah/LinkAce.git synced 2025-04-21 23:42:10 +02:00

Update packages, fix merge issues and tests

This commit is contained in:
Kovah 2023-09-28 20:50:48 +02:00
parent c084752b95
commit f0421b7222
No known key found for this signature in database
GPG Key ID: AAAA031BA9830D7B
21 changed files with 1655 additions and 1191 deletions

View File

@ -47,7 +47,7 @@ class ImportHtmlBookmarks
'url' => $link['url'],
'title' => $title,
'description' => $description,
'icon' => LinkIconMapper::getIconForUrl($link['uri']),
'icon' => LinkIconMapper::getIconForUrl($link['url']),
'is_private' => usersettings('tags_private_default') === '1' ? true : $isPublic,
]);
$newLink->created_at = Carbon::createFromTimestamp($link['dateCreated']);

View File

@ -3,38 +3,39 @@
namespace App\Http\Controllers\Guest;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Traits\HandlesQueryOrder;
use App\Http\Controllers\Traits\ChecksOrdering;
use App\Models\Link;
use Illuminate\Contracts\View\View;
use Illuminate\Http\Request;
class LinkController extends Controller
{
use HandlesQueryOrder;
use ChecksOrdering;
public function __construct()
{
$this->allowedOrderBy = Link::$allowOrderBy;
}
/**
* Display an overview of all links.
*
* @param Request $request
* @return View
*/
public function index(Request $request): View
{
$links = Link::publicOnly()->with(['tags' => fn ($query) => $query->publicOnly()]);
$orderBy = $request->input('orderBy', 'created_at');
$orderDir = $this->getOrderDirection($request);
if ($orderBy === 'random') {
$this->orderBy = $request->input('orderBy', 'created_at');
$this->orderDir = $request->input('orderBy', 'desc');
$this->checkOrdering();
if ($this->orderBy === 'random') {
$links->inRandomOrder();
} else {
$links->orderBy($orderBy, $orderDir);
$links->orderBy($this->orderBy, $this->orderDir);
}
return view('guest.links.index', [
'links' => $links->paginate(getPaginationLimit()),
'route' => $request->getBaseUrl(),
'orderBy' => $request->input('orderBy', 'created_at'),
'orderDir' => $request->input('orderDir', 'desc'),
'orderBy' => $this->orderBy,
'orderDir' => $this->orderDir,
]);
}
}

View File

@ -3,29 +3,35 @@
namespace App\Http\Controllers\Guest;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Traits\HandlesQueryOrder;
use App\Http\Controllers\Traits\ChecksOrdering;
use App\Models\LinkList;
use Illuminate\Contracts\View\View;
use Illuminate\Http\Request;
class ListController extends Controller
{
use HandlesQueryOrder;
use ChecksOrdering;
public function __construct()
{
$this->allowedOrderBy = LinkList::$allowOrderBy;
}
public function index(Request $request): View
{
$this->orderBy = $request->input('orderBy', 'created_at');
$this->orderDir = $request->input('orderBy', 'desc');
$this->checkOrdering();
$lists = LinkList::publicOnly()
->withCount(['links' => fn ($query) => $query->publicOnly()])
->orderBy(
$request->input('orderBy', 'name'),
$this->getOrderDirection($request, 'asc')
)
->withCount(['links' => fn($query) => $query->publicOnly()])
->orderBy($this->orderBy, $this->orderDir)
->paginate(getPaginationLimit());
return view('guest.lists.index', [
'lists' => $lists,
'orderBy' => $request->input('orderBy', 'name'),
'orderDir' => $this->getOrderDirection($request, 'asc'),
'orderBy' => $this->orderBy,
'orderDir' => $this->orderDir,
]);
}
@ -33,19 +39,21 @@ class ListController extends Controller
{
$list = LinkList::publicOnly()->findOrFail($listID);
$this->orderBy = $request->input('orderBy', 'created_at');
$this->orderDir = $request->input('orderBy', 'desc');
$this->checkOrdering();
$links = $list->links()
->publicOnly()
->orderBy(
$request->input('orderBy', 'title'),
$this->getOrderDirection($request, 'asc')
)->paginate(getPaginationLimit());
->orderBy($this->orderBy, $this->orderDir)
->paginate(getPaginationLimit());
return view('guest.lists.show', [
'list' => $list,
'listLinks' => $links,
'route' => $request->getBaseUrl(),
'orderBy' => $request->input('orderBy', 'title'),
'orderDir' => $this->getOrderDirection($request, 'asc'),
'orderBy' => $this->orderBy,
'orderDir' => $this->orderDir,
]);
}
}

View File

@ -3,6 +3,7 @@
namespace App\Http\Controllers\Guest;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Traits\ChecksOrdering;
use App\Http\Controllers\Traits\HandlesQueryOrder;
use App\Models\Tag;
use Illuminate\Contracts\View\View;
@ -10,43 +11,51 @@ use Illuminate\Http\Request;
class TagController extends Controller
{
use HandlesQueryOrder;
use ChecksOrdering;
public function __construct()
{
$this->allowedOrderBy = Tag::$allowOrderBy;
}
public function index(Request $request): View
{
$this->orderBy = $request->input('orderBy', 'created_at');
$this->orderDir = $request->input('orderBy', 'desc');
$this->checkOrdering();
$tags = Tag::publicOnly()
->withCount(['links' => fn ($query) => $query->publicOnly()])
->orderBy(
$request->input('orderBy', 'name'),
$this->getOrderDirection($request, 'asc')
)
->orderBy($this->orderBy, $this->orderDir)
->paginate(getPaginationLimit());
return view('guest.tags.index', [
'tags' => $tags,
'route' => $request->getBaseUrl(),
'orderBy' => $request->input('orderBy', 'name'),
'orderDir' => $this->getOrderDirection($request, 'asc'),
'orderBy' => $this->orderBy,
'orderDir' => $this->orderDir,
]);
}
public function show(Request $request, int $tagID): View
{
$this->orderBy = $request->input('orderBy', 'created_at');
$this->orderDir = $request->input('orderBy', 'desc');
$this->checkOrdering();
$tag = Tag::publicOnly()->findOrFail($tagID);
$links = $tag->links()
->publicOnly()
->orderBy(
$request->input('orderBy', 'title'),
$request->input('orderDir', 'asc')
)->paginate(getPaginationLimit());
->orderBy($this->orderBy, $this->orderDir)
->paginate(getPaginationLimit());
return view('guest.tags.show', [
'tag' => $tag,
'tagLinks' => $links,
'route' => $request->getBaseUrl(),
'orderBy' => $request->input('orderBy', 'title'),
'orderDir' => $request->input('orderDir', 'asc'),
'orderBy' => $this->orderBy,
'orderDir' => $this->orderDir,
]);
}
}

View File

@ -17,7 +17,6 @@ use Illuminate\Http\Request;
class LinkController extends Controller
{
use ChecksOrdering;
use HandlesQueryOrder;
public function __construct()
{
@ -27,9 +26,8 @@ class LinkController extends Controller
public function index(Request $request): View
{
$orderBy = $request->input('orderBy', session()->get('links.index.orderBy', 'created_at'));
$orderDir = $this->getOrderDirection($request, session()->get('links.index.orderDir', 'desc'));
$this->orderBy = $request->input('orderBy', session()->get('links.index.orderBy', 'created_at'));
$this->orderDir = $request->input('orderDir', session()->get('links.index.orderDir', 'desc'));
$this->checkOrdering();
session()->put('links.index.orderBy', $this->orderBy);
@ -39,10 +37,10 @@ class LinkController extends Controller
->visibleForUser()
->with('tags');
if ($orderBy === 'random') {
if ($this->orderBy === 'random') {
$links->inRandomOrder();
} else {
$links->orderBy($orderBy, $orderDir);
$links->orderBy($this->orderBy, $this->orderDir);
}
return view('models.links.index', [

View File

@ -4,7 +4,6 @@ namespace App\Http\Controllers\Models;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Traits\ChecksOrdering;
use App\Http\Controllers\Traits\HandlesQueryOrder;
use App\Http\Requests\Models\ListStoreRequest;
use App\Http\Requests\Models\ListUpdateRequest;
use App\Models\LinkList;
@ -16,7 +15,6 @@ use Illuminate\Http\Request;
class ListController extends Controller
{
use ChecksOrdering;
use HandlesQueryOrder;
public function __construct()
{
@ -26,12 +24,12 @@ class ListController extends Controller
public function index(Request $request): View
{
$orderBy = $request->input('orderBy', session()->get('lists.index.orderBy', 'name'));
$orderDir = $this->getOrderDirection($request, session()->get('lists.index.orderDir', 'asc'));
$this->orderBy = $request->input('orderBy', session()->get('lists.index.orderBy', 'name'));
$this->orderDir = $request->input('orderDir', session()->get('lists.index.orderDir', 'asc'));
$this->checkOrdering();
session()->put('lists.index.orderBy', $orderBy);
session()->put('lists.index.orderDir', $orderDir);
session()->put('lists.index.orderBy', $this->orderBy);
session()->put('lists.index.orderDir', $this->orderDir);
$lists = LinkList::query()
->visibleForUser()
@ -74,20 +72,22 @@ class ListController extends Controller
public function show(Request $request, LinkList $list): View
{
$this->orderBy = $request->input('orderBy', 'created_at');
$this->orderDir = $request->input('orderBy', 'desc');
$this->checkOrdering();
$links = $list->links()
->byUser()
->orderBy(
$request->input('orderBy', 'created_at'),
$request->input('orderDir', 'desc')
)->paginate(getPaginationLimit());
->orderBy($this->orderBy, $this->orderDir)
->paginate(getPaginationLimit());
return view('models.lists.show', [
'list' => $list,
'history' => $list->audits()->latest()->get(),
'listLinks' => $links,
'route' => $request->getBaseUrl(),
'orderBy' => $request->input('orderBy', 'created_at'),
'orderDir' => $request->input('orderDir', 'desc'),
'orderBy' => $this->orderBy,
'orderDir' => $this->orderDir,
]);
}

View File

@ -27,9 +27,8 @@ class TagController extends Controller
public function index(Request $request): View
{
$orderBy = $request->input('orderBy', session()->get('tags.index.orderBy', 'name'));
$orderDir = $this->getOrderDirection($request, session()->get('tags.index.orderDir', 'asc'));
$this->orderBy = $request->input('orderBy', session()->get('tags.index.orderBy', 'name'));
$this->orderDir = $request->input('orderDir', session()->get('tags.index.orderDir', 'asc'));
$this->checkOrdering();
session()->put('tags.index.orderBy', $this->orderBy);
@ -77,11 +76,11 @@ class TagController extends Controller
{
$this->allowedOrderBy = Link::$allowOrderBy;
$this->orderBy = $request->input('orderBy', 'created_at');
$this->orderDir = $this->getOrderDirection($request);
$this->orderDir = $request->input('orderBy', 'desc');
$this->checkOrdering();
$links = $tag->links()->visibleForUser()
$links = $tag->links()
->visibleForUser()
->orderBy($this->orderBy, $this->orderDir)
->paginate(getPaginationLimit());
@ -90,8 +89,8 @@ class TagController extends Controller
'history' => $tag->audits()->latest()->get(),
'tagLinks' => $links,
'route' => $request->getBaseUrl(),
'orderBy' => $request->input('orderBy', 'created_at'),
'orderDir' => $this->getOrderDirection($request),
'orderBy' => $this->orderBy,
'orderDir' => $this->orderDir,
]);
}

View File

@ -7,6 +7,7 @@ use App\Audits\Modifiers\LinkStatusModifier;
use App\Audits\Modifiers\ListRelationModifier;
use App\Audits\Modifiers\TagRelationModifier;
use App\Audits\Modifiers\VisibilityModifier;
use App\Enums\ModelAttribute;
use App\Jobs\SaveLinkToWaybackmachine;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
@ -86,6 +87,7 @@ class Link extends Model implements Auditable
'check_disabled',
'created_at',
'updated_at',
'random',
];
public string $langBase = 'link';
@ -244,11 +246,13 @@ class Link extends Model implements Auditable
*/
public function initiateInternetArchiveBackup(): void
{
if (usersettings('archive_backups_enabled') === '0') {
if (usersettings('archive_backups_enabled') === false) {
return;
}
if ($this->is_private && usersettings('archive_private_backups_enabled') === '0') {
if ($this->visibility === ModelAttribute::VISIBILITY_PRIVATE
&& usersettings('archive_private_backups_enabled') === false
) {
return;
}

View File

@ -64,6 +64,7 @@ class LinkList extends Model implements Auditable
'visibility',
'created_at',
'updated_at',
'random',
];
public string $langBase = 'list';

View File

@ -59,6 +59,7 @@ class Tag extends Model implements Auditable
'visibility',
'created_at',
'updated_at',
'random',
];
public string $langBase = 'tag';

View File

@ -6,25 +6,25 @@
"require": {
"php": "^8.0 | ^8.1 | ^8.2",
"ext-pdo": "*",
"composer/semver": "^1.5",
"doctrine/dbal": "^3.3.5",
"composer/semver": "^3.3.1",
"doctrine/dbal": "^3.7.0",
"guzzlehttp/guzzle": "^7.0.1",
"kovah/laravel-html-meta": "^2.0",
"laracasts/flash": "^3.1",
"laravel/fortify": "^1.7",
"laravel/framework": "^9.0",
"laravel/sanctum": "^2.15",
"laravel/sanctum": "^v3.3.1",
"league/csv": "^9.6",
"league/flysystem-aws-s3-v3": "^3.0.13",
"owen-it/laravel-auditing": "^13.0",
"predis/predis": "^1.1",
"predis/predis": "^v2.2",
"rap2hpoutre/laravel-log-viewer": "^2.2",
"sentry/sentry-laravel": "^2.3",
"shaarli/netscape-bookmark-parser": "^v3.2",
"sentry/sentry-laravel": "^3.8.0",
"shaarli/netscape-bookmark-parser": "^v4.0.0",
"spatie/laravel-activitylog": "^4.5",
"spatie/laravel-backup": "^8.1.2",
"spatie/laravel-permission": "^5.5",
"spatie/laravel-settings": "^2.4",
"spatie/laravel-settings": "^2.7.0",
"symfony/http-client": "^6.0",
"symfony/mailgun-mailer": "^6.0"
},
@ -79,7 +79,10 @@
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true
"sort-packages": true,
"allow-plugins": {
"php-http/discovery": true
}
},
"minimum-stability": "dev",
"prefer-stable": true

2582
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -4,33 +4,30 @@ use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePersonalAccessTokensTable extends Migration
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
public function up(): void
{
Schema::create('personal_access_tokens', function (Blueprint $table) {
$table->bigIncrements('id');
$table->id();
$table->morphs('tokenable');
$table->string('name');
$table->string('token', 64)->unique();
$table->text('abilities')->nullable();
$table->timestamp('last_used_at')->nullable();
$table->timestamp('expires_at')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
public function down(): void
{
Schema::dropIfExists('personal_access_tokens');
}
}
};

View File

@ -15,7 +15,7 @@ class CreateSettingsTable extends Migration
$table->string('group')->index();
$table->string('name');
$table->boolean('locked');
$table->boolean('locked')->default(false);
$table->json('payload');
$table->timestamps();

Binary file not shown.

View File

@ -21,7 +21,7 @@ CREATE INDEX "jobs_queue_index" on "jobs" ("queue");
CREATE TABLE IF NOT EXISTS "failed_jobs" ("id" integer not null primary key autoincrement, "connection" text not null, "queue" text not null, "payload" text not null, "exception" text not null, "failed_at" datetime default CURRENT_TIMESTAMP not null);
CREATE TABLE IF NOT EXISTS "lists" (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, user_id INTEGER NOT NULL, name CLOB NOT NULL COLLATE BINARY, description CLOB DEFAULT NULL COLLATE BINARY, is_private BOOLEAN DEFAULT 0 NOT NULL, created_at DATETIME DEFAULT NULL, updated_at DATETIME DEFAULT NULL, deleted_at DATETIME DEFAULT NULL);
CREATE TABLE IF NOT EXISTS "link_lists" ("link_id" integer not null, "list_id" integer not null, primary key ("link_id", "list_id"));
CREATE TABLE IF NOT EXISTS "personal_access_tokens" ("id" integer not null primary key autoincrement, "tokenable_type" varchar not null, "tokenable_id" integer not null, "name" varchar not null, "token" varchar not null, "abilities" text, "last_used_at" datetime, "created_at" datetime, "updated_at" datetime);
CREATE TABLE IF NOT EXISTS "personal_access_tokens" ("id" integer not null primary key autoincrement, "tokenable_type" varchar not null, "tokenable_id" integer not null, "name" varchar not null, "token" varchar not null, "abilities" text, "last_used_at" datetime, "expires_at" datetime, "created_at" datetime, "updated_at" datetime);
CREATE INDEX "personal_access_tokens_tokenable_type_tokenable_id_index" on "personal_access_tokens" ("tokenable_type", "tokenable_id");
CREATE UNIQUE INDEX "personal_access_tokens_token_unique" on "personal_access_tokens" ("token");
CREATE TABLE links (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, user_id INTEGER NOT NULL, url CLOB NOT NULL COLLATE BINARY, title CLOB NOT NULL COLLATE BINARY, description CLOB DEFAULT NULL COLLATE BINARY, is_private BOOLEAN DEFAULT 0 NOT NULL, created_at DATETIME DEFAULT NULL, updated_at DATETIME DEFAULT NULL, deleted_at DATETIME DEFAULT NULL, icon VARCHAR(255) DEFAULT NULL COLLATE BINARY, status INTEGER DEFAULT 1 NOT NULL, check_disabled BOOLEAN DEFAULT 0 NOT NULL, thumbnail CLOB DEFAULT NULL COLLATE BINARY);

View File

@ -46,8 +46,8 @@ class LinkApiTest extends ApiTestCase
->assertOk()
->assertJson([
'data' => [
['url' => 'https://public-link.com'],
['url' => 'https://internal-link.com'],
['url' => 'https://public-link.com'],
],
])
->assertJsonMissing([
@ -75,8 +75,8 @@ class LinkApiTest extends ApiTestCase
->assertOk()
->assertJson([
'data' => [
['url' => 'https://public-link.com'],
['url' => 'https://internal-link.com'],
['url' => 'https://public-link.com'],
],
])
->assertJsonMissing([
@ -95,9 +95,9 @@ class LinkApiTest extends ApiTestCase
->assertOk()
->assertJson([
'data' => [
['url' => 'https://public-link.com'],
['url' => 'https://internal-link.com'],
['url' => 'https://private-link.com'],
['url' => 'https://internal-link.com'],
['url' => 'https://public-link.com'],
],
]);
}

View File

@ -51,19 +51,19 @@ class LinkControllerTest extends TestCase
->assertDontSee('https://private-link.com');
$this->flushSession();
$this->get('links?orderBy=created_at&orderDir=asc')
$this->get('links?orderBy=created_at&orderDir=desc')
->assertOk()
->assertSeeInOrder([
'https://linkace.example.com/test',
'https://the-new-linkace.com',
'https://internal-link.com',
'https://public-link.com',
]);
$this->flushSession();
$this->get('links?orderBy=created_at&orderDir=wrong-asc')
->assertOk()
->assertSeeInOrder([
'https://the-new-linkace.com',
'https://linkace.example.com/test',
'https://public-link.com',
'https://internal-link.com',
]);
}
@ -233,7 +233,7 @@ class LinkControllerTest extends TestCase
'description' => null,
'lists' => null,
'tags' => null,
'visibility' => 1,
'visibility' => 3,
]);
Queue::assertNotPushed(SaveLinkToWaybackmachine::class);

View File

@ -38,16 +38,16 @@ class ListControllerTest extends TestCase
$this->get('lists?orderBy=created_at&orderDir=desc')
->assertOk()
->assertSeeInOrder([
'Super New List',
'A Test List',
'Internal List',
'Public List',
]);
$this->flushSession();
$this->get('lists?orderBy=created_at&orderDir=wrong-desc')
->assertOk()
->assertSeeInOrder([
'A Test List',
'Super New List',
'Public List',
'Internal List',
]);
}

View File

@ -28,22 +28,26 @@ class TagControllerTest extends TestCase
{
$this->createTestTags();
$this->get('tags')->assertOk()->assertSee('Public Tag')->assertSee('Internal Tag')->assertDontSee('Private Tag');
$this->get('tags')
->assertOk()
->assertSee('Public Tag')
->assertSee('Internal Tag')
->assertDontSee('Private Tag');
$this->flushSession();
$this->get('tags?orderBy=created_at&orderDir=desc')
->assertOk()
->assertSeeInOrder([
'new-tag',
'a-tag',
'Internal Tag',
'Public Tag',
]);
$this->flushSession();
$this->get('tags?orderBy=created_at&orderDir=wrong-desc')
->assertOk()
->assertSeeInOrder([
'a-tag',
'new-tag',
'Public Tag',
'Internal Tag',
]);
}

View File

@ -15,16 +15,21 @@ trait PreparesTestData
{
$otherUser ??= User::factory()->create();
$link = Link::factory()->create(['url' => 'https://public-link.com']);
$link = Link::factory()->create([
'url' => 'https://public-link.com',
'created_at' => now()->subDay(),
]);
$link2 = Link::factory()->create([
'url' => 'https://internal-link.com',
'user_id' => $otherUser->id,
'visibility' => ModelAttribute::VISIBILITY_INTERNAL,
'created_at' => now()->subHour(),
]);
$link3 = Link::factory()->create([
'url' => 'https://private-link.com',
'user_id' => $otherUser->id,
'visibility' => ModelAttribute::VISIBILITY_PRIVATE,
'created_at' => now()->subMinute(),
]);
return [$link, $link2, $link3];
@ -34,16 +39,21 @@ trait PreparesTestData
{
$otherUser ??= User::factory()->create();
$list = LinkList::factory()->create(['name' => 'Public List']);
$list = LinkList::factory()->create([
'name' => 'Public List',
'created_at' => now()->subDay(),
]);
$list2 = LinkList::factory()->create([
'name' => 'Internal List',
'user_id' => $otherUser->id,
'visibility' => ModelAttribute::VISIBILITY_INTERNAL,
'created_at' => now()->subHour(),
]);
$list3 = LinkList::factory()->create([
'name' => 'Private List',
'user_id' => $otherUser->id,
'visibility' => ModelAttribute::VISIBILITY_PRIVATE,
'created_at' => now()->subMinute(),
]);
return [$list, $list2, $list3];
@ -53,16 +63,21 @@ trait PreparesTestData
{
$otherUser ??= User::factory()->create();
$tag1 = Tag::factory()->create(['name' => 'Public Tag']);
$tag1 = Tag::factory()->create([
'name' => 'Public Tag',
'created_at' => now()->subDay(),
]);
$tag2 = Tag::factory()->create([
'name' => 'Internal Tag',
'user_id' => $otherUser->id,
'visibility' => ModelAttribute::VISIBILITY_INTERNAL,
'created_at' => now()->subHour(),
]);
$tag3 = Tag::factory()->create([
'name' => 'Private Tag',
'user_id' => $otherUser->id,
'visibility' => ModelAttribute::VISIBILITY_PRIVATE,
'created_at' => now()->subMinute(),
]);
return [$tag1, $tag2, $tag3];