Skip to content

Commit

Permalink
big wip. Update the ssh service so it works properly again. Update cr…
Browse files Browse the repository at this point in the history
…ud view. add pulse and telescope. Rework the design for navigation. add several new pages
  • Loading branch information
austinkregel committed Jun 3, 2024
1 parent d70ff4e commit 522d544
Show file tree
Hide file tree
Showing 71 changed files with 1,796 additions and 590 deletions.
28 changes: 28 additions & 0 deletions app/Console/Commands/BulkScoutImport.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace App\Console\Commands;

use App\Services\Code;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Artisan;
use Laravel\Scout\Searchable;
use Spatie\Activitylog\Traits\LogsActivity;

class BulkScoutImport extends Command
{
protected $signature = 'app:bulk-scout-import';

protected $description = 'Command description';

public function handle()
{
$searchableModels = Code::instancesOf(Searchable::class)
->getClasses();

foreach($searchableModels as $model) {
Artisan::call('scout:import', [
'model' => $model,
]);
}
}
}
54 changes: 54 additions & 0 deletions app/Console/Commands/Initialize.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace App\Console\Commands;

use App\Models\Credential;
use App\Models\User;
use App\Services\SshKeyGeneratorService;
use Illuminate\Console\Command;
use Illuminate\Support\Str;

class Initialize extends Command
{
protected $signature = 'app:initialize';

protected $description = 'Initialize the application';
public function handle()
{
if (Credential::where('type', Credential::TYPE_SSH)->exists()) {
$this->info('SSH key already exists');
return;
}

if (! User::exists()) {
$this->call('make:user');
}

$randomName = Str::random(16);
$passKey = Str::random(16);

[$privateKey, $publicKey] = SshKeyGeneratorService::generate($passKey);

$publicKeyFile = storage_path('app/keys/'.$randomName.'.pub');
$privateKeyFile = storage_path('app/keys/'.$randomName);

file_put_contents($publicKeyFile, $publicKey);
chmod($publicKeyFile, 0600);
file_put_contents($privateKeyFile, $privateKey);
chmod($privateKeyFile, 0600);

Credential::create([
'service' => Credential::TYPE_SSH,
'type' => Credential::TYPE_SSH,
'name' => 'SSH',
'user_id' => User::first()->id,
'settings' => [
'pub_key' => $publicKey,
'pub_key_file' => $publicKeyFile,
'private_key' => $privateKey,
'private_key_file' => $privateKeyFile,
'pass_key' => !empty($passKey) ? encrypt($passKey) : '',
],
]);
}
}
5 changes: 5 additions & 0 deletions app/Http/Controllers/AdminController.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,9 @@ public function email()
'mail' => '',
]);
}

public function index()
{
return
}
}
83 changes: 83 additions & 0 deletions app/Http/Controllers/Spork/BatchJobController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

namespace App\Http\Controllers\Spork;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Inertia\Inertia;
use Kregel\ExceptionProbe\Stacktrace;

class BatchJobController extends Controller
{
public function index()
{
$batches = \DB::table('job_batches')
->select('*')
->orderByDesc('created_at')
->paginate();

$paginator = new LengthAwarePaginator(
array_map(function ($batch) {
$batch->jobs = \DB::table('failed_jobs')
->select('*')
->whereIn('uuid', json_decode($batch->failed_job_ids, true))
->orderByDesc('failed_at')
->get()
->map(function ($job) {
$job->parsed_exception = (new Stacktrace)->parse($job->exception);
$job->payload = json_decode($job->payload, true);

return $job;
});
$batch->failed_at = $batch->jobs->max('failed_at');

return $batch;
}, $batches->items()),
$batches->total(),
$batches->perPage(),
$batches->currentPage()
);

return Inertia::render('Admin/BatchJob/Index', [
'title' => 'Batch Jobs',
'paginator' => $paginator,
]);
}

public function show(Request $request, $batch)
{
$batches = \DB::table('job_batches')
->select('*')
->orderByDesc('created_at')
->where('id', $batch)
->paginate();

$paginator = new LengthAwarePaginator(
array_map(function ($batch) {
$batch->jobs = \DB::table('failed_jobs')
->select('*')
->whereIn('uuid', json_decode($batch->failed_job_ids, true))
->orderByDesc('failed_at')
->get()
->map(function ($job) {
$job->parsed_exception = (new Stacktrace)->parse($job->exception);
$job->payload = json_decode($job->payload, true);

return $job;
});
$batch->failed_at = $batch->jobs->max('failed_at');

return $batch;
}, $batches->items()),
$batches->total(),
$batches->perPage(),
$batches->currentPage()
);

return Inertia::render('Admin/BatchJob/Show', [
'title' => 'Batch Jobs',
'paginator' => $paginator,
]);
}
}
23 changes: 16 additions & 7 deletions app/Http/Controllers/Spork/DashboardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,27 @@
use App\Models\Person;
use App\Models\User;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Inertia\Inertia;

class DashboardController extends Controller
{
public function __invoke()
{
$person = Person::whereJsonContains('emails', auth()->user()->email)
// for now, this is fine, my email base does support this idea, but I know if someone/
// wanted to be malicious they could take advantage of this.
->first();
$person = auth()->user()->person();
$batchJobs = JobBatch::query()
->orderByDesc('created_at')
->paginate(request('job_limit', 10), ['*'], 'job_page', request('job_page', 1));

$batchJobs->setCollection(
Collection::make(array_map(function ($batchJob) {
$batchJob->failed_at = \DB::table('failed_jobs')
->selectRaw('max(failed_at)')
->whereIn('id', $batchJob->failed_job_ids)
->value('failed_at');
return $batchJob;
}, $batchJobs->items()))
);

return Inertia::render('Dashboard', [
'accounts' => auth()->user()->accounts()
Expand Down Expand Up @@ -55,9 +66,7 @@ public function __invoke()
->where('expires_at', '<=', now()->addWeeks(4))
->orderByDesc('expires_at')
->paginate(request('expiring_limit', 15), ['*'], 'expiring_page', request('expiring_page', 1)),
'job_batches' => JobBatch::query()
->orderByDesc('created_at')
->paginate(request('job_limit', 10), ['*'], 'job_page', request('job_page', 1)),
'job_batches' => $batchJobs,
]);
}
}
8 changes: 8 additions & 0 deletions app/Http/Controllers/Spork/DevelopmentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@

namespace App\Http\Controllers\Spork;

use Inertia\Inertia;

class DevelopmentController
{
public function index()
{
return Inertia::render('Development/Index', [
// 'instances' => LaravelProgrammingStyle::instancesOf(CustomAction::class),
]);
}
}
2 changes: 2 additions & 0 deletions app/Http/Controllers/Spork/FileManagerController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace App\Http\Controllers\Spork;

use Inertia\Inertia;

class FileManagerController
{
public function __invoke()
Expand Down
4 changes: 2 additions & 2 deletions app/Http/Controllers/Spork/InboxController.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ public function index()

public function show(Message $message)
{
abort_if($message->type !== 'email', 404);
abort_if($message->type !== 'email', 405);

$message->load('credential');

abort_unless($message->credential->user_id === auth()->id(), 404);
abort_unless($message->credential->user_id === auth()->id(), 4035);

$message = (new ImapCredentialService($message->credential))->findMessage($message->event_id, true);
$messageBody = base64_decode($message['body']);
Expand Down
8 changes: 8 additions & 0 deletions app/Http/Controllers/Spork/ManageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use App\Services\Development\DescribeTableService;
use Illuminate\Support\Str;
use Inertia\Inertia;
use Spatie\Activitylog\Models\Activity;

class ManageController
{
Expand All @@ -17,6 +18,13 @@ public function index()
'description' => [
'fillable' => [],
],
'metrics' => Activity::latest()
->paginate(
request('limit', 15),
['*'],
'manage_page',
request('manage_page', 1)
),
]);
}

Expand Down
8 changes: 7 additions & 1 deletion app/Jobs/News/UpdateFeed.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,17 @@ public function handle(\App\Services\News\RssFeedService $service): void
/** @var AbstractFeed $rssFeed */
$rssFeed = $service->fetchRssFeed($this->feed->url);

if (empty($rssFeed)) {
return;
}

/** @var FeedItem $feedItem */
foreach ($rssFeed->getData() as $feedItem) {
// If we already have the item's GUID, we must already have this item so we should stop,
// as any items afterwards are probably already in our system as well.
if ($this->feed->articles()->where('external_guid', $feedItem->getUuidIfExists())->exists()) {
if ($this->feed->articles()
->where('external_guid', $feedItem->getUuidIfExists() ?? $feedItem->getUrl())
->exists()) {
break;
}

Expand Down
2 changes: 1 addition & 1 deletion app/Jobs/Registrar/CloudflareSyncJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function sync(): void

foreach ($data as $key => $value) {
if ($localDomain->$key instanceof Carbon || $value instanceof Carbon) {
if ($value instanceof Carbon && ! $value->equalTo($localDomain->$key)) {
if ($value instanceof Carbon && (is_null($localDomain->$key) || ! $value->equalTo($localDomain->$key))) {
$localDomain->$key = $value;
} elseif ($localDomain->$key instanceof Carbon && ! $localDomain->$key->equalTo($value)) {
$localDomain->$key = $value;
Expand Down
9 changes: 6 additions & 3 deletions app/Jobs/Registrar/NamecheapSyncJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,24 @@ public function sync(): void
$domains = $this->service->getDomains(100, $page++);

foreach ($domains as $domain) {
$localDomain = Domain::where('credential_id', $this->credential->id)
->where('domain_id', $domain['id'])
$localDomain = Domain::query()
->withoutGlobalScope('active')
->where('credential_id', $this->credential->id)
->where('name', $domain['domain'])
->first();

$data = [
'name' => $domain['domain'],
'domain_id' => $domain['id'],
'registered_at' => $domain['created_at'],
'expires_at' => $domain['expires_at'],
'verification_key' => 'reforged_'.Str::random(48),
];

if (empty($localDomain)) {
$localDomain = new Domain;
$localDomain->credential_id = $this->credential->id;
$localDomain->verification_key = 'reforged_'.Str::random(48);

}

foreach ($data as $key => $value) {
Expand Down
5 changes: 4 additions & 1 deletion app/Models/Article.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Laravel\Scout\Searchable;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\LogsActivity;

class Article extends Model implements Crud
{
use HasFactory;
use Searchable;
use LogsActivity;
use ScopeQSearch;
use ScopeRelativeSearch;
Expand Down Expand Up @@ -65,7 +67,7 @@ public static function fromFeedItem(ExternalRssFeed $feed, FeedItem $item): self
$post = new Article();
// If the item's GUID is a v4 UUID, we may as well use it as our UUID.
$post->uuid = $item->getUuidIfExists();
$post->external_guid = $item->getExternalId();
$post->external_guid = $item->getUuidIfExists() ?? $item->getUrl();
$post->author_id = $feed->id;
$post->author_type = get_class($feed);
$post->headline = $item->getTitle();
Expand Down Expand Up @@ -95,6 +97,7 @@ public function getActivitylogOptions(): LogOptions
->logOnly(['headline', 'content', 'attachment', 'url'])
->useLogName('article')
->logFillable()
->dontSubmitEmptyLogs()
->logOnlyDirty();
}
}
3 changes: 2 additions & 1 deletion app/Models/Credential.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ class Credential extends Model implements Crud, ModelQuery
public $fillable = [
'name',
'type',
'user_id',
'service',
'api_key',
'secret_key',
Expand Down Expand Up @@ -160,7 +161,7 @@ public function getPrivateKey(): string

public function getPasskey(): string
{
return decrypt($this->settings['pass_key'] ?? '');
return empty($this->settings['pass_key'] ?? '') ? '': decrypt($this->settings['pass_key'] ?? '');
}

public function getActivitylogOptions(): LogOptions
Expand Down
Loading

0 comments on commit 522d544

Please sign in to comment.