Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b0c6976a95 | ||
| a674163f7f | |||
|
|
a52d95e620 | ||
|
|
fdc5b46ef3 | ||
| 7aa47b74b9 | |||
| fa056218d8 | |||
|
|
c4cb329139 | ||
| e30591b584 | |||
|
|
fe849df6db | ||
| e633457ed3 | |||
|
|
e4cff69469 | ||
| c24cf70d77 | |||
|
|
e817dfe30c | ||
| e05fa1cab6 | |||
|
|
7338210bcf | ||
| 6408e0c923 | |||
|
|
4131b1dd1c | ||
| a2feef4c08 | |||
| f3743699a2 | |||
|
|
e6160a4d12 | ||
| 4374f5e3cd | |||
|
|
212d43d145 | ||
| 3045c2df3d | |||
| 6d5524a215 | |||
|
|
380422d230 | ||
| e5ea38c973 |
@@ -5,9 +5,6 @@ on:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '28 5 * * *'
|
||||
# workflow_run support in Gitea can be tricky, keeping it but might need adjustment
|
||||
workflow_run:
|
||||
workflows: ["Sync Repo"]
|
||||
types:
|
||||
@@ -265,6 +262,11 @@ jobs:
|
||||
git commit -m "Update manifest version to ${{ steps.version.outputs.VERSION }} [▶️]" || echo "Nothing to commit"
|
||||
git push origin main
|
||||
|
||||
- name: 🛠 Install zip
|
||||
if: steps.check_commits.outputs.commit_count != '0'
|
||||
run: |
|
||||
apt-get update && apt-get install -y zip
|
||||
|
||||
- name: 📦 Create ZIP package (excluding certain files)
|
||||
if: steps.check_commits.outputs.commit_count != '0'
|
||||
run: |
|
||||
@@ -319,18 +321,17 @@ jobs:
|
||||
ZIP_NAME="${{ steps.version.outputs.ZIP_NAME }}"
|
||||
FILE_PATH="./$ZIP_NAME"
|
||||
|
||||
curl -s -X POST "${{ gitea.api_url }}/repos/${{ gitea.repository }}/releases/$RELEASE_ID/assets" \
|
||||
curl --fail -s -X POST "${{ gitea.api_url }}/repos/${{ gitea.repository }}/releases/$RELEASE_ID/assets?name=$ZIP_NAME" \
|
||||
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
|
||||
-H "Content-Type: application/zip" \
|
||||
--data-binary @"$FILE_PATH" \
|
||||
-o /dev/null
|
||||
--data-binary @"$FILE_PATH"
|
||||
|
||||
# ----- Docker steps -----
|
||||
- name: Clone Upstream Code (if needed)
|
||||
if: steps.check_commits.outputs.commit_count != '0' && (steps.check_upstream.outputs.upstream_needs_update == 'true' || steps.check_upstream.outputs.repo_url != '')
|
||||
run: |
|
||||
rm -rf upstream_src
|
||||
git clone --depth 1 --branch ${{ steps.check_upstream.outputs.repo_branch }} ${{ steps.check_upstream.outputs.repo_url }} upstream_src
|
||||
rm -rf upstream_src
|
||||
git clone --depth 1 --branch ${{ steps.check_upstream.outputs.repo_branch }} ${{ steps.check_upstream.outputs.repo_url }} upstream_src
|
||||
|
||||
- name: 🔍 Check if Dockerfile exists
|
||||
if: steps.check_commits.outputs.commit_count != '0' || steps.check_upstream.outputs.upstream_needs_update == 'true'
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
name: Update AWS SDK PHAR
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '34 3 * * *' # 03:34 UTC == 00:34 BRT
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
download-aws-sdk:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: catthehacker/ubuntu:act-latest
|
||||
permissions:
|
||||
contents: write
|
||||
actions: write # needed to dispatch another workflow
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Download AWS SDK PHAR
|
||||
run: |
|
||||
mkdir -p vendor
|
||||
wget https://github.com/aws/aws-sdk-php/releases/latest/download/aws.phar -O vendor/aws.phar
|
||||
|
||||
- name: Commit and push changes
|
||||
id: commit_step
|
||||
run: |
|
||||
git config --global --add safe.directory '*'
|
||||
git config user.name "Gitea Actions"
|
||||
git config user.email "actions@git.icc.gg"
|
||||
git add vendor/aws.phar
|
||||
|
||||
# If there are changes, commit & push; set output flag accordingly
|
||||
if git diff --quiet && git diff --staged --quiet; then
|
||||
echo "No changes to commit"
|
||||
echo "changes_committed=false" >> $GITHUB_OUTPUT
|
||||
else
|
||||
git commit -m "Update AWS SDK PHAR [▶️]"
|
||||
git push origin HEAD:main
|
||||
echo "changes_committed=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
59
.gitea/workflows/update_readme.yml
Normal file
59
.gitea/workflows/update_readme.yml
Normal file
@@ -0,0 +1,59 @@
|
||||
name: Update README
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 4 * * *" # Every day at 4 AM UTC
|
||||
|
||||
jobs:
|
||||
update-readme:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: catthehacker/ubuntu:act-latest
|
||||
|
||||
env:
|
||||
SOURCE_REPO: ivancarlos/.gitea
|
||||
SOURCE_BRANCH: main
|
||||
|
||||
steps:
|
||||
- name: Checkout current repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Checkout source README template
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ env.SOURCE_REPO }}
|
||||
ref: ${{ env.SOURCE_BRANCH }}
|
||||
token: ${{ secrets.CR_PAT }}
|
||||
path: source_readme
|
||||
|
||||
- name: Update README.md (footer only)
|
||||
run: |
|
||||
set -e
|
||||
|
||||
# --- Extract footer block from source (everything from <!-- footer --> onward) ---
|
||||
FOOTER=$(awk '/<!-- footer -->/{flag=1}flag' source_readme/README.md)
|
||||
|
||||
# --- Replace everything after <!-- footer --> with FOOTER ---
|
||||
awk -v footer="$FOOTER" '
|
||||
/<!-- footer -->/ {
|
||||
print footer
|
||||
found=1
|
||||
exit
|
||||
}
|
||||
{ print }
|
||||
' README.md > README.tmp && mv README.tmp README.md
|
||||
|
||||
- name: Remove source_readme from git index
|
||||
run: rm -rf source_readme
|
||||
|
||||
- name: Commit and push changes
|
||||
run: |
|
||||
git config user.name "Gitea Actions"
|
||||
git config user.email "actions@git.icc.gg"
|
||||
git add README.md
|
||||
git commit -m "Sync README from template [▶️]" || echo "Nothing to commit"
|
||||
git push origin ${{ github.ref_name }}
|
||||
@@ -4,7 +4,7 @@ COPY composer.json composer.json
|
||||
# COPY composer.lock composer.lock # No lock file yet
|
||||
COPY auth_keycloak.php auth_keycloak.php
|
||||
COPY s3_client.php s3_client.php
|
||||
RUN composer install --no-dev --ignore-platform-reqs --no-scripts --prefer-dist
|
||||
RUN export COMPOSER_PROCESS_TIMEOUT=2000 && composer install --no-dev --ignore-platform-reqs --no-scripts --prefer-dist
|
||||
|
||||
# Stage 2: Final image
|
||||
FROM php:8.4-fpm-alpine
|
||||
@@ -17,7 +17,7 @@ RUN apk add --no-cache --update nginx \
|
||||
# Copy dependencies from vendor stage
|
||||
COPY --from=vendor /app/vendor /var/www/html/vendor
|
||||
# Copy aws.phar
|
||||
COPY vendor/aws.phar /var/www/html/vendor/aws.phar
|
||||
# aws.phar is now installed via composer
|
||||
|
||||
# Copy application code
|
||||
COPY . /var/www/html/
|
||||
|
||||
22
README.md
22
README.md
@@ -1,19 +1,6 @@
|
||||
# Bundled CMDB
|
||||
Small CMDB project that uses ESET data sent to database for asset management, uses Keycloak as SSO provider for user authentication, S3 for file submission and access related to each asset
|
||||
|
||||
<!-- buttons -->
|
||||
[](https://github.com/ivancarlosti/bundledcmdb/stargazers)
|
||||
[](https://github.com/sponsors/ivancarlosti)
|
||||
[](https://github.com/sponsors/ivancarlosti)
|
||||
[](https://github.com/ivancarlosti/bundledcmdb/pulse)
|
||||
[](https://github.com/ivancarlosti/bundledcmdb/issues)
|
||||
[](LICENSE)
|
||||
[](https://github.com/ivancarlosti/bundledcmdb/commits)
|
||||
[](https://github.com/ivancarlosti/bundledcmdb/security)
|
||||
[](https://github.com/ivancarlosti/bundledcmdb?tab=coc-ov-file)
|
||||
[][sponsor]
|
||||
<!-- endbuttons -->
|
||||
|
||||
## Requirement:
|
||||
|
||||
* [Docker Compose](https://docs.docker.com/engine/install/)
|
||||
@@ -48,14 +35,7 @@ docker compose pull && docker compose up -d
|
||||
[**buying me a coffee**][buymeacoffee], [**donate by paypal**][paypal], [**sponsor this project**][sponsor] or just [**leave a star**](../..)⭐
|
||||
|Thanks for your support, it is much appreciated!|
|
||||
|
||||
[cc]: https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/adding-a-code-of-conduct-to-your-project
|
||||
[contributing]: https://docs.github.com/en/articles/setting-guidelines-for-repository-contributors
|
||||
[security]: https://docs.github.com/en/code-security/getting-started/adding-a-security-policy-to-your-repository
|
||||
[support]: https://docs.github.com/en/articles/adding-support-resources-to-your-project
|
||||
[it]: https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository#configuring-the-template-chooser
|
||||
[prt]: https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository
|
||||
[funding]: https://docs.github.com/en/articles/displaying-a-sponsor-button-in-your-repository
|
||||
[ivancarlos]: https://ivancarlos.it
|
||||
[ivancarlos]: https://ivancarlos.me
|
||||
[buymeacoffee]: https://www.buymeacoffee.com/ivancarlos
|
||||
[paypal]: https://icc.gg/donate
|
||||
[sponsor]: https://github.com/sponsors/ivancarlosti
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
"php": "^8.2",
|
||||
"ext-pdo": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-json": "*"
|
||||
"ext-json": "*",
|
||||
"aws/aws-sdk-php": "^3.0"
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
// --- MariaDB Settings ---
|
||||
require_once __DIR__ . '/vendor/aws.phar';
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
define('DB_HOST', getenv('DB_SERVER') ?: '127.0.0.1');
|
||||
define('DB_NAME', getenv('DB_NAME') ?: 'YOURDBNAME');
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
<?php
|
||||
require 'config.php';
|
||||
try {
|
||||
$pdo = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4", DB_USER, DB_PASS);
|
||||
$stmt = $pdo->query("DESCRIBE users");
|
||||
print_r($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
} catch (PDOException $e) {
|
||||
echo "Error: " . $e->getMessage();
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"version": "6.1.0",
|
||||
"version": "7.2.0",
|
||||
"author": "Ivan Carlos"
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ $output = fopen('php://output', 'w');
|
||||
fwrite($output, "\xEF\xBB\xBF");
|
||||
|
||||
// Write CSV header row
|
||||
fputcsv($output, $columns_to_export);
|
||||
fputcsv($output, $columns_to_export, ",", "\"", "\\");
|
||||
|
||||
// Write all rows
|
||||
foreach ($allRows as $row) {
|
||||
@@ -152,7 +152,7 @@ foreach ($allRows as $row) {
|
||||
}
|
||||
$exportRow[] = $val;
|
||||
}
|
||||
fputcsv($output, $exportRow);
|
||||
fputcsv($output, $exportRow, ",", "\"", "\\");
|
||||
}
|
||||
|
||||
fclose($output);
|
||||
|
||||
@@ -247,6 +247,11 @@ function sort_arrow($col, $current_by, $current_dir) {
|
||||
<?php endif; ?>
|
||||
<button type="submit" class="export-btn">Export to Excel</button>
|
||||
</form>
|
||||
<?php if ($role === 'superadmin'): ?>
|
||||
<form method="get" action="manage_permissions.php" style="margin: 0;">
|
||||
<button type="submit" class="export-btn" style="background-color: #2196F3;">Manage Permissions</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
<div class="header-links">
|
||||
<form method="post" action="logout.php" style="display:inline;">
|
||||
<button type="submit">Logout</button>
|
||||
|
||||
243
public/manage_permissions.php
Normal file
243
public/manage_permissions.php
Normal file
@@ -0,0 +1,243 @@
|
||||
<?php
|
||||
// manage_permissions.php
|
||||
session_start();
|
||||
require_once '../config.php';
|
||||
|
||||
// Security check: Only SuperAdmins allowed
|
||||
$role = $_SESSION['role'] ?? 'user';
|
||||
if ($role !== 'superadmin') {
|
||||
die('Access Denied: You must be a SuperAdmin to view this page.');
|
||||
}
|
||||
|
||||
// Helper: Escape output
|
||||
function escape($text) {
|
||||
return htmlspecialchars((string)$text, ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
|
||||
// DB Connection
|
||||
try {
|
||||
$pdo = new PDO(
|
||||
"mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4",
|
||||
DB_USER,
|
||||
DB_PASS,
|
||||
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
|
||||
);
|
||||
} catch (PDOException $e) {
|
||||
die("DB Connection failed: " . $e->getMessage());
|
||||
}
|
||||
|
||||
$message = '';
|
||||
$messageType = ''; // 'success' or 'error'
|
||||
|
||||
// Handle POST actions
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$action = $_POST['action'] ?? '';
|
||||
|
||||
if ($action === 'add' || $action === 'update') {
|
||||
$email = $_POST['email'] ?? '';
|
||||
$newRole = $_POST['role_to_set'] ?? '';
|
||||
|
||||
if ($email && in_array($newRole, ['admin', 'superadmin', 'manager'])) {
|
||||
// Update user role
|
||||
$stmt = $pdo->prepare("UPDATE users SET role = :role WHERE email = :email");
|
||||
$success = $stmt->execute([':role' => $newRole, ':email' => $email]);
|
||||
|
||||
if ($success && $stmt->rowCount() > 0) {
|
||||
$message = "Successfully updated permission for " . escape($email);
|
||||
$messageType = 'success';
|
||||
} elseif ($success) {
|
||||
$message = "User " . escape($email) . " already has that role or does not exist.";
|
||||
$messageType = 'info';
|
||||
} else {
|
||||
$message = "Failed to update permission.";
|
||||
$messageType = 'error';
|
||||
}
|
||||
}
|
||||
} elseif ($action === 'remove') {
|
||||
$email = $_POST['email'] ?? '';
|
||||
// Prevent self-removal if validation needed, but usually SuperAdmin can remove themselves if not careful.
|
||||
// Let's just allow it or maybe warn. For now allow.
|
||||
|
||||
if ($email === $_SESSION['user_email']) {
|
||||
$message = "You cannot remove your own SuperAdmin status from here.";
|
||||
$messageType = 'error';
|
||||
} else {
|
||||
$stmt = $pdo->prepare("UPDATE users SET role = 'user' WHERE email = :email");
|
||||
$success = $stmt->execute([':email' => $email]);
|
||||
if ($success) {
|
||||
$message = "Removed admin rights from " . escape($email);
|
||||
$messageType = 'success';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch Admins and SuperAdmins
|
||||
$stmt = $pdo->query("SELECT * FROM users WHERE LOWER(TRIM(role)) IN ('admin', 'superadmin', 'manager') ORDER BY role DESC, email ASC");
|
||||
$admins = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// Fetch All Users for Dropdown
|
||||
$stmt = $pdo->query("SELECT email FROM users ORDER BY email ASC");
|
||||
$allUsers = $stmt->fetchAll(PDO::FETCH_COLUMN);
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Manage Permissions</title>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<style>
|
||||
.container {
|
||||
max-width: 900px;
|
||||
margin: 20px auto;
|
||||
padding: 20px;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||||
}
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 2rem;
|
||||
border-bottom: 2px solid #eee;
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
.message {
|
||||
padding: 10px;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.message.success { background: #d4edda; color: #155724; border: 1px solid #c3e6cb; }
|
||||
.message.error { background: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }
|
||||
.message.info { background: #cce5ff; color: #004085; border: 1px solid #b8daff; }
|
||||
|
||||
.section {
|
||||
margin-bottom: 2rem;
|
||||
padding: 1.5rem;
|
||||
background: #f8f9fa;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #dee2e6;
|
||||
}
|
||||
.section h3 { margin-top: 0; }
|
||||
|
||||
table { width: 100%; border-collapse: collapse; margin-top: 1rem; }
|
||||
th, td { padding: 10px; border: 1px solid #ddd; text-align: left; }
|
||||
th { background: #f1f1f1; }
|
||||
|
||||
.role-badge {
|
||||
padding: 4px 8px;
|
||||
border-radius: 12px;
|
||||
font-size: 0.85em;
|
||||
font-weight: bold;
|
||||
}
|
||||
.role-superadmin { background: #6f42c1; color: white; }
|
||||
.role-admin { background: #28a745; color: white; }
|
||||
.role-manager { background: #17a2b8; color: white; }
|
||||
|
||||
.btn-remove {
|
||||
background: #dc3545;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 5px 10px;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.btn-add {
|
||||
background: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
select, input { padding: 8px; border: 1px solid #ced4da; border-radius: 4px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h2>Permission Management</h2>
|
||||
<a href="main.php" class="btn-add" style="background: #6c757d; text-decoration: none;">« Back to Dashboard</a>
|
||||
</div>
|
||||
|
||||
<?php if ($message): ?>
|
||||
<div class="message <?php echo $messageType; ?>">
|
||||
<?php echo escape($message); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Add New Section -->
|
||||
<div class="section">
|
||||
<h3>Grant Permissions</h3>
|
||||
<p>Select a user to promote to Admin or SuperAdmin status.</p>
|
||||
<form method="post" style="display: flex; gap: 10px; align-items: center; flex-wrap: wrap;">
|
||||
<input type="hidden" name="action" value="add">
|
||||
|
||||
<label for="email">User:</label>
|
||||
<select name="email" id="email" required style="min-width: 200px;">
|
||||
<option value="">-- Select User --</option>
|
||||
<?php foreach ($allUsers as $uEmail): ?>
|
||||
<option value="<?php echo escape($uEmail); ?>">
|
||||
<?php echo escape($uEmail); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
|
||||
<label for="role">Role:</label>
|
||||
<select name="role_to_set" id="role" required>
|
||||
<option value="manager">Manager</option>
|
||||
<option value="admin">Admin</option>
|
||||
<option value="superadmin">SuperAdmin</option>
|
||||
</select>
|
||||
|
||||
<button type="submit" class="btn-add">Grant Permission</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- List Section -->
|
||||
<div class="section" style="background: white; border: none; padding: 0;">
|
||||
<h3>Current Admins & SuperAdmins</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Email</th>
|
||||
<th>Company</th>
|
||||
<th>Current Role</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($admins)): ?>
|
||||
<tr><td colspan="4">No admins found.</td></tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($admins as $admin): ?>
|
||||
<tr>
|
||||
<td><?php echo escape($admin['email']); ?></td>
|
||||
<td><?php echo escape($admin['company']); ?></td>
|
||||
<td>
|
||||
<span class="role-badge role-<?php echo escape($admin['role']); ?>">
|
||||
<?php echo strtoupper(escape($admin['role'])); ?>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($admin['email'] === $_SESSION['user_email']): ?>
|
||||
<span style="color: #6c757d; font-style: italic;">(You)</span>
|
||||
<?php else: ?>
|
||||
<form method="post" style="display:inline;" onsubmit="return confirm('Are you sure you want to remove admin rights from this user?');">
|
||||
<input type="hidden" name="action" value="remove">
|
||||
<input type="hidden" name="email" value="<?php echo escape($admin['email']); ?>">
|
||||
<button type="submit" class="btn-remove">Remove</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
BIN
vendor/aws.phar
vendored
BIN
vendor/aws.phar
vendored
Binary file not shown.
Reference in New Issue
Block a user