Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
92ec357
Add optional code param in upload request
nickhnsn Aug 9, 2024
3815c19
Merge pull request #588 from nickhnsn/patch-1
sergix44 Aug 29, 2024
c1ff48d
Bump twig/twig from 2.16.0 to 2.16.1
dependabot[bot] Sep 9, 2024
da356da
enable custom sender via config
Mainfrezzer Oct 11, 2024
6b8558c
Merge pull request #605 from sergix44/dependabot/composer/twig/twig-2…
sergix44 Oct 12, 2024
eef26b9
Translated using Weblate (Serbian)
Reportiv Oct 9, 2024
8ef247c
Merge pull request #608 from weblate/weblate-xbackbone-xbackbone
sergix44 Oct 12, 2024
92549a2
Bump bootstrap from 4.6.1 to 5.0.0
dependabot[bot] Oct 12, 2024
4d7005e
Merge branch 'sergix44:master' into master
Mainfrezzer Oct 18, 2024
e596428
Bump twig/twig from 2.16.1 to 3.11.2
dependabot[bot] Nov 6, 2024
7a880be
Merge pull request #612 from sergix44/dependabot/composer/twig/twig-3…
sergix44 Dec 1, 2024
8a468f0
Merge branch 'sergix44:master' into master
Mainfrezzer Dec 16, 2024
99dd555
Exporting ShareX Settings Fix
Jan 16, 2025
bf89b09
Merge pull request #617 from SenkaWolf/master
sergix44 Jan 17, 2025
c6ff921
Merge pull request #616 from Mainfrezzer/master
sergix44 Jan 17, 2025
fd1fbb1
Apply fixes from StyleCI
StyleCIBot Jan 17, 2025
064e946
Merge pull request #619 from sergix44/analysis-VBVyBP
sergix44 Jan 17, 2025
3d15d18
Merge pull request #609 from sergix44/dependabot/npm_and_yarn/bootstr…
sergix44 Jan 17, 2025
fc83e1c
Revert "Bump twig/twig from 2.16.1 to 3.11.2"
sergix44 Jan 17, 2025
2470cec
Merge pull request #620 from sergix44/revert-612-dependabot/composer/…
sergix44 Jan 17, 2025
57a78e6
Bump twig/twig from 2.16.1 to 3.11.2
dependabot[bot] Jan 17, 2025
0814e11
Merge pull request #621 from sergix44/dependabot/composer/twig/twig-3…
sergix44 Jan 18, 2025
291e80a
Translated using Weblate (Russian)
dyrkuwu Nov 2, 2024
7528d23
Added translation using Weblate (Tamil)
Nov 4, 2024
cd6b404
Translated using Weblate (Tamil)
Nov 4, 2024
2797be7
Translated using Weblate (Portuguese)
Nov 13, 2024
016ff7e
Translated using Weblate (Finnish)
Ricky-Tigg Nov 28, 2024
aa7f8eb
Translated using Weblate (Indonesian)
rezaalmanda Dec 23, 2024
238ad65
Merge pull request #610 from weblate/weblate-xbackbone-xbackbone
sergix44 Jan 18, 2025
8e3128c
Fix mail retrieval
sergix44 Jan 18, 2025
115e1eb
update for php 8.4
sergix44 Jan 18, 2025
bdf9d14
update changelog
sergix44 Jan 18, 2025
bbef8b5
update dependencies
sergix44 Jan 18, 2025
0cc4f26
update site changelog
sergix44 Jan 18, 2025
b137f25
temporary hide deprecations to avoid breaking sessions
sergix44 Jan 18, 2025
5fed0e7
Update FUNDING.yml
sergix44 Jan 19, 2025
2eb0375
FIX ArgumentCountError in UploadController::saveMedia
The-MEO Jan 19, 2025
e910f7e
Merge pull request #625 from The-MEO/fix/ArgumentCountError
sergix44 Jan 23, 2025
5e9d5c2
bump release
sergix44 Jan 26, 2025
d0ed9c2
update lock
sergix44 Jan 26, 2025
89ed969
Add basic 2FA support
SkyLostTR Jul 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/FUNDING.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: #
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
custom: http://bit.ly/XBackBonePaypal
custom: #
2 changes: 1 addition & 1 deletion .github/workflows/test_suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
strategy:
matrix:
operating-system: [ubuntu-latest]
php-versions: ["7.3", "7.4", "8.0", "8.1", "8.2"]
php-versions: ["7.3", "7.4", "8.0", "8.1", "8.2", "8.3", "8.4"]

steps:
- uses: actions/checkout@v2
Expand Down
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,25 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## Unreleased

## [3.8.1] - 2025-01-24
### Fixed
- Crash when uploading file (#625)

## [3.8.0] - 2025-01-18
### Added
- Support for PHP 8.4
- Add an `app_email` option to the config (#616)
- Exporting ShareX settings now work for the latest version of ShareX 16.1.0 (#617)
- Option to upload file with a custom name (#588)
- Upload from clipboard (#572)

### Changed
- Updated translations.
- Updated dependencies.

### Fixed
- Page count calculation (#586)

## [3.7.0] - 2024-01-14
### Added
- Added support for vanity urls.
Expand Down
8 changes: 7 additions & 1 deletion app/Controllers/Auth/LoginController.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public function login(Request $request, Response $response): Response

$username = param($request, 'username');
$password = param($request, 'password');
$user = $this->database->query('SELECT `id`, `email`, `username`, `password`,`is_admin`, `active`, `current_disk_quota`, `max_disk_quota`, `ldap`, `copy_raw` FROM `users` WHERE `username` = ? OR `email` = ? LIMIT 1', [$username, $username])->fetch();
$user = $this->database->query('SELECT `id`, `email`, `username`, `password`,`is_admin`, `active`, `current_disk_quota`, `max_disk_quota`, `ldap`, `copy_raw`, `twofa_secret` FROM `users` WHERE `username` = ? OR `email` = ? LIMIT 1', [$username, $username])->fetch();

if ($this->config['ldap']['enabled'] && (!$user || $user->ldap ?? true)) {
$user = $this->ldapLogin($request, $username, param($request, 'password'), $user);
Expand All @@ -70,6 +70,12 @@ public function login(Request $request, Response $response): Response
return redirect($response, route('login'));
}

if (!empty($user->twofa_secret)) {
$this->session->set('twofa_user', $user)
->set('twofa_remember', param($request, 'remember') === 'on');
return redirect($response, route('2fa.show'));
}

$this->session->set('logged', true)
->set('user_id', $user->id)
->set('username', $user->username)
Expand Down
55 changes: 55 additions & 0 deletions app/Controllers/Auth/TwoFactorController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace App\Controllers\Auth;

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

class TwoFactorController extends AuthController
{
public function show(Response $response): Response
{
if (!$this->session->has('twofa_user')) {
return redirect($response, route('login.show'));
}

return view()->render($response, 'auth/2fa.twig');
}

public function verify(Request $request, Response $response): Response
{
$user = $this->session->get('twofa_user');
if (!$user) {
return redirect($response, route('login.show'));
}

$code = param($request, 'code');
if (!verify_totp_code($user->twofa_secret, $code)) {
$this->session->alert(lang('2fa_invalid'), 'danger');
return redirect($response, route('2fa.show'));
}

$this->session->set('logged', true)
->set('user_id', $user->id)
->set('username', $user->username)
->set('admin', $user->is_admin)
->set('copy_raw', $user->copy_raw);

$this->setSessionQuotaInfo($user->current_disk_quota, $user->max_disk_quota);

$this->session->alert(lang('welcome', [$user->username]), 'info');
$this->logger->info("User $user->username logged in.");

if ($this->session->get('twofa_remember')) {
$this->refreshRememberCookie($user->id);
}

$this->session->delete('twofa_user')->delete('twofa_remember');

if ($this->session->has('redirectTo')) {
return redirect($response, $this->session->get('redirectTo'));
}

return redirect($response, route('home'));
}
}
30 changes: 19 additions & 11 deletions app/Controllers/ClientController.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,38 @@ class ClientController extends Controller
public function getShareXConfig(Request $request, Response $response, int $id): Response
{
$user = make(UserRepository::class)->get($request, $id, true);

if (!$user->token) {
$this->session->alert(lang('no_upload_token'), 'danger');

return redirect($response, $request->getHeaderLine('Referer'));
}


$fileBaseName = $user->username . '-ShareX'; // Base file name without extension
$fileName = $fileBaseName . '.sxcu'; // Full file name with extension

$json = [
'Version' => '16.1.0',
'Name' => $fileBaseName,
'DestinationType' => 'ImageUploader, TextUploader, FileUploader',
'RequestMethod' => 'POST',
'RequestURL' => route('upload'),
'FileFormName' => 'upload',
'Body' => 'MultipartFormData',
'Arguments' => [
'file' => '$filename$',
'text' => '$input$',
'file' => '{filename}',
'text' => '{input}',
'token' => $user->token,
],
'URL' => '$json:url$',
'ThumbnailURL' => '$json:url$/raw',
'DeletionURL' => '$json:url$/delete/'.$user->token,
'FileFormName' => 'upload',
'URL' => '{json:url}',
'ThumbnailURL' => '{json:url}/raw',
'DeletionURL' => '{json:url}/delete/' . $user->token,
];

return json($response, $json, 200, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)
->withHeader('Content-Disposition', 'attachment;filename="'.$user->username.'-ShareX.sxcu"');
->withHeader('Content-Disposition', 'attachment;filename="' . $fileName . '"');
}


/**
* @param Request $request
Expand Down
19 changes: 14 additions & 5 deletions app/Controllers/UploadController.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public function uploadEndpoint(Request $request, Response $response): Response
}

try {
$response = $this->saveMedia($response, $file, $user);
$response = $this->saveMedia($response, $file, $user, param($request, 'code'));
} catch (Exception $e) {
$this->updateUserQuota($request, $user->id, $file->getSize(), true);
throw $e;
Expand Down Expand Up @@ -178,15 +178,24 @@ protected function validateUser(Request $request, Response $response, UploadedFi
* @param Response $response
* @param UploadedFileInterface $file
* @param $user
* @param $code
* @return Response
* @throws \League\Flysystem\FileExistsException
* @throws \League\Flysystem\FileNotFoundException
*/
protected function saveMedia(Response $response, UploadedFileInterface $file, $user)
protected function saveMedia(Response $response, UploadedFileInterface $file, $user, $code = null)
{
do {
$code = humanRandomString();
} while ($this->database->query('SELECT COUNT(*) AS `count` FROM `uploads` WHERE `code` = ?', $code)->fetch()->count > 0);
if ($code === null) {
do {
$code = humanRandomString();
} while ($this->database->query('SELECT COUNT(*) AS `count` FROM `uploads` WHERE `code` = ?', $code)->fetch()->count > 0);
} else {
$existingCodeCount = $this->database->query('SELECT COUNT(*) AS `count` FROM `uploads` WHERE `code` = ?', $code)->fetch()->count;
if ($existingCodeCount > 0) {
$this->json['message'] = 'Custom url code already exists.';
return json($response, $this->json, 409);
}
}

$fileInfo = pathinfo($file->getClientFilename());
$storagePath = "$user->user_code/$code.$fileInfo[extension]";
Expand Down
65 changes: 63 additions & 2 deletions app/helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,12 @@ function dsnFromConfig(array $config): string
*/
function platform_mail($mailbox = 'no-reply'): string
{
$config = resolve('config');

if (isset($config['app_email'])) {
return $config['app_email'];
}

return $mailbox.'@'.str_ireplace('www.', '', parse_url(resolve('config')['base_url'], PHP_URL_HOST));
}
}
Expand Down Expand Up @@ -523,8 +529,63 @@ function isSecure(): bool
* @param mixed ...$pieces
* @return string
*/
function glue(...$pieces): string
function glue(...$pieces): string
{
return '/'.implode('/', $pieces);
}
}

if (!function_exists('base32_decode')) {
function base32_decode(string $secret)
{
return '/'.implode('/', $pieces);
$alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
$secret = strtoupper($secret);
$bits = '';
foreach (str_split($secret) as $c) {
$pos = strpos($alphabet, $c);
if ($pos !== false) {
$bits .= str_pad(decbin($pos), 5, '0', STR_PAD_LEFT);
}
}

$binary = '';
for ($i = 0; $i < strlen($bits); $i += 8) {
$byte = substr($bits, $i, 8);
if (strlen($byte) === 8) {
$binary .= chr(bindec($byte));
}
}

return $binary;
}
}

if (!function_exists('totp_generate_code')) {
function totp_generate_code(string $secret, int $timestamp = null): string
{
if ($timestamp === null) {
$timestamp = floor(time() / 30);
}
$key = base32_decode($secret);
$binaryTime = pack('N*', 0).pack('N*', $timestamp);
$hash = hash_hmac('sha1', $binaryTime, $key, true);
$offset = ord(substr($hash, -1)) & 0x0F;
$truncated = substr($hash, $offset, 4);
$value = unpack('N', $truncated)[1] & 0x7FFFFFFF;

return str_pad((string) ($value % 1000000), 6, '0', STR_PAD_LEFT);
}
}

if (!function_exists('verify_totp_code')) {
function verify_totp_code(string $secret, string $code, int $window = 1): bool
{
$time = floor(time() / 30);
for ($i = -$window; $i <= $window; $i++) {
if (hash_equals(totp_generate_code($secret, $time + $i), $code)) {
return true;
}
}
return false;
}
}
3 changes: 3 additions & 0 deletions app/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use App\Controllers\Auth\LoginController;
use App\Controllers\Auth\PasswordRecoveryController;
use App\Controllers\Auth\RegisterController;
use App\Controllers\Auth\TwoFactorController;
use App\Controllers\ClientController;
use App\Controllers\DashboardController;
use App\Controllers\ExportController;
Expand Down Expand Up @@ -81,6 +82,8 @@
$app->post('/recover/password/{resetToken}', [PasswordRecoveryController::class, 'recoverPassword'])->setName('recover.password');
$app->get('/login', [LoginController::class, 'show'])->setName('login.show');
$app->post('/login', [LoginController::class, 'login'])->setName('login');
$app->get('/2fa', [TwoFactorController::class, 'show'])->setName('2fa.show');
$app->post('/2fa', [TwoFactorController::class, 'verify'])->setName('2fa.verify');
$app->map(['GET', 'POST'], '/logout', [LoginController::class, 'logout'])->setName('logout');

$app->post('/upload', [UploadController::class, 'uploadEndpoint'])->setName('upload');
Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "sergix44/xbackbone",
"license": "AGPL-3.0-only",
"version": "3.7.0",
"version": "3.8.1",
"description": "A lightweight ShareX PHP backend",
"type": "project",
"require": {
Expand All @@ -25,7 +25,7 @@
"slim/slim": "^4.0",
"spatie/flysystem-dropbox": "^1.0",
"superbalist/flysystem-google-storage": "^7.2",
"twig/twig": "^2.14"
"twig/twig": "^3.11"
},
"config": {
"optimize-autoloader": true,
Expand Down
Loading
Loading