mirror of
https://github.com/getnamingo/registry.git
synced 2025-07-23 19:10:30 +02:00
Tokens can be also updated
This commit is contained in:
parent
664102d65d
commit
25f119a094
4 changed files with 180 additions and 4 deletions
|
@ -1358,6 +1358,98 @@ class SystemController extends Controller
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updateToken(Request $request, Response $response, $args)
|
||||||
|
{
|
||||||
|
if ($_SESSION["auth_roles"] != 0) {
|
||||||
|
return $response->withHeader('Location', '/dashboard')->withStatus(302);
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = $this->container->get('db');
|
||||||
|
// Get the current URI
|
||||||
|
$uri = $request->getUri()->getPath();
|
||||||
|
|
||||||
|
if ($args) {
|
||||||
|
$args = trim($args);
|
||||||
|
|
||||||
|
if (!preg_match('/^[a-zA-Z0-9\-]+$/', $args)) {
|
||||||
|
$this->container->get('flash')->addMessage('error', 'Invalid token format');
|
||||||
|
return $response->withHeader('Location', '/registry/tokens')->withStatus(302);
|
||||||
|
}
|
||||||
|
|
||||||
|
$token = $db->selectRow('SELECT token, domain_name, crdate, lastupdate, tokenStatus FROM allocation_tokens WHERE token = ?', [ $args ]);
|
||||||
|
if ($token) {
|
||||||
|
$_SESSION['token_to_update'] = $token;
|
||||||
|
return view($response,'admin/system/updateToken.twig', [
|
||||||
|
'token' => $token,
|
||||||
|
'currentUri' => $uri
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
// Token does not exist, redirect to the tokens view
|
||||||
|
return $response->withHeader('Location', '/registry/tokens')->withStatus(302);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Redirect to the tokens view
|
||||||
|
return $response->withHeader('Location', '/registry/tokens')->withStatus(302);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateTokenProcess(Request $request, Response $response)
|
||||||
|
{
|
||||||
|
if ($_SESSION["auth_roles"] != 0) {
|
||||||
|
return $response->withHeader('Location', '/dashboard')->withStatus(302);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->getMethod() === 'POST') {
|
||||||
|
// Retrieve POST data
|
||||||
|
$data = $request->getParsedBody();
|
||||||
|
$db = $this->container->get('db');
|
||||||
|
if (!empty($_SESSION['token_to_update'])) {
|
||||||
|
$token = $_SESSION['token_to_update']['token'];
|
||||||
|
} else {
|
||||||
|
$this->container->get('flash')->addMessage('error', 'No token specified for update');
|
||||||
|
return $response->withHeader('Location', '/registry/tokens')->withStatus(302);
|
||||||
|
}
|
||||||
|
$domain_name = $data['domain_name'] ?? null;
|
||||||
|
|
||||||
|
if (empty($domain_name)) {
|
||||||
|
$this->container->get('flash')->addMessage('error', 'Domain name must be provided');
|
||||||
|
return $response->withHeader('Location', '/registry/tokens/update/'.$token)->withStatus(302);
|
||||||
|
}
|
||||||
|
|
||||||
|
$invalid_domain = validate_label($domain_name, $this->container->get('db'));
|
||||||
|
if ($invalid_domain) {
|
||||||
|
$this->container->get('flash')->addMessage('error', 'Domain ' . $domainName . ' is invalid: ' . $invalid_domain);
|
||||||
|
return $response->withHeader('Location', '/registry/tokens/update/'.$token)->withStatus(302);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$db->beginTransaction();
|
||||||
|
|
||||||
|
$currentDateTime = new \DateTime();
|
||||||
|
$update = $currentDateTime->format('Y-m-d H:i:s.v'); // Current timestamp
|
||||||
|
|
||||||
|
$db->update('allocation_tokens', [
|
||||||
|
'domain_name' => $domain_name,
|
||||||
|
'lastupdate' => $update
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'token' => $token
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$db->commit();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$db->rollBack();
|
||||||
|
$this->container->get('flash')->addMessage('error', 'Database failure during update: ' . $e->getMessage());
|
||||||
|
return $response->withHeader('Location', '/registry/tokens/update/'.$token)->withStatus(302);
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($_SESSION['token_to_update']);
|
||||||
|
$this->container->get('flash')->addMessage('success', 'Token ' . $token . ' has been updated successfully on ' . $update);
|
||||||
|
return $response->withHeader('Location', '/registry/tokens/update/'.$token)->withStatus(302);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function deleteToken(Request $request, Response $response, $args)
|
public function deleteToken(Request $request, Response $response, $args)
|
||||||
{
|
{
|
||||||
if ($_SESSION["auth_roles"] != 0) {
|
if ($_SESSION["auth_roles"] != 0) {
|
||||||
|
|
81
cp/resources/views/admin/system/updateToken.twig
Normal file
81
cp/resources/views/admin/system/updateToken.twig
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
{% extends "layouts/app.twig" %}
|
||||||
|
|
||||||
|
{% block title %}{{ __('Update Token') }} {{ token.token }}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="page-wrapper">
|
||||||
|
<!-- Page header -->
|
||||||
|
<div class="page-header d-print-none">
|
||||||
|
<div class="container-xl">
|
||||||
|
<div class="row g-2 align-items-center">
|
||||||
|
<div class="col">
|
||||||
|
<!-- Page pre-title -->
|
||||||
|
<div class="page-pretitle">
|
||||||
|
{{ __('Overview') }}
|
||||||
|
</div>
|
||||||
|
<h2 class="page-title">
|
||||||
|
{{ __('Update Token') }} {{ token.token }}
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Page body -->
|
||||||
|
<div class="page-body">
|
||||||
|
<div class="container-xl">
|
||||||
|
<div class="col-12">
|
||||||
|
{% include 'partials/flash.twig' %}
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="datagrid">
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">{{ __('Token') }}</div>
|
||||||
|
<div class="datagrid-content">{{ token.token }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">{{ __('Creation Date') }}</div>
|
||||||
|
<div class="datagrid-content">{{ token.crdate }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">{{ __('Last Updated') }}</div>
|
||||||
|
<div class="datagrid-content">{{ token.lastupdate | default('N/A') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="datagrid-item">
|
||||||
|
<div class="datagrid-title">{{ __('Status') }}</div>
|
||||||
|
<div class="datagrid-content">{% set status = token.tokenStatus|lower %}
|
||||||
|
{% set color = 'gray' %}
|
||||||
|
|
||||||
|
{% if status == 'new' %}
|
||||||
|
{% set color = 'green' %}
|
||||||
|
{% elseif status == 'used' %}
|
||||||
|
{% set color = 'yellow' %}
|
||||||
|
{% elseif status == 'deprecated' %}
|
||||||
|
{% set color = 'red' %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<span class="status status-{{ color }}">{{ status|capitalize }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<form action="/registry/tokens/update" method="post">
|
||||||
|
{{ csrf.field | raw }}
|
||||||
|
<div class="form-group mt-3">
|
||||||
|
<label for="domain_name" class="form-label required">{{ __('Create Domain') }}:</label>
|
||||||
|
<input type="text" class="form-control" id="domain_name" name="domain_name" placeholder="example.com" value="{{ token.domain_name }}" required="required">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer">
|
||||||
|
<div class="row align-items-center">
|
||||||
|
<div class="col-auto">
|
||||||
|
<button type="submit" class="btn btn-primary">{{ __('Update Token') }}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% include 'partials/footer.twig' %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -70,7 +70,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function actionsFormatter(cell, formatterParams, onRendered) {
|
function actionsFormatter(cell, formatterParams, onRendered) {
|
||||||
return `<a class="btn btn-outline-danger btn-icon delete-btn" id="delete-btn" href="javascript:void(0);" data-delete-url="/registry/tokens/delete/${cell.getRow().getData().token}" title="{{ __('Delete Token') }}"><svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M4 7h16"></path><path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12"></path><path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"></path><path d="M10 12l4 4m0 -4l-4 4"></path></svg></a>`;
|
return `<a class="btn btn-outline-primary btn-icon update-btn" href="/registry/tokens/update/${cell.getRow().getData().token}" title="{{ __('Update Token') }}"><svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1"></path><path d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415z"></path><path d="M16 5l3 3"></path></svg></a>
|
||||||
|
<a class="btn btn-outline-danger btn-icon delete-btn" id="delete-btn" href="javascript:void(0);" data-delete-url="/registry/tokens/delete/${cell.getRow().getData().token}" title="{{ __('Delete Token') }}"><svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M4 7h16"></path><path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12"></path><path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"></path><path d="M10 12l4 4m0 -4l-4 4"></path></svg></a>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
table = new Tabulator("#tokenTable", {
|
table = new Tabulator("#tokenTable", {
|
||||||
|
@ -93,10 +94,10 @@
|
||||||
placeholder: "{{ __('No Data') }}",
|
placeholder: "{{ __('No Data') }}",
|
||||||
columns:[
|
columns:[
|
||||||
{formatter:"responsiveCollapse", width:30, minWidth:30, hozAlign:"center", resizable:false, headerSort:false, responsive:0},
|
{formatter:"responsiveCollapse", width:30, minWidth:30, hozAlign:"center", resizable:false, headerSort:false, responsive:0},
|
||||||
{title:"{{ __('Token') }}", field:"token", minWidth:300, minWidth:100, headerSort:true, resizable:false, formatter: copyableFormatter, responsive:0},
|
{title:"{{ __('Token') }}", field:"token", width:400, minWidth:200, headerSort:true, resizable:false, formatter: copyableFormatter, responsive:0},
|
||||||
{ title: "{{ __('Domain') }}", field: "domain_name", width:300, minWidth:80, headerSort:true, resizable:false, formatter: domainFormatter, responsive:2},
|
{ title: "{{ __('Domain') }}", field: "domain_name", width:300, minWidth:80, headerSort:true, resizable:false, formatter: domainFormatter, responsive:2},
|
||||||
{title:"{{ __('Type') }}", field:"tokenType", width:120, minWidth:80, headerSort:true, resizable:false, formatter: typeStatusFormatter, responsive:2},
|
{title:"{{ __('Type') }}", field:"tokenType", width:160, minWidth:100, headerSort:true, resizable:false, formatter: typeStatusFormatter, responsive:2},
|
||||||
{title:"{{ __('Status') }}", field:"tokenStatus", width:120, minWidth:80, headerSort:true, resizable:false, formatter: lifecycleStatusFormatter, responsive:2},
|
{title:"{{ __('Status') }}", field:"tokenStatus", width:160, minWidth:100, headerSort:true, resizable:false, formatter: lifecycleStatusFormatter, responsive:2},
|
||||||
{title: "{{ __('Actions') }}", formatter: actionsFormatter, resizable:false, headerSort:false, download:false, hozAlign: "center", responsive:0, cellClick: function(e, cell){
|
{title: "{{ __('Actions') }}", formatter: actionsFormatter, resizable:false, headerSort:false, download:false, hozAlign: "center", responsive:0, cellClick: function(e, cell){
|
||||||
if (e.target.closest('.delete-btn')) {
|
if (e.target.closest('.delete-btn')) {
|
||||||
e.preventDefault(); // Prevent the default link behavior
|
e.preventDefault(); // Prevent the default link behavior
|
||||||
|
|
|
@ -141,6 +141,8 @@ $app->group('', function ($route) {
|
||||||
$route->map(['GET', 'POST'], '/registry/reserved', SystemController::class .':manageReserved')->setName('manageReserved');
|
$route->map(['GET', 'POST'], '/registry/reserved', SystemController::class .':manageReserved')->setName('manageReserved');
|
||||||
$route->get('/registry/tokens', SystemController::class .':manageTokens')->setName('manageTokens');
|
$route->get('/registry/tokens', SystemController::class .':manageTokens')->setName('manageTokens');
|
||||||
$route->get('/registry/tokens/generate', SystemController::class .':generateTokens')->setName('generateTokens');
|
$route->get('/registry/tokens/generate', SystemController::class .':generateTokens')->setName('generateTokens');
|
||||||
|
$route->get('/registry/tokens/update/{token}', SystemController::class . ':updateToken')->setName('updateToken');
|
||||||
|
$route->post('/registry/tokens/update', SystemController::class . ':updateTokenProcess')->setName('updateTokenProcess');
|
||||||
$route->map(['GET', 'POST'], '/registry/tokens/delete/{token}', SystemController::class . ':deleteToken')->setName('deleteToken');
|
$route->map(['GET', 'POST'], '/registry/tokens/delete/{token}', SystemController::class . ':deleteToken')->setName('deleteToken');
|
||||||
$route->post('/registry/promotions', SystemController::class . ':managePromo')->setName('managePromo');
|
$route->post('/registry/promotions', SystemController::class . ':managePromo')->setName('managePromo');
|
||||||
$route->post('/registry/phases', SystemController::class . ':managePhases')->setName('managePhases');
|
$route->post('/registry/phases', SystemController::class . ':managePhases')->setName('managePhases');
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue