5 Commits

Author SHA1 Message Date
Alexander Schmidt
d0b70acf39 Fix short URL redirect when PATH_INFO is empty string
Some checks failed
Build & Push Docker Image / build (push) Has been cancelled
2026-03-27 10:09:08 +01:00
Alexander Schmidt
ffd9327e3e Allow self-hosted origins in API verification
Some checks failed
Build & Push Docker Image / build (push) Has been cancelled
2026-03-27 09:44:11 +01:00
Alexander Schmidt
40b81a5dc8 Fix install.sh: correct GitHub repo name in compose URL 2026-03-27 09:32:34 +01:00
Alexander Schmidt
dc5582aa04 Point source links to GitHub repo
Some checks failed
Build & Push Docker Image / build (push) Has been cancelled
2026-03-27 09:11:29 +01:00
Alexander Schmidt
643ced23e9 Fix GitHub Actions: add DOCKER environment, use Node.js 24 2026-03-27 09:09:38 +01:00
8 changed files with 18 additions and 10 deletions

View File

@@ -7,10 +7,12 @@ on:
env: env:
IMAGE_NAME: xmrpay IMAGE_NAME: xmrpay
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
environment: DOCKER
permissions: permissions:
contents: read contents: read
packages: write packages: write

View File

@@ -145,7 +145,7 @@ xmrpay.link/
## Self-Hosting ## Self-Hosting
```bash ```bash
git clone https://gitea.schmidt.eco/schmidt1024/xmrpay.link.git git clone https://github.com/schmidt1024/xmrpay.git
cd xmrpay.link cd xmrpay.link
# Serve with any web server that supports PHP # Serve with any web server that supports PHP
# No build tools, no npm, no database required # No build tools, no npm, no database required

View File

@@ -14,13 +14,19 @@ function send_security_headers(): void {
// ── Origin verification ─────────────────────────────────────────────────────── // ── Origin verification ───────────────────────────────────────────────────────
function verify_origin(): void { function verify_origin(): void {
$allowed = [
'https://xmrpay.link',
'http://mc6wfeaqc7oijgdcudrr5zsotmwok3jzk3tu2uezzyjisn7nzzjjizyd.onion',
];
$origin = $_SERVER['HTTP_ORIGIN'] ?? ''; $origin = $_SERVER['HTTP_ORIGIN'] ?? '';
// Allow same-origin (no Origin header from direct same-origin requests) // Allow same-origin (no Origin header from direct same-origin requests)
if ($origin === '') return; if ($origin === '') return;
// Dynamically allow the host this instance runs on
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$self_origin = $scheme . '://' . ($_SERVER['HTTP_HOST'] ?? '');
$allowed = [
$self_origin,
'https://xmrpay.link',
'http://mc6wfeaqc7oijgdcudrr5zsotmwok3jzk3tu2uezzyjisn7nzzjjizyd.onion',
];
if (!in_array($origin, $allowed, true)) { if (!in_array($origin, $allowed, true)) {
http_response_code(403); http_response_code(403);
echo json_encode(['error' => 'Origin not allowed']); echo json_encode(['error' => 'Origin not allowed']);

View File

@@ -13,7 +13,7 @@ var I18n = (function () {
var VERSION = '1.0.0'; var VERSION = '1.0.0';
var footer = 'Open Source &middot; No Tracking &middot; No KYC<br /><a href="https://gitea.schmidt.eco/schmidt1024/xmrpay.link" target="_blank" rel="noopener noreferrer">Source</a> &middot; <a href="http://mc6wfeaqc7oijgdcudrr5zsotmwok3jzk3tu2uezzyjisn7nzzjjizyd.onion" title="Tor Hidden Service">Onion</a> &middot; <a href="/privacy.html">Privacy &amp; Terms</a><br /><span class="version">v' + VERSION + '</span>'; var footer = 'Open Source &middot; No Tracking &middot; No KYC<br /><a href="https://github.com/schmidt1024/xmrpay" target="_blank" rel="noopener noreferrer">Source</a> &middot; <a href="http://mc6wfeaqc7oijgdcudrr5zsotmwok3jzk3tu2uezzyjisn7nzzjjizyd.onion" title="Tor Hidden Service">Onion</a> &middot; <a href="/privacy.html">Privacy &amp; Terms</a><br /><span class="version">v' + VERSION + '</span>';
var translations = { var translations = {
en: { en: {

View File

@@ -115,7 +115,7 @@
</main> </main>
<footer> <footer>
<p data-i18n-html="footer">Open Source &middot; No Tracking &middot; No KYC<br /><a href="https://gitea.schmidt.eco/schmidt1024/xmrpay.link" target="_blank" rel="noopener noreferrer">Source</a> &middot; <a href="http://mc6wfeaqc7oijgdcudrr5zsotmwok3jzk3tu2uezzyjisn7nzzjjizyd.onion" title="Tor Hidden Service">Onion</a> &middot; <a href="/privacy.html">Privacy &amp; Terms</a><br /><span class="version">v1.0.0</span></p> <p data-i18n-html="footer">Open Source &middot; No Tracking &middot; No KYC<br /><a href="https://github.com/schmidt1024/xmrpay" target="_blank" rel="noopener noreferrer">Source</a> &middot; <a href="http://mc6wfeaqc7oijgdcudrr5zsotmwok3jzk3tu2uezzyjisn7nzzjjizyd.onion" title="Tor Hidden Service">Onion</a> &middot; <a href="/privacy.html">Privacy &amp; Terms</a><br /><span class="version">v1.0.0</span></p>
</footer> </footer>
<div class="lang-picker" id="langPicker"> <div class="lang-picker" id="langPicker">

View File

@@ -7,7 +7,7 @@ set -e
DOMAIN="${1:-}" DOMAIN="${1:-}"
INSTALL_DIR="/opt/xmrpay" INSTALL_DIR="/opt/xmrpay"
IMAGE="schmidt1024/xmrpay:latest" IMAGE="schmidt1024/xmrpay:latest"
COMPOSE_URL="https://raw.githubusercontent.com/schmidt1024/xmrpay.link/master/docker-compose.yml" COMPOSE_URL="https://raw.githubusercontent.com/schmidt1024/xmrpay/master/docker-compose.yml"
# ── Helpers ─────────────────────────────────────────────────────────────────── # ── Helpers ───────────────────────────────────────────────────────────────────

View File

@@ -198,7 +198,7 @@
</main> </main>
<footer> <footer>
<p data-i18n-html="footer">Open Source &middot; No Tracking &middot; No KYC &middot; <a href="https://gitea.schmidt.eco/schmidt1024/xmrpay.link" target="_blank" rel="noopener noreferrer">Source</a> &middot; <a href="http://mc6wfeaqc7oijgdcudrr5zsotmwok3jzk3tu2uezzyjisn7nzzjjizyd.onion" title="Tor Hidden Service">Onion</a> &middot; <a href="/privacy.html">Privacy &amp; Terms</a></p> <p data-i18n-html="footer">Open Source &middot; No Tracking &middot; No KYC &middot; <a href="https://github.com/schmidt1024/xmrpay" target="_blank" rel="noopener noreferrer">Source</a> &middot; <a href="http://mc6wfeaqc7oijgdcudrr5zsotmwok3jzk3tu2uezzyjisn7nzzjjizyd.onion" title="Tor Hidden Service">Onion</a> &middot; <a href="/privacy.html">Privacy &amp; Terms</a></p>
</footer> </footer>
<div class="lang-picker" id="langPicker"> <div class="lang-picker" id="langPicker">

2
s.php
View File

@@ -1,5 +1,5 @@
<?php <?php
$pathInfo = isset($_SERVER['PATH_INFO']) && is_string($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : null; $pathInfo = isset($_SERVER['PATH_INFO']) && is_string($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'] !== '' ? $_SERVER['PATH_INFO'] : null;
$queryCode = isset($_GET['c']) && is_string($_GET['c']) ? $_GET['c'] : ''; $queryCode = isset($_GET['c']) && is_string($_GET['c']) ? $_GET['c'] : '';
$code = trim($pathInfo ?? $queryCode, '/'); $code = trim($pathInfo ?? $queryCode, '/');