Skip to content

Commit a09556e

Browse files
committed
♻️ rewrite webhook settings in vue; api improvements
fixes #2888 fixes #2889
1 parent f73ae81 commit a09556e

File tree

14 files changed

+169
-172
lines changed

14 files changed

+169
-172
lines changed

app/Http/Controllers/API/v1/WebhookController.php

Lines changed: 21 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ class WebhookController extends Controller
1818
* path="/webhooks",
1919
* operationId="getWebhooks",
2020
* tags={"Webhooks"},
21-
* summary="Get webhooks for current user and current application",
22-
* description="Returns all webhooks which are created for the current user and which the current authorized applicaton has access to.",
21+
* summary="Get webhooks for current user.",
22+
* description="Returns all webhooks which are created for the current user.",
2323
* @OA\Response(
2424
* response=200,
2525
* description="successful operation",
@@ -37,12 +37,8 @@ class WebhookController extends Controller
3737
* }
3838
* )
3939
*/
40-
public function getWebhooks(Request $request): AnonymousResourceCollection {
41-
$clientId = $request->user()->token()->client->id;
42-
$webhooks = Webhook::where('oauth_client_id', '=', $clientId)
43-
->where('user_id', '=', $request->user()->id)
44-
->get();
45-
return WebhookResource::collection($webhooks);
40+
public function index(): AnonymousResourceCollection {
41+
return WebhookResource::collection(Webhook::where('user_id', auth()->id())->get());
4642
}
4743

4844
/**
@@ -51,7 +47,7 @@ public function getWebhooks(Request $request): AnonymousResourceCollection {
5147
* operationId="getSingleWebhook",
5248
* tags={"Webhooks"},
5349
* summary="Get single webhook",
54-
* description="Returns a single webhook Object, if user and application is authorized to see it",
50+
* description="Returns a single webhook Object, if user is authorized to see it",
5551
* @OA\Parameter (
5652
* name="id",
5753
* in="path",
@@ -74,19 +70,11 @@ public function getWebhooks(Request $request): AnonymousResourceCollection {
7470
* {"passport": {}}, {"token": {}}
7571
* }
7672
* )
77-
*
78-
* Show single webhook
79-
*
80-
* @param int $webhookId
81-
*
82-
* @return WebhookResource|JsonResponse
8373
*/
84-
public function getWebhook(Request $request, int $webhookId): WebhookResource|JsonResponse {
85-
$clientId = $request->user()->token()->client->id;
86-
$webhook = Webhook::where('oauth_client_id', '=', $clientId)
87-
->where('user_id', '=', $request->user()->id)
88-
->where('id', '=', $webhookId)
89-
->first();
74+
public function show(int $webhookId): WebhookResource|JsonResponse {
75+
$webhook = Webhook::where('user_id', auth()->id())
76+
->where('id', '=', $webhookId)
77+
->first();
9078
if ($webhook == null) {
9179
return $this->sendError('No webhook found for this id.');
9280
}
@@ -98,7 +86,7 @@ public function getWebhook(Request $request, int $webhookId): WebhookResource|Js
9886
* path="/webhooks/{id}",
9987
* operationId="deleteWebhook",
10088
* tags={"Webhooks"},
101-
* summary="Delete a webhook if the user and application are authorized to do",
89+
* summary="Delete a webhook if the user is authorized to do",
10290
* description="",
10391
* @OA\Parameter (
10492
* name="id",
@@ -107,30 +95,21 @@ public function getWebhook(Request $request, int $webhookId): WebhookResource|Js
10795
* example=1337,
10896
* @OA\Schema(type="integer")
10997
* ),
110-
* @OA\Response(
111-
* response=200,
112-
* description="successful operation",
113-
* @OA\JsonContent(
114-
* ref="#/components/schemas/SuccessResponse"
115-
* )
116-
* ),
117-
* @OA\Response(response=400, description="Bad request"),
118-
* @OA\Response(response=404, description="No webhook found for this id"),
119-
* @OA\Response(response=403, description="User or application not authorized to delete this webhook"),
120-
* security={
121-
* {"passport": {}}, {"token": {}}
122-
* }
98+
* @OA\Response(response=204, description="Webhook deleted."),
99+
* @OA\Response(response=400, description="Bad request"),
100+
* @OA\Response(response=404, description="No webhook found for this id"),
101+
* @OA\Response(response=403, description="User or application not authorized to delete this webhook"),
102+
* security={
103+
* {"passport": {}}, {"token": {}}
104+
* }
123105
* )
124-
*
125-
* @param int $webhookId
126-
*
127-
* @return JsonResponse
128106
*/
129-
public function deleteWebhook(Request $request, int $webhookId): JsonResponse {
107+
public function destroy(int $webhookId): JsonResponse {
130108
try {
131109
$webhook = Webhook::findOrFail($webhookId);
132-
WebhookBackend::deleteWebhook($webhook, $request->user()->token()->client);
133-
return $this->sendResponse();
110+
$this->authorize('delete', $webhook);
111+
$webhook->delete();
112+
return response()->json(null, 204);
134113
} catch (AuthorizationException) {
135114
return $this->sendError('You are not allowed to delete this webhook', 403);
136115
} catch (ModelNotFoundException) {

app/Http/Controllers/Backend/WebhookController.php

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -56,25 +56,6 @@ public static function createWebhook(
5656
return $webhook;
5757
}
5858

59-
/**
60-
* Deletes a webhook
61-
*
62-
* @throws AuthorizationException
63-
*/
64-
public static function deleteWebhook(
65-
Webhook $webhook,
66-
OAuthClient|null $client
67-
): bool {
68-
Gate::authorize("delete", $webhook);
69-
// Checking if the client is allowed to delete here,
70-
// because I found no way of doing that in the policy.
71-
if ($client != null && $client->id != $webhook->client->id) {
72-
throw new AuthorizationException();
73-
}
74-
$webhook->delete();
75-
return true;
76-
}
77-
7859
public static function sendStatusWebhook(Status $status, WebhookEventEnum $event): void {
7960
self::dispatchWebhook($status->user, $event, [
8061
'status' => new StatusResource($status)

app/Http/Controllers/Frontend/SettingsController.php

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,6 @@ public function renderToken(): Renderable {
169169
]);
170170
}
171171

172-
public function renderWebhooks(): Renderable {
173-
return view('settings.webhooks', [
174-
'webhooks' => WebhookController::index(user: auth()->user()),
175-
]);
176-
}
177-
178172
/**
179173
* Approve a follow request
180174
*

app/Http/Controllers/Frontend/WebhookController.php

Lines changed: 0 additions & 24 deletions
This file was deleted.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace App\Http\Resources;
4+
5+
use App\Enum\WebhookEvent;
6+
use Illuminate\Http\Request;
7+
use Illuminate\Http\Resources\Json\JsonResource;
8+
9+
class WebhookEventResource extends JsonResource
10+
{
11+
/**
12+
* Transform the resource into an array.
13+
*
14+
* @param Request $request
15+
*
16+
* @return array
17+
*/
18+
public function toArray($request): array {
19+
return [
20+
'type' => $this->event->value,
21+
];
22+
}
23+
}

app/Http/Resources/WebhookResource.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,12 @@ class WebhookResource extends JsonResource
1818
public function toArray($request): array {
1919
return [
2020
'id' => $this->id,
21-
'clientId' => $this->oauth_client_id,
22-
'userId' => $this->user_id,
21+
'clientId' => $this->oauth_client_id, // TODO: should be removed
22+
'client' => new ClientResource($this->client),
23+
'userId' => $this->user_id, // TODO: should be removed and replaced with user object
2324
'url' => $this->url,
2425
'createdAt' => $this->created_at->toIso8601String(),
25-
'events' => array_map(function($event) {
26-
return WebhookEvent::from($event)->name();
27-
}, $this->events),
26+
'events' => WebhookEventResource::collection($this->events),
2827
];
2928
}
3029
}

lang/de.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -826,5 +826,6 @@
826826
"trip-info.user": "User",
827827
"trip-info.origin": "Abfahrtsort",
828828
"trip-info.destination": "Zielort",
829-
"requested-timestamp": "Abfragezeitpunkt"
829+
"requested-timestamp": "Abfragezeitpunkt",
830+
"successfully-deleted": "Erfolgreich gelöscht"
830831
}

lang/en.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -826,5 +826,6 @@
826826
"trip-info.user": "User",
827827
"trip-info.origin": "Origin",
828828
"trip-info.destination": "Destination",
829-
"requested-timestamp": "Requested timestamp"
829+
"requested-timestamp": "Requested timestamp",
830+
"successfully-deleted": "Successfully deleted"
830831
}

resources/js/app.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import TripCreationForm from "../vue/components/TripCreation/TripCreationForm.vu
1919
import {createPinia} from 'pinia'
2020
import piniaPluginPersistedsState from 'pinia-plugin-persistedstate'
2121
import FriendCheckinSettings from "../vue/components/Settings/FriendCheckinSettings.vue";
22+
import WebhookSettings from "../vue/components/Settings/Webhooks.vue";
2223

2324
window.notyf = new Notyf({
2425
duration: 5000,
@@ -59,6 +60,8 @@ document.addEventListener("DOMContentLoaded", function () {
5960
fallbackLang = "de";
6061
}
6162

63+
// TODO: As we add more vue components here, we should consider embedding them in a better way
64+
6265
const i18nOptions = {
6366
fallbackLang: fallbackLang,
6467
fallbackMissingTranslations: true,
@@ -117,7 +120,14 @@ document.addEventListener("DOMContentLoaded", function () {
117120
app7.use(i18nVue, i18nOptions);
118121
app7.use(pinia);
119122
app7.mount("#settings-friend-checkin");
123+
}
120124

125+
if (document.getElementById("settings-webhooks")) {
126+
const app8 = createApp({});
127+
app8.component("Webhooks", WebhookSettings);
128+
app8.use(i18nVue, i18nOptions);
129+
app8.use(pinia);
130+
app8.mount("#settings-webhooks");
121131
}
122132
});
123133

Lines changed: 2 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,8 @@
1-
@php
2-
use Carbon\Carbon;
3-
use App\Enum\WebhookEvent;
4-
@endphp
51
@extends('layouts.settings')
62
@section('title', __('settings.title-webhooks'))
73

84
@section('content')
9-
<div class="row justify-content-center">
10-
<div class="col-md-8 col-lg-7">
11-
<div class="card mb-3">
12-
<div class="card-header">{{ __('settings.title-webhooks') }}</div>
13-
<div class="card-body table-responsive px-0">
14-
<p class="mx-4">
15-
{{ __('settings.webhook-description') }}
16-
</p>
17-
@if(count($webhooks) == 0)
18-
<p class="text-danger mx-4">{{__('settings.no-webhooks')}}</p>
19-
@else
20-
<table class="table">
21-
<thead>
22-
<tr>
23-
<th>{{ __('settings.client-name') }}</th>
24-
<th>{{ __('settings.created') }}</th>
25-
<th>{{ __('settings.webhook-event-notifications-description') }}</th>
26-
<th></th>
27-
</tr>
28-
</thead>
29-
<tbody>
30-
@foreach($webhooks as $webhook)
31-
<tr>
32-
<td>{{ $webhook->client->name }}</td>
33-
<td>{{ Carbon::parse($webhook->created_at)->isoFormat(__('datetime-format')) }}</td>
34-
<td>
35-
<ul>
36-
@foreach($webhook->events()->get() as $event)
37-
<li>{{ __('settings.webhook_event.' . $event->event->value) }}</li>
38-
@endforeach
39-
</ul>
40-
</td>
41-
<td>
42-
<form method="post" action="{{ route('delwebhook') }}">
43-
@csrf
44-
<input type="hidden" name="webhookId" value="{{$webhook->id}}"/>
45-
<button class="btn btn-block btn-danger mx-0">
46-
<i class="fas fa-trash"></i>
47-
</button>
48-
</form>
49-
</td>
50-
</tr>
51-
@endforeach
52-
</tbody>
53-
</table>
54-
@endif
55-
</div>
56-
</div>
57-
</div>
5+
<div id="settings-webhooks">
6+
<Webhooks></Webhooks>
587
</div>
598
@endsection

0 commit comments

Comments
 (0)