mirror of
https://github.com/itflow-org/itflow
synced 2026-11-11 23:17:23 +00:00
Roles stage 3: roles and agents in the API and Admin > API Keys rebuilt; new api/v1/roles/read.php where an admin key reads every role with its level per module and agent count, archived on request, and any other key reads only its own user's role, and new api/v1/technicians/read.php listing agents with their role under Support at Read; API role refusals now say what the call needs and what the key's user has, naming the module, level and role, and technicians/time.php needs Read instead of Modify; Admin > API Keys shows each key's agent and role, what it can open and for which clients, whether it works (works until, expires in N days, expired, or won't work with the reason when its agent is disabled, archived, has no role or is missing) and when it was last used, with search by key or agent name; New and Edit windows show the picked agent's access as they are picked and offer only active agents, Create before ticking the copied box opens the Key tab, new keys default to a year and must end after today, and an expired key can be renamed and stay expired; handlers moved to functions/api_keys.php with validation, escaped messages and audit entries naming the agent and what an edit changed, fixing empty names on revoke, delete and bulk delete, a backslash shown for apostrophes in names, the bulk count of keys ticked rather than deleted, keys created already expired and expired keys that could not be renamed; database 3.1.7 adds api_keys.api_key_last_used_at, set at most once a minute in the configured timezone; changelog updated
This commit is contained in:
@@ -1,71 +1,61 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Edit an API key - its name, the day it stops working and the agent it
|
||||
* acts as. The key itself can't be shown or changed: make a new one.
|
||||
*/
|
||||
|
||||
require_once '../../includes/modal_header.php';
|
||||
|
||||
$api_key_id = intval($_GET['id']);
|
||||
|
||||
$sql = mysqli_query($mysqli, "SELECT api_key_expire, api_key_name, api_key_user_id FROM api_keys WHERE api_key_id = $api_key_id LIMIT 1");
|
||||
$row = mysqli_fetch_assoc($sql);
|
||||
$api_key_name = escapeHtml($row['api_key_name']);
|
||||
$api_key_expire = escapeHtml($row['api_key_expire']);
|
||||
$api_key_user_id = intval($row['api_key_user_id']);
|
||||
$row = apiKeyRow($_GET['id'] ?? 0);
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
|
||||
if (!$row) { ?>
|
||||
<div class="modal-body text-center text-secondary py-5">That key is gone - it may have been deleted.</div>
|
||||
<?php } else {
|
||||
$api_key_id = intval($row['api_key_id']);
|
||||
$role = roleRow($row['user_role_id'] ?? 0); ?>
|
||||
|
||||
<div class="modal-header bg-dark">
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-key me-2"></i>Editing API Key:
|
||||
<strong><?= $api_key_name ?></strong></h5>
|
||||
<h5 class="modal-title"><i class="fas fa-fw fa-key me-2"></i>API Key: <strong><?= escapeHtml($row['api_key_name']) ?></strong></h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||
<input type="hidden" name="api_key_id" value="<?= $api_key_id ?>">
|
||||
<div class="modal-body">
|
||||
|
||||
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
|
||||
<input type="hidden" name="api_key_id" value="<?= $api_key_id ?>">
|
||||
<div class="d-flex flex-wrap align-items-center gap-2 mb-3">
|
||||
<?= apiKeyStatePill($row, $role) ?>
|
||||
<span class="small text-body-secondary"><span class="font-monospace">••••<?= escapeHtml(substr((string) $row['api_key_secret'], -4)) ?></span> · last used <?= $row['api_key_last_used_at'] ? escapeHtml(timeAgo($row['api_key_last_used_at'])) : 'never' ?></span>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label>Name <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-sticky-note"></i></span>
|
||||
<input type="text" class="form-control" name="name" placeholder="Key Name" maxlength="255"
|
||||
value="<?= $api_key_name ?>" required autofocus>
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-sticky-note"></i></span>
|
||||
<input type="text" class="form-control" name="name" placeholder="What uses it" maxlength="255" value="<?= escapeHtml($row['api_key_name']) ?>" required autofocus>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label>Expiration Date <strong class="text-danger">*</strong></label>
|
||||
<label>Expires <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
|
||||
<input type="date" class="form-control" name="expire" min="<?= date('Y-m-d') ?>" max="2999-12-31"
|
||||
value="<?= $api_key_expire ?>" required>
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
|
||||
<input type="date" class="form-control" name="expire" max="2999-12-31" value="<?= escapeHtml($row['api_key_expire']) ?>" required>
|
||||
</div>
|
||||
<div class="form-text">It works until the start of that day. A later day brings an expired key back.</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label>Run as User <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-user-shield"></i></span>
|
||||
<select class="form-select select2" name="run_as_user" required>
|
||||
<option value="">- Select a user -</option>
|
||||
<?php
|
||||
$sql_run_users = mysqli_query($mysqli, "SELECT user_id, user_name, user_avatar FROM users WHERE user_type = 1 AND user_status = 1 AND user_archived_at IS NULL ORDER BY user_name ASC");
|
||||
while ($run_user = mysqli_fetch_assoc($sql_run_users)) {
|
||||
$run_user_id = intval($run_user['user_id']);
|
||||
$run_user_name = escapeHtml($run_user['user_name']); ?>
|
||||
<option value="<?= $run_user_id ?>" <?php if ($run_user_id == $api_key_user_id) { echo "selected"; } ?><?= selectOptionUser($run_user['user_id'], $run_user['user_name'], $run_user['user_avatar'] ?? '') ?>><?= $run_user_name ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
<small class="form-text text-muted">The key inherits this user's module permissions and client access.</small>
|
||||
</div>
|
||||
<?= apiKeyAgentFieldHtml(isset(apiKeyAgents()[intval($row['api_key_user_id'])]) ? $row['api_key_user_id'] : 0) ?>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="edit_api_key" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save</button>
|
||||
<button type="submit" name="edit_api_key" class="btn btn-primary text-bold"><i class="fas fa-check me-2"></i>Save changes</button>
|
||||
<button type="button" class="btn btn-light" data-bs-dismiss="modal"><i class="fas fa-times me-2"></i>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
require_once "../../../includes/modal_footer.php";
|
||||
<?php }
|
||||
require_once '../../../includes/modal_footer.php';
|
||||
|
||||
Reference in New Issue
Block a user