Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f2810a7950 | ||
|
|
d572067cf6 |
No files matched your search
+13
@@ -10,13 +10,26 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
supervisor \
|
supervisor \
|
||||||
# Others
|
# Others
|
||||||
net-tools curl less nano \
|
net-tools curl less nano \
|
||||||
|
# PHP extensions needed by the OIDC helpers
|
||||||
|
libzip-dev libpng-dev libicu-dev libpq-dev \
|
||||||
|
&& docker-php-ext-install pdo_mysql \
|
||||||
|
&& docker-php-ext-install zip \
|
||||||
|
&& docker-php-ext-install intl \
|
||||||
# Clean up
|
# Clean up
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# -------------------------------------------------------------
|
||||||
|
# Install Composer (stand‑alone)
|
||||||
|
# -------------------------------------------------------------
|
||||||
|
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
||||||
|
|
||||||
# Apache on 8069
|
# Apache on 8069
|
||||||
COPY apache_ports.conf /etc/apache2/ports.conf
|
COPY apache_ports.conf /etc/apache2/ports.conf
|
||||||
COPY apache_vhost.conf /etc/apache2/sites-available/000-default.conf
|
COPY apache_vhost.conf /etc/apache2/sites-available/000-default.conf
|
||||||
COPY web/ /var/www/html/
|
COPY web/ /var/www/html/
|
||||||
|
# Set up composer
|
||||||
|
WORKDIR /var/www/html/
|
||||||
|
RUN composer install --no-dev --optimize-autoloader --no-interaction
|
||||||
|
|
||||||
# API on 5000
|
# API on 5000
|
||||||
RUN mkdir -p /opt/Fitness
|
RUN mkdir -p /opt/Fitness
|
||||||
|
|||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
require_once __DIR__ . '/config.php';
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Fitness Site – OIDC Demo</title>
|
||||||
|
<style>
|
||||||
|
body { font-family: Arial, sans-serif; margin: 2rem; }
|
||||||
|
.info { margin-top: 1rem; }
|
||||||
|
pre { background: #f4f4f4; padding: 1rem; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Fitness Site – OIDC Demo</h1>
|
||||||
|
|
||||||
|
<?php if (!isset($_SESSION['user'])): ?>
|
||||||
|
<p>You are not logged in.</p>
|
||||||
|
<p><a href="/login.php"><button>Login with Authelia</button></a></p>
|
||||||
|
<?php else: ?>
|
||||||
|
<p>Logged in as: <strong><?=htmlspecialchars($_SESSION['user']['user_info']['name'] ?? 'N/A')?></strong></p>
|
||||||
|
|
||||||
|
<div class="info">
|
||||||
|
<h2>User Information</h2>
|
||||||
|
<pre><?=htmlspecialchars(json_encode($_SESSION['user']['user_info'], JSON_PRETTY_PRINT))?></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info">
|
||||||
|
<h2>ID Token Payload (claims)</h2>
|
||||||
|
<pre><?=htmlspecialchars(json_encode($_SESSION['user']['id_info'], JSON_PRETTY_PRINT))?></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p><a href="/logout.php"><button>Logout</button></a></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
File renamed without changes.
@@ -1,9 +0,0 @@
|
|||||||
OIDC_CLIENT_ID=fitness-oidc
|
|
||||||
OIDC_CLIENT_SECRET=egebuqzZfVnjjBG9JDQ8tjW3TzV9gJurvT7qfB6c2SX2nPBNeaGycDfx4788QzJd
|
|
||||||
OIDC_REDIRECT_URI=https://fitness.matt-cloud.com/pgapi/auth/oidc/callback
|
|
||||||
OIDC_AUTH_ENDPOINT=https://auth.matt-cloud.com/oidc/auth
|
|
||||||
OIDC_TOKEN_ENDPOINT=https://auth.matt-cloud.com/oidc/token
|
|
||||||
OIDC_USERINFO_ENDPOINT=https://auth.matt-cloud.com/oidc/userinfo
|
|
||||||
OIDC_LOGOUT_ENDPOINT=https://auth.matt-cloud.com/logout
|
|
||||||
# Optional: the default redirect after logout
|
|
||||||
OIDC_POST_LOGOUT_REDIRECT_URI=https://fitness.matt-cloud.com/
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
require_once __DIR__ . '/config.php';
|
|
||||||
?>
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Fitness Site – OIDC Demo</title>
|
|
||||||
<style>
|
|
||||||
body { font-family: Arial, sans-serif; margin: 2rem; }
|
|
||||||
.info { margin-top: 1rem; }
|
|
||||||
pre { background: #f4f4f4; padding: 1rem; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Fitness Site – OIDC Demo</h1>
|
|
||||||
|
|
||||||
<?php if (!isset($_SESSION['user'])): ?>
|
|
||||||
<p>You are not logged in.</p>
|
|
||||||
<p><a href="/login.php"><button>Login with Authelia</button></a></p>
|
|
||||||
<?php else: ?>
|
|
||||||
<p>Logged in as: <strong><?=htmlspecialchars($_SESSION['user']['user_info']['name'] ?? 'N/A')?></strong></p>
|
|
||||||
|
|
||||||
<div class="info">
|
|
||||||
<h2>User Information</h2>
|
|
||||||
<pre><?=htmlspecialchars(json_encode($_SESSION['user']['user_info'], JSON_PRETTY_PRINT))?></pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="info">
|
|
||||||
<h2>ID Token Payload (claims)</h2>
|
|
||||||
<pre><?=htmlspecialchars(json_encode($_SESSION['user']['id_info'], JSON_PRETTY_PRINT))?></pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p><a href="/logout.php"><button>Logout</button></a></p>
|
|
||||||
<?php endif; ?>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
-114
@@ -1,114 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Fitness Tracker</title>
|
|
||||||
<style>
|
|
||||||
table { width: 100%; border-collapse: collapse; }
|
|
||||||
th, td { border: 1px solid #ddd; padding: 8px; }
|
|
||||||
th { background:#f0f0f0; }
|
|
||||||
#drop-zone { border: 2px dashed #aaa; padding: 1rem; text-align:center; cursor:pointer; }
|
|
||||||
#drop-zone.hover { background:#e0e0ff; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<h1>Providers</h1>
|
|
||||||
<button id="add-provider-btn">Add Provider</button>
|
|
||||||
<table id="providers-table">
|
|
||||||
<thead><tr><th>ID</th><th>Name</th><th>Phone</th><th>Photo</th></tr></thead>
|
|
||||||
<tbody></tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<!-- Add Provider Modal -->
|
|
||||||
<div id="modal" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.5);">
|
|
||||||
<div style="background:#fff; margin:5% auto; padding:1rem; width:300px; position:relative;">
|
|
||||||
<h2>Add Provider</h2>
|
|
||||||
<label>Name: <input type="text" id="p-name"></label><br>
|
|
||||||
<label>Age: <input type="number" id="p-age"></label><br>
|
|
||||||
<label>Phone: <input type="text" id="p-phone"></label><br>
|
|
||||||
<label>Rates: <input type="text" id="p-rates" placeholder='{"hourly":70}'></label><br>
|
|
||||||
<label>Private: <input type="checkbox" id="p-private"></label><br>
|
|
||||||
|
|
||||||
<div id="drop-zone">Drag photo or click to upload</div>
|
|
||||||
<input type="file" id="p-file" style="display:none;">
|
|
||||||
<br>
|
|
||||||
<button id="save-provider">Save</button>
|
|
||||||
<button id="cancel-provider">Cancel</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
const API = 'http://localhost:5000';
|
|
||||||
|
|
||||||
// ----------- Fetch & render providers -----------------
|
|
||||||
async function loadProviders() {
|
|
||||||
const res = await fetch(`${API}/providers`);
|
|
||||||
const data = await res.json();
|
|
||||||
const tbody = document.querySelector('#providers-table tbody');
|
|
||||||
tbody.innerHTML = '';
|
|
||||||
data.forEach(p => {
|
|
||||||
const tr = document.createElement('tr');
|
|
||||||
tr.innerHTML = `
|
|
||||||
<td>${p.id}</td>
|
|
||||||
<td>${p.name}</td>
|
|
||||||
<td>${p.phone}</td>
|
|
||||||
<td><img src="${p.photo}" width="50"></td>
|
|
||||||
`;
|
|
||||||
tbody.appendChild(tr);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
loadProviders();
|
|
||||||
|
|
||||||
// ----------- Modal handling -----------------
|
|
||||||
const modal = document.getElementById('modal');
|
|
||||||
const addBtn = document.getElementById('add-provider-btn');
|
|
||||||
const cancelBtn = document.getElementById('cancel-provider');
|
|
||||||
const dropZone = document.getElementById('drop-zone');
|
|
||||||
const fileInput = document.getElementById('p-file');
|
|
||||||
let uploadedPhotoUrl = null;
|
|
||||||
|
|
||||||
addBtn.onclick = () => { modal.style.display='block'; }
|
|
||||||
cancelBtn.onclick = () => { modal.style.display='none'; }
|
|
||||||
|
|
||||||
dropZone.onclick = () => fileInput.click();
|
|
||||||
|
|
||||||
fileInput.onchange = () => uploadFile(fileInput.files[0]);
|
|
||||||
|
|
||||||
dropZone.addEventListener('dragover', e => { e.preventDefault(); dropZone.classList.add('hover'); });
|
|
||||||
dropZone.addEventListener('dragleave', e => { e.preventDefault(); dropZone.classList.remove('hover'); });
|
|
||||||
dropZone.addEventListener('drop', e => {
|
|
||||||
e.preventDefault(); dropZone.classList.remove('hover');
|
|
||||||
uploadFile(e.dataTransfer.files[0]);
|
|
||||||
});
|
|
||||||
|
|
||||||
async function uploadFile(file) {
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append('photo', file);
|
|
||||||
const resp = await fetch(`${API}/upload_photo`, { method: 'POST', body: formData });
|
|
||||||
uploadedPhotoUrl = await resp.text(); // /uploads/xxxx.jpg
|
|
||||||
dropZone.textContent = '✓ Uploaded';
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------- Save provider -----------------
|
|
||||||
const saveBtn = document.getElementById('save-provider');
|
|
||||||
saveBtn.onclick = async () => {
|
|
||||||
const payload = {
|
|
||||||
name: document.getElementById('p-name').value,
|
|
||||||
age: parseInt(document.getElementById('p-age').value, 10),
|
|
||||||
phone: document.getElementById('p-phone').value,
|
|
||||||
rates: JSON.parse(document.getElementById('p-rates').value),
|
|
||||||
private: document.getElementById('p-private').checked,
|
|
||||||
photo: uploadedPhotoUrl
|
|
||||||
};
|
|
||||||
await fetch(`${API}/providers`, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify(payload)
|
|
||||||
});
|
|
||||||
modal.style.display='none';
|
|
||||||
loadProviders(); // refresh table
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
Reference in new issue
Block a user