frontend JS to create, retrieve, and delete API keys

This commit is contained in:
DESKTOP-T0O5CDB\DESK-555BD 2026-01-24 19:35:59 -07:00
parent 05aa49171f
commit 5904461f94
4 changed files with 94 additions and 6 deletions

View File

@ -336,6 +336,24 @@ namespace CarCareTracker.Controllers
var result = _userLogic.AddUserToHousehold(GetUserID(), username);
return Json(result);
}
[HttpGet]
public IActionResult GetUserAPIKeys()
{
var result = _userLogic.GetAPIKeysByUserId(GetUserID());
return Json(result);
}
[HttpPost]
public IActionResult CreateAPIKeyForUser(string keyName, List<HouseholdPermission> permissions)
{
var result = _userLogic.CreateAPIKey(GetUserID(), keyName, permissions);
return Json(result);
}
[HttpPost]
public IActionResult DeleteAPIKeyForUser(int keyId)
{
var result = _userLogic.DeleteAPIKeyByKeyIdAndUserId(keyId, GetUserID());
return Json(OperationResponse.Conditional(result, "API Key Deleted", StaticHelper.GenericErrorMessage));
}
[Authorize(Roles = nameof(UserData.IsRootUser))]
[HttpGet]
public IActionResult GetRootAccountInformationModal()

View File

@ -24,8 +24,7 @@ namespace CarCareTracker.External.Implementations
{
var db = _liteDB.GetLiteDB();
var table = db.GetCollection<APIKey>(tableName);
var apiKeyRecord = table.FindOne(Query.EQ(nameof(APIKey.Id), apiKeyId));
return apiKeyRecord ?? new APIKey();
return table.FindById(apiKeyId);
}
public APIKey GetAPIKeyByKey(string hashedKey)
{

View File

@ -24,7 +24,8 @@ namespace CarCareTracker.Logic
bool DeleteAllHouseholdByParentUserId(int parentUserId);
bool DeleteAllHouseholdByChildUserId(int childUserId);
OperationResponse CreateAPIKey(int userId, string keyName, List<HouseholdPermission> permisions);
bool DeleteAPIKeyByKeyId(int keyId);
List<APIKey> GetAPIKeysByUserId(int userId);
bool DeleteAPIKeyByKeyIdAndUserId(int keyId, int userId);
bool DeleteAllAPIKeysByUserId(int userId);
}
public class UserLogic: IUserLogic
@ -296,6 +297,12 @@ namespace CarCareTracker.Logic
}
public OperationResponse CreateAPIKey(int userId, string keyName, List<HouseholdPermission> permisions)
{
//check if user already has an API key by that name.
var existingApiKeys = _apiKeyData.GetAPIKeyRecordsByUserId(userId);
if (existingApiKeys.Any(x=>x.Name.ToLower() == keyName.ToLower()))
{
return OperationResponse.Failed("An API Key with that name already exists");
}
//generate key pair
var unhashedKey = Guid.NewGuid().ToString().Replace("-", string.Empty);
var hashedKey = StaticHelper.GetHash(unhashedKey);
@ -303,7 +310,8 @@ namespace CarCareTracker.Logic
{
UserId = userId,
Name = keyName,
Permissions = permisions
Permissions = permisions,
Key = hashedKey
};
var result = _apiKeyData.SaveAPIKey(keyToSave);
if (result && keyToSave.Id != default)
@ -312,11 +320,21 @@ namespace CarCareTracker.Logic
}
return OperationResponse.Failed("Unable to create API Key");
}
public bool DeleteAPIKeyByKeyId(int keyId)
public List<APIKey> GetAPIKeysByUserId(int userId)
{
var result = _apiKeyData.GetAPIKeyRecordsByUserId(userId);
return result;
}
public bool DeleteAPIKeyByKeyIdAndUserId(int keyId, int userId)
{
var existingKey = _apiKeyData.GetAPIKeyById(keyId);
if (existingKey.Id != default && existingKey.UserId == userId)
{
var result = _apiKeyData.DeleteAPIKeyById(keyId);
return result;
}
return false;
}
public bool DeleteAllAPIKeysByUserId(int userId)
{
var result = _apiKeyData.DeleteAllAPIKeysByUserId(userId);

View File

@ -661,6 +661,59 @@ function addUserToHousehold() {
});
}
function createApiKey() {
Swal.fire({
title: 'Create API Key',
html: `
<input type="text" id="inputApiKeyName" class="swal2-input" placeholder="Key Name" onkeydown="handleSwalEnter(event)">
`,
confirmButtonText: 'Create',
focusConfirm: false,
preConfirm: () => {
const keyName = $("#inputApiKeyName").val();
if (!keyName) {
Swal.showValidationMessage(`Please enter a name`);
}
return { keyName }
},
}).then(function (result) {
if (result.isConfirmed) {
$.post('/Home/CreateAPIKeyForUser', { keyName: result.value.keyName, permissions: [] }, function (data) {
if (data.success) {
Swal.fire({
title: data.message,
icon: 'success',
html: `<div class="input-group"><input type="text" class="form-control" readonly value="${data.additionalData.apiKey}"><div class="input-group-text"><button type="button" class="btn btn-sm text-secondary password-visible-button" onclick="copyApiKey(this)"><i class="bi bi-copy"></i></button></div></div>`
})
} else {
errorToast(data.message);
}
});
}
});
}
function copyApiKey(elem) {
let textToCopy = $(elem).parent().siblings("input").val();
navigator.clipboard.writeText(textToCopy);
Swal.showValidationMessage(`API Key Copied to Clipboard`);
}
function getUserApiKeys() {
$.get('/Home/GetUserAPIKeys', function (data) {
console.log(data);
})
}
function deleteApiKey(keyId) {
$.post('/Home/DeleteAPIKeyForUser', { keyId: keyId }, function (data) {
if (data.success) {
successToast(data.message);
} else {
errorToast(data.message);
}
});
}
function showAccountInformationModal() {
$.get('/Home/GetUserAccountInformationModal', function (data) {
$('#accountInformationModalContent').html(data);