Files
panel/resources/views/admin/api/index.blade.php
Mackenzie Molloy 7576d0d08e Added support for viewing and deleting of any Application API Keys (#5176)
This PR closes Issue #5175.

For context, I am aware that Application API Keys are deprecated in
favour of Client API Keys however they are still operational within
Pterodactyl and thus, not fully removed.

Currently in Pterodactyl, as an Admin, you can only view your
Application API Keys on the Admin Panel. In this PR, I made it so all
Application Keys are visible and deletable. The key strings are
obfuscated if the key does not belong to the user viewing.


![image](https://github.com/user-attachments/assets/9edb2533-d99c-4ec3-80cc-25630fd48594)

The reason for adding this is primarily so other admin users can be
aware of and delete another admin user's Application API keys from the
UI. This functionality is useful in the event of a malicious user
compromising an admin account, creating some API Keys to continue their
attacks and the owner of the compromised admin account being unaware of
Application API Keys. In this instance, even after a password reset, the
attack could continue via the Application API without the admin
realising it.

I've tested the creation and deleting of keys along with using keys via
the Application API to ensure no breakages have occurred.

---------

Co-authored-by: DaneEveritt <dane@daneeveritt.com>
2026-02-11 16:03:35 -08:00

114 lines
4.6 KiB
PHP

@extends('layouts.admin')
@section('title')
Application API
@endsection
@section('content-header')
<h1>Application API<small>Control access credentials for managing this Panel via the API.</small></h1>
<ol class="breadcrumb">
<li><a href="{{ route('admin.index') }}">Admin</a></li>
<li class="active">Application API</li>
</ol>
@endsection
@section('content')
<div class="row">
<div class="col-xs-12">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">Credentials List</h3>
<div class="box-tools">
<a href="{{ route('admin.api.new') }}" class="btn btn-sm btn-primary">Create New</a>
</div>
</div>
<div class="box-body table-responsive no-padding">
<table class="table table-hover">
<tr>
<th>Key</th>
<th>Memo</th>
<th>Last Used</th>
<th>Created</th>
<th>Created by</th>
<th></th>
</tr>
@foreach($keys as $key)
<tr>
<td><code>
@if (Auth::user()->is($key->user))
{{ $key->identifier . decrypt($key->token) }}
@else
{{ $key->identifier . '****' }}
@endif
</code></td>
<td>{{ $key->memo }}</td>
<td>
@if(!is_null($key->last_used_at))
@datetimeHuman($key->last_used_at)
@else
&mdash;
@endif
</td>
<td>@datetimeHuman($key->created_at)</td>
<td>
<a href="{{ route('admin.users.view', $key->user->id) }}">{{ $key->user->username }}</a>
</td>
<td>
<a href="#" data-action="revoke-key" data-attr="{{ $key->identifier }}">
<i class="fa fa-trash-o text-danger"></i>
</a>
</td>
</tr>
@endforeach
</table>
</div>
</div>
</div>
</div>
@endsection
@section('footer-scripts')
@parent
<script>
$(document).ready(function() {
$('[data-action="revoke-key"]').click(function (event) {
var self = $(this);
event.preventDefault();
swal({
type: 'error',
title: 'Revoke API Key',
text: 'Once this API key is revoked any applications currently using it will stop working.',
showCancelButton: true,
allowOutsideClick: true,
closeOnConfirm: false,
confirmButtonText: 'Revoke',
confirmButtonColor: '#d9534f',
showLoaderOnConfirm: true
}, function () {
$.ajax({
method: 'DELETE',
url: '/admin/api/revoke/' + self.data('attr'),
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
}
}).done(function () {
swal({
type: 'success',
title: '',
text: 'API Key has been revoked.'
});
self.parent().parent().slideUp();
}).fail(function (jqXHR) {
console.error(jqXHR);
swal({
type: 'error',
title: 'Whoops!',
text: 'An error occurred while attempting to revoke this key.'
});
});
});
});
});
</script>
@endsection