Remotely/Server/Pages/ApiKeys.razor
2021-07-29 07:57:31 -07:00

141 lines
4.2 KiB
Plaintext

@page "/api-keys"
@attribute [Authorize]
@inherits AuthComponentBase
@inject IDataService DataService
@inject AuthenticationStateProvider AuthProvider
@inject IJsInterop JsInterop
@inject IModalService ModalService
<h3>API Keys</h3>
@if (!string.IsNullOrWhiteSpace(_alertMessage))
{
<AlertBanner Message="@_alertMessage" />
}
@if (!string.IsNullOrWhiteSpace(_newKeySecret))
{
<h5 class="text-warning font-weight-bold mb-2 mt-4">Warning: The key's secret will only be shown once. Save it now.</h5>
<h5 class="mb-4">
<label class="mr-1">Key Secret:</label>
<input class="form-control custom-control-inline" readonly value="@_newKeySecret" style="width:400px" />
</h5>
}
@if (User.IsAdministrator)
{
<div class="mb-2 mt-4">
<label class="mr-1">New Token Name:</label>
<input @bind="_createKeyName" @bind:event="oninput"
class="form-control form-control-sm custom-control-inline mr-1"
style="width:200px" />
<button class="btn btn-primary" type="button" @onclick="CreateNewKey">Create</button>
<button class="btn btn-sm btn-secondary ml-2" @onclick="ShowApiKeyHelp">
<span class="oi oi-question-mark"></span>
</button>
</div>
<table class="table table-hover table-striped">
<thead>
<tr>
<th>Name</th>
<th>ID</th>
<th>Last Used</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var apiToken in _apiTokens)
{
<tr @key="apiToken.ID">
<td>@apiToken.Name</td>
<td>@apiToken.ID</td>
<td>@apiToken.LastUsed</td>
<td>
<button type="button" class="btn btn-primary" @onclick="() => RenameKey(apiToken.ID)">Rename</button>
</td>
<td>
<button type="submit" class="btn btn-danger" @onclick="() => DeleteKey(apiToken.ID)">Delete</button>
</td>
</tr>
}
</tbody>
</table>
}
else
{
<h5 class="text-muted">Only organization administrators can view this page.</h5>
}
@code {
private readonly List<ApiToken> _apiTokens = new();
private string _alertMessage;
private string _createKeyName;
private string _newKeySecret;
protected override async Task OnInitializedAsync()
{
RefreshData();
await base.OnInitializedAsync();
}
private async Task CreateNewKey()
{
var secret = PasswordGenerator.GeneratePassword(36);
var secretHash = new PasswordHasher<RemotelyUser>().HashPassword(null, secret);
await DataService.CreateApiToken(Username, _createKeyName, secret);
RefreshData();
_alertMessage = "Key created.";
_newKeySecret = secret;
}
private async Task DeleteKey(string keyId)
{
var result = await JsInterop.Confirm("Are you sure you want to delete this key?");
if (result)
{
await DataService.DeleteApiToken(Username, keyId);
RefreshData();
_alertMessage = "Key deleted.";
}
}
private void RefreshData()
{
_apiTokens.Clear();
_apiTokens.AddRange(DataService.GetAllApiTokens(User.Id));
_createKeyName = null;
_alertMessage = null;
_newKeySecret = null;
}
private async Task RenameKey(string keyId)
{
var newName = await JsInterop.Prompt("New key name");
if (!string.IsNullOrWhiteSpace(newName))
{
await DataService.RenameApiToken(Username, keyId, newName);
RefreshData();
_alertMessage = "Key renamed.";
}
}
private void ShowApiKeyHelp()
{
ModalService.ShowModal("Using API Keys", new[]
{
"API keys should be added to the request header when making API calls. The key should be \"Authorization\", and value should be \"{key-id}:{key-secret}\". Note the colon in between.",
"Example: Authorization=e5da1c09-e851-4bd4-a8c1-532144b3f894:7uY6h5zBYm4+90pZVek4lD6ewbQ83nKcDpghBfG00hhZu6Ew"
});
}
}