]> BookStack Code Mirror - bookstack/commitdiff
API Tokens: Updated interfaces to return to correct location
authorDan Brown <redacted>
Thu, 19 Oct 2023 10:31:45 +0000 (11:31 +0100)
committerDan Brown <redacted>
Thu, 19 Oct 2023 10:31:45 +0000 (11:31 +0100)
Since management of API tokens can be accessed via two routes, this adds
tracking and handling to reutrn the user to the correct place.

app/Api/ApiToken.php
app/Api/UserApiTokenController.php
resources/views/users/account/auth.blade.php
resources/views/users/api-tokens/create.blade.php
resources/views/users/api-tokens/delete.blade.php
resources/views/users/api-tokens/edit.blade.php
resources/views/users/api-tokens/parts/list.blade.php
resources/views/users/edit.blade.php
routes/web.php

index 5c2d591e4083783d2ca6e75f86a0263ef38d9ec3..ca89c813ed09be449376a22c8a1a739c0b94977e 100644 (file)
@@ -52,4 +52,12 @@ class ApiToken extends Model implements Loggable
     {
         return "({$this->id}) {$this->name}; User: {$this->user->logDescriptor()}";
     }
+
+    /**
+     * Get the URL for managing this token.
+     */
+    public function getUrl(string $path = ''): string
+    {
+        return url("/api-tokens/{$this->user_id}/{$this->id}/" . trim($path, '/'));
+    }
 }
index 8357420ee13015f4d8dac9d6315f4b27a267cc28..7455be4ff6948c07e7722e5eaa7d2cbbe7dad4d8 100644 (file)
@@ -14,16 +14,17 @@ class UserApiTokenController extends Controller
     /**
      * Show the form to create a new API token.
      */
-    public function create(int $userId)
+    public function create(Request $request, int $userId)
     {
-        // Ensure user is has access-api permission and is the current user or has permission to manage the current user.
         $this->checkPermission('access-api');
         $this->checkPermissionOrCurrentUser('users-manage', $userId);
+        $this->updateContext($request);
 
         $user = User::query()->findOrFail($userId);
 
         return view('users.api-tokens.create', [
             'user' => $user,
+            'back' => $this->getRedirectPath($user),
         ]);
     }
 
@@ -60,14 +61,16 @@ class UserApiTokenController extends Controller
         session()->flash('api-token-secret:' . $token->id, $secret);
         $this->logActivity(ActivityType::API_TOKEN_CREATE, $token);
 
-        return redirect($user->getEditUrl('/api-tokens/' . $token->id));
+        return redirect($token->getUrl());
     }
 
     /**
      * Show the details for a user API token, with access to edit.
      */
-    public function edit(int $userId, int $tokenId)
+    public function edit(Request $request, int $userId, int $tokenId)
     {
+        $this->updateContext($request);
+
         [$user, $token] = $this->checkPermissionAndFetchUserToken($userId, $tokenId);
         $secret = session()->pull('api-token-secret:' . $token->id, null);
 
@@ -76,6 +79,7 @@ class UserApiTokenController extends Controller
             'token'  => $token,
             'model'  => $token,
             'secret' => $secret,
+            'back' => $this->getRedirectPath($user),
         ]);
     }
 
@@ -97,7 +101,7 @@ class UserApiTokenController extends Controller
 
         $this->logActivity(ActivityType::API_TOKEN_UPDATE, $token);
 
-        return redirect($user->getEditUrl('/api-tokens/' . $token->id));
+        return redirect($token->getUrl());
     }
 
     /**
@@ -123,7 +127,7 @@ class UserApiTokenController extends Controller
 
         $this->logActivity(ActivityType::API_TOKEN_DELETE, $token);
 
-        return redirect($user->getEditUrl('#api_tokens'));
+        return redirect($this->getRedirectPath($user));
     }
 
     /**
@@ -142,4 +146,30 @@ class UserApiTokenController extends Controller
 
         return [$user, $token];
     }
+
+    /**
+     * Update the context for where the user is coming from to manage API tokens.
+     * (Track of location for correct return redirects)
+     */
+    protected function updateContext(Request $request): void
+    {
+        $context = $request->query('context');
+        if ($context) {
+            session()->put('api-token-context', $context);
+        }
+    }
+
+    /**
+     * Get the redirect path for the current api token editing session.
+     * Attempts to recall the context of where the user is editing from.
+     */
+    protected function getRedirectPath(User $relatedUser): string
+    {
+        $context = session()->get('api-token-context');
+        if ($context === 'settings') {
+            return $relatedUser->getEditUrl('#api_tokens');
+        }
+
+        return url('/my-account/auth#api_tokens');
+    }
 }
index 3503978cfa956ecaf78dc9c94b5b0de1c94d8d2a..d6f85093bf37bddb7f7cb8b86f8061f50adb7c59 100644 (file)
@@ -82,6 +82,6 @@
     @endif
 
     @if(userCan('access-api'))
-        @include('users.api-tokens.parts.list', ['user' => user()])
+        @include('users.api-tokens.parts.list', ['user' => user(), 'context' => 'my-account'])
     @endif
 @stop
index 9cf772082d2e8a16af03d44166880ad68ff9291f..8250c5ae829592ed29feb09ceba588da31cd5fd6 100644 (file)
@@ -7,8 +7,8 @@
         <main class="card content-wrap auto-height">
             <h1 class="list-heading">{{ trans('settings.user_api_token_create') }}</h1>
 
-            <form action="{{ $user->getEditUrl('/create-api-token') }}" method="post">
-                {!! csrf_field() !!}
+            <form action="{{ url('/api-tokens/' . $user->id . '/create') }}" method="post">
+                {{ csrf_field() }}
 
                 <div class="setting-list">
                     @include('users.api-tokens.parts.form')
@@ -21,7 +21,7 @@
                 </div>
 
                 <div class="form-group text-right">
-                    <a href="{{ $user->getEditUrl('#api_tokens') }}" class="button outline">{{ trans('common.cancel') }}</a>
+                    <a href="{{ $back }}" class="button outline">{{ trans('common.cancel') }}</a>
                     <button class="button" type="submit">{{ trans('common.save') }}</button>
                 </div>
 
index 45f0e2fa0eb808f9047b4ff6defbecf2d47d1556..2b9a29e6a1fe4a68a2563c483a29e1c14abf45ae 100644 (file)
             <div class="grid half">
                 <p class="text-neg"><strong>{{ trans('settings.user_api_token_delete_confirm') }}</strong></p>
                 <div>
-                    <form action="{{ $user->getEditUrl('/api-tokens/' . $token->id) }}" method="POST" class="text-right">
-                        {!! csrf_field() !!}
-                        {!! method_field('delete') !!}
+                    <form action="{{ $token->getUrl() }}" method="POST" class="text-right">
+                        {{ csrf_field() }}
+                        {{ method_field('delete') }}
 
-                        <a href="{{ $user->getEditUrl('/api-tokens/' . $token->id) }}" class="button outline">{{ trans('common.cancel') }}</a>
+                        <a href="{{ $token->getUrl() }}" class="button outline">{{ trans('common.cancel') }}</a>
                         <button type="submit" class="button">{{ trans('common.confirm') }}</button>
                     </form>
                 </div>
index 61c1ac2a63e607099ef70fc12e5ab8680e0fa4cf..aa3e49dedf8512e688fb46020c93d7313a39061c 100644 (file)
@@ -7,9 +7,9 @@
         <main class="card content-wrap auto-height">
             <h1 class="list-heading">{{ trans('settings.user_api_token') }}</h1>
 
-            <form action="{{ $user->getEditUrl('/api-tokens/' . $token->id) }}" method="post">
-                {!! method_field('put') !!}
-                {!! csrf_field() !!}
+            <form action="{{ $token->getUrl() }}" method="post">
+                {{ method_field('put') }}
+                {{ csrf_field() }}
 
                 <div class="setting-list">
 
@@ -52,8 +52,8 @@
                     </div>
 
                     <div class="form-group text-right">
-                        <a href="{{  $user->getEditUrl('#api_tokens') }}" class="button outline">{{ trans('common.back') }}</a>
-                        <a href="{{  $user->getEditUrl('/api-tokens/' . $token->id . '/delete') }}" class="button outline">{{ trans('settings.user_api_token_delete') }}</a>
+                        <a href="{{  $back }}" class="button outline">{{ trans('common.back') }}</a>
+                        <a href="{{  $token->getUrl('/delete') }}" class="button outline">{{ trans('settings.user_api_token_delete') }}</a>
                         <button class="button" type="submit">{{ trans('common.save') }}</button>
                     </div>
                 </div>
index 3081682a4ae12d3f6c07733ad51caab2abede4b5..70aaa58f3f61a3b0d59776be5ee6d6e22830e2ce 100644 (file)
@@ -4,7 +4,7 @@
         <div class="text-right pt-xs">
             @if(userCan('access-api'))
                 <a href="{{ url('/api/docs') }}" class="button outline">{{ trans('settings.users_api_tokens_docs') }}</a>
-                <a href="{{ $user->getEditUrl('/create-api-token') }}" class="button outline">{{ trans('settings.users_api_tokens_create') }}</a>
+                <a href="{{ url('/api-tokens/' . $user->id . '/create?context=' . $context) }}" class="button outline">{{ trans('settings.users_api_tokens_create') }}</a>
             @endif
         </div>
     </div>
@@ -14,7 +14,7 @@
             @foreach($user->apiTokens as $token)
                 <div class="item-list-row flex-container-row items-center wrap py-xs gap-x-m">
                     <div class="flex px-m py-xs min-width-m">
-                        <a href="{{ $user->getEditUrl('/api-tokens/' . $token->id) }}">{{ $token->name }}</a> <br>
+                        <a href="{{ $token->getUrl("?context={$context}") }}">{{ $token->name }}</a> <br>
                         <span class="small text-muted italic">{{ $token->token_id }}</span>
                     </div>
                     <div class="flex flex-container-row items-center min-width-m">
@@ -23,7 +23,7 @@
                             {{ $token->expires_at->format('Y-m-d') ?? '' }}
                         </div>
                         <div class="flex px-m py-xs text-right">
-                            <a class="button outline small" href="{{ $user->getEditUrl('/api-tokens/' . $token->id) }}">{{ trans('common.edit') }}</a>
+                            <a class="button outline small" href="{{ $token->getUrl("?context={$context}") }}">{{ trans('common.edit') }}</a>
                         </div>
                     </div>
                 </div>
index 1254a13307ae3c2f7acd580b313c6609f7a6123d..076b28c746ba41c67b0f7e69cfd3d6aa5c451d0f 100644 (file)
             </section>
         @endif
 
-        @include('users.api-tokens.parts.list', ['user' => $user])
+        @include('users.api-tokens.parts.list', ['user' => $user, 'context' => 'settings'])
     </div>
 
 @stop
index 69ce5167c3112f23200bb4b963c4ea6f5f5f8725..c2f4891b834268b8fbfaf2a21a15dd872bfe6750 100644 (file)
@@ -251,12 +251,12 @@ Route::middleware('auth')->group(function () {
     Route::patch('/preferences/update-code-language-favourite', [UserControllers\UserPreferencesController::class, 'updateCodeLanguageFavourite']);
 
     // User API Tokens
-    Route::get('/settings/users/{userId}/create-api-token', [UserApiTokenController::class, 'create']);
-    Route::post('/settings/users/{userId}/create-api-token', [UserApiTokenController::class, 'store']);
-    Route::get('/settings/users/{userId}/api-tokens/{tokenId}', [UserApiTokenController::class, 'edit']);
-    Route::put('/settings/users/{userId}/api-tokens/{tokenId}', [UserApiTokenController::class, 'update']);
-    Route::get('/settings/users/{userId}/api-tokens/{tokenId}/delete', [UserApiTokenController::class, 'delete']);
-    Route::delete('/settings/users/{userId}/api-tokens/{tokenId}', [UserApiTokenController::class, 'destroy']);
+    Route::get('/api-tokens/{userId}/create', [UserApiTokenController::class, 'create']);
+    Route::post('/api-tokens/{userId}/create', [UserApiTokenController::class, 'store']);
+    Route::get('/api-tokens/{userId}/{tokenId}', [UserApiTokenController::class, 'edit']);
+    Route::put('/api-tokens/{userId}/{tokenId}', [UserApiTokenController::class, 'update']);
+    Route::get('/api-tokens/{userId}/{tokenId}/delete', [UserApiTokenController::class, 'delete']);
+    Route::delete('/api-tokens/{userId}/{tokenId}', [UserApiTokenController::class, 'destroy']);
 
     // Roles
     Route::get('/settings/roles', [UserControllers\RoleController::class, 'index']);
Morty Proxy This is a proxified and sanitized view of the page, visit original site.