Fix zeecka

This commit is contained in:
Zeecka
2026-01-18 13:24:31 +01:00
parent 27811d60cd
commit e9b01275d5
9 changed files with 435 additions and 474 deletions
+5 -6
View File
@@ -42,6 +42,11 @@ def create_app() -> Flask:
app.config["REDIS_QUEUE"] = Queue(connection=Redis(host="redis", port=6379))
db.init_app(app)
@app.context_processor
def inject_datetime() -> dict[str, Any]:
"""Inject datetime into all templates."""
return {"datetime": datetime}
@app.errorhandler(413)
def too_large(_: Any) -> tuple[Response, int]:
"""Error Handler for Max File Size."""
@@ -428,12 +433,6 @@ def create_app() -> Flask:
return send_file(output_file, as_attachment=True)
# Returns Current Year
@app.context_processor
def return_curr_year():
year = datetime.today().year
return{"year":year}
return app
File diff suppressed because it is too large Load Diff
+13 -14
View File
@@ -105,11 +105,12 @@ document.addEventListener('click', function (event) {
// Check if the clicked element is a copy icon
if (event.target.classList.contains('copy-icon')) {
const icon = event.target;
const textarea = icon.closest('.textarea-container').querySelector('textarea');
const codeContainer = icon.closest('.code-container');
const codeBlock = codeContainer ? codeContainer.querySelector('code') : null;
if (textarea) {
textarea.select();
navigator.clipboard.writeText(textarea.value).then(() => {
if (codeBlock) {
const textToCopy = codeBlock.textContent;
navigator.clipboard.writeText(textToCopy).then(() => {
icon.classList.remove('fa-copy');
icon.classList.add('fa-check');
setTimeout(() => {
@@ -487,16 +488,13 @@ function parseResult(result) {
analyzer.innerHTML += `<div class="alert alert-success" role="alert">${output}</div>`;
} else if (Array.isArray(result[tool]["output"])) {
if (result[tool]["output"].length > 0) {
var texarea_content = `<div class="textarea-container">`;
texarea_content += `<textarea class="form-control w-100 mb-2" rows="8" readonly>`;
for (const line of result[tool]["output"]) {
texarea_content += escapeHtml(`${line}\n`);
}
texarea_content = texarea_content.trim();
texarea_content += `</textarea>`;
texarea_content += `<i class="fas fa-copy copy-icon"></i>`;
texarea_content += `</div>`;
analyzer.innerHTML += texarea_content;
var code_content = `<div class="code-container position-relative mb-2">`;
code_content += `<pre class="mb-0"><code>`;
code_content += result[tool]["output"].map(line => escapeHtml(line)).join('\n').trim();
code_content += `</code></pre>`;
code_content += `<i class="fas fa-copy copy-icon"></i>`;
code_content += `</div>`;
analyzer.innerHTML += code_content;
}
} else if (typeof result[tool]["output"] === "object") {
var table_content = `<div class="table-container">`;
@@ -739,3 +737,4 @@ if (browseBtn) {
xhr.send(formData);
});
}
+29 -15
View File
@@ -2,33 +2,48 @@
<html lang="en" data-bs-theme="dark">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Aperi'Solve</title>
<link rel="icon" type="image/svg+xml" href="/static/img/logo.svg" />
<link href="https://fonts.googleapis.com/css2?family=Fira+Code&display=swap" rel="stylesheet" />
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<meta name="description" content="Aperi'Solve - Online steganography analysis platform for images">
<title>Aperi'Solve - Steganography Analysis</title>
<link rel="icon" type="image/svg+xml" href="/static/img/logo.svg">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://cdnjs.cloudflare.com">
<link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;700&display=swap" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/all.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="/static/css/aperisolve.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/css/aperisolve.css" rel="stylesheet">
</head>
<body class="text-light">
<body class="d-flex flex-column min-vh-100 text-light">
<div id="three-bg"></div>
<!-- Main content area -->
<main class="flex-grow-1">
<div class="container mt-5">
<a class="title_link" href="/">
<img src="/static/img/logo.svg" alt="logo" id="water-logo"/>
<span class="title-text"> Aperi'Solve </span>
<span class="title-version">(v.{{ config["PROJECT_VERSION"] }})</span>
<br><br>
<header class="site-header mb-4">
<a class="title-link d-inline-flex align-items-center text-decoration-none" href="/" aria-label="Aperi'Solve Home">
<img src="/static/img/logo.svg" alt="Aperi'Solve logo" class="logo-img me-3" width="80" height="80">
<div class="d-flex flex-column">
<span class="title-text">Aperi'Solve</span>
<span class="title-version">v.{{ config["PROJECT_VERSION"] }}</span>
</div>
</a>
</header>
{% block body_content %} {% endblock %}
</div>
</main>
<!-- Footer -->
{% include "footer.html" %}
<!-- Modal Structure -->
<div id="image-modal-container">
<img id="modal-image" src="" />
</div>
<!-- Scripts -->
<script src="/static/js/aperisolve.js"></script>
<!-- Background -->
<script type="importmap">
{
"imports": {
@@ -39,7 +54,6 @@
</script>
<script type="module" src="/static/js/background.js"></script>
{% block footer_content %} {% endblock %}
{% include "footer.html" %}
</body>
</html>
+4 -5
View File
@@ -1,8 +1,7 @@
{% extends 'base.html' %}
{% block body_content %}
<div id="httperror">
<h1>{{ statuscode }}</h1>
<br>
<h2>{{ message }}</h2>
</div>
<section id="httperror" class="text-center py-5">
<h1 class="display-1 mb-4">{{ statuscode }}</h1>
<h2 class="h3 text-light-emphasis">{{ message }}</h2>
</section>
{% endblock %}
+21 -24
View File
@@ -1,29 +1,26 @@
<footer class="d-flex justify-content-center gap-4 my-4 flex-wrap">
<div>
<a class="title-link-footer" href="/">
<span class="title-text-footer">Aperi'Solve</span>
<span class="title-version-footer">(v.{{ config["PROJECT_VERSION"] }}) © {{ year }} </span>
<footer class="mt-auto py-3 px-3">
<div class="container-fluid">
<div class="d-flex justify-content-between align-items-center flex-wrap gap-3">
<!-- Copyright -->
<div class="footer-text">
Aperi'Solve (v.{{ config["PROJECT_VERSION"] }}) © {{ datetime.today().year }}
</div>
<!-- Links -->
<div class="d-flex align-items-center gap-3 flex-wrap">
<a href="https://buymeacoffee.com/aperisolve" title="Buy Me A Coffee" class="footer-link">
<img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" class="footer-icon-img" />
</a>
<a href="/faq" title="FAQ" class="footer-link">
<i class="fa-regular fa-circle-question fa-lg"></i>
</a>
<a href="https://github.com/Zeecka/AperiSolve" target="_blank" rel="noopener" title="GitHub" class="footer-link">
<i class="fa-brands fa-github fa-lg"></i>
</a>
<a href="https://x.com/Zeecka_" target="_blank" rel="noopener" title="Twitter" class="footer-link">
<i class="fa-brands fa-x-twitter fa-lg"></i>
</a>
</div>
<div>
<a href="https://buymeacoffee.com/aperisolve" title="Coffee" class="text-light text-decoration-none">
<img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" id="coffee" />
</a>
</div>
<div>
<a href="/faq" title="FAQ" class="text-light text-decoration-none">
<i class="fa-regular fa-circle-question"></i>
</a>
</div>
<div>
<a href="https://github.com/Zeecka/AperiSolve" target="_blank" title="GitHub"
class="text-light text-decoration-none">
<i class="fa-brands fa-github"></i>
</a>
</div>
<div>
<a href="https://x.com/Zeecka_" target="_blank" title="Twitter" class="text-light text-decoration-none">
<i class="fa-brands fa-x-twitter"></i>
</a>
</div>
</footer>
+45 -25
View File
@@ -1,39 +1,59 @@
{% extends 'base.html' %}
{% block body_content %}
<form id="upload-form" class="card p-4" method="POST" enctype="multipart/form-data">
<form id="upload-form" class="card p-4 mb-4" method="POST" enctype="multipart/form-data">
<!-- Description Section -->
<section class="mb-4">
<h2 class="h4 mb-3">What is this?</h2>
<p class="text-light-emphasis mb-0">
Aperi'Solve is an online platform which performs layer analysis on images.
The platform also uses zsteg, steghide, outguess, exiftool, binwalk, foremost and strings
for deeper steganography analysis. Supports: PNG, JPG, GIF, BMP, JPEG, JFIF, JPE, TIFF...
</p>
</section>
<!-- Drop Zone -->
<div class="mb-3">
<div>
<h2>What is this ?</h2>
<p>Aperi'Solve is an online platform which performs layer analysis on image. The platform also uses zsteg,
steghide, outguess, exiftool, binwalk, foremost and strings for deeper steganography analysis. The platform
supports the following images format: .png, .jpg, .gif, .bmp, .jpeg, .jfif, .jpe, .tiff...</p>
</div>
<div id="drop-zone" class="border border-secondary rounded p-4 text-center mb-3">
<p id="drag-msg">📂 Drag and drop an image here or click to select</p>
<input type="file" id="image" name="image" accept="image/*" hidden required />
<button type="button" class="btn btn-secondary mt-2" id="browse-btn">
Choose an image
<label for="image" class="form-label visually-hidden">Image file</label>
<div id="drop-zone" class="drop-zone border border-2 border-dashed rounded-3 p-4 text-center">
<p id="drag-msg" class="mb-3">📂 Drag and drop an image here or click to select</p>
<input type="file" id="image" name="image" accept="image/*" class="visually-hidden" required>
<button type="button" class="btn btn-secondary" id="browse-btn" aria-label="Choose image file">
<i class="fa fa-folder-open me-2"></i>Choose an image
</button>
</div>
</div>
<!-- Password Field -->
<div class="mb-3">
<label for="password" class="form-label">Password (optional)</label>
<input class="form-control" type="text" name="password" id="password" />
<label for="password" class="form-label">Password <small class="text-muted">(optional)</small></label>
<input class="form-control" type="text" name="password" id="password" placeholder="Enter password if required">
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="deep" />
<label class="form-check-label" for="deep">Deep analysis</label>
<!-- Deep Analysis Toggle -->
<div class="form-check form-switch mb-4">
<input class="form-check-input" type="checkbox" role="switch" id="deep">
<label class="form-check-label" for="deep">
Deep analysis <small class="text-muted">(slower, more thorough)</small>
</label>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
<div class="progress mt-3 d-none" id="progress-container">
<div class="progress-bar" id="progress-bar" role="progress-bar" style="width: 0%">
<!-- Submit Button -->
<button type="submit" class="btn btn-primary btn-lg w-100">
<i class="fa fa-upload me-2"></i>Analyze Image
</button>
<!-- Progress Bar -->
<div class="progress mt-3 d-none" id="progress-container" role="progressbar" aria-label="Upload progress">
<div class="progress-bar progress-bar-striped progress-bar-animated" id="progress-bar" style="width: 0%">
0%
</div>
</div>
</form>
<div id="result" class="mt-5">
<div id="result-infos" class="mb-3"></div>
<div id="result-analyzers" class="mb-3"></div>
<div id="result-removal" class="mb-3"></div>
</div>
<!-- Results Section -->
<section id="result" class="results-section pb-4">
<div id="result-infos" class="mb-4"></div>
<div id="result-analyzers" class="mb-4"></div>
<div id="result-removal" class="mb-4"></div>
</section>
{% endblock %}
+5 -5
View File
@@ -1,10 +1,10 @@
{% extends 'base.html' %}
{% block body_content %}
<div id="result" class="mt-5">
<div id="result-infos" class="mb-3"></div>
<div id="result-analyzers" class="mb-3"></div>
<div id="result-removal" class="mb-3"></div>
</div>
<section id="result" class="results-section">
<div id="result-infos" class="mb-4"></div>
<div id="result-analyzers" class="mb-4"></div>
<div id="result-removal" class="mb-4"></div>
</section>
{% endblock %}
{% block footer_content %}
<script>
+12 -7
View File
@@ -1,10 +1,15 @@
{% extends 'base.html' %}
{% block body_content %}
<div id="result" class="mt-5">
{% for img in images %}<!--
--><div class="browse-images">
<a href="{{ img.link }}" target="_blank"><img src="{{ img.file }}"/></a>
</div><!--
-->{% endfor %}
</div>
<section id="result" class="results-section">
<h2 class="h3 mb-4">Browse Submissions</h2>
<div class="row g-3">
{% for img in images %}
<div class="col-6 col-md-4 col-lg-3">
<a href="{{ img.link }}" target="_blank" class="d-block browse-image-link">
<img src="{{ img.file }}" alt="Submission thumbnail" class="img-fluid rounded" loading="lazy">
</a>
</div>
{% endfor %}
</div>
</section>
{% endblock %}