Skip to content

Commit b8d628d

Browse files
committed
fix: improved checks on path during update
1 parent 7e6b91d commit b8d628d

3 files changed

Lines changed: 39 additions & 4 deletions

File tree

phpmyfaq/.htaccess

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ DirectoryIndex index.php
163163
# Setup and update pages
164164
RewriteCond %{REQUEST_URI} ^(.*/)setup/
165165
RewriteRule ^(.*/)?setup/(.*) $1setup/index.php [L,QSA]
166-
RewriteRule ^update$ update/index.php [L,QSA]
166+
RewriteRule ^update$ update/ [R=301,L]
167167
RewriteCond %{REQUEST_FILENAME} !-f
168168
RewriteRule ^update/(.*) update/index.php [L,QSA]
169169
# Administration API

phpmyfaq/assets/src/configuration/update.ts

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,26 @@
1313
* @since 2023-10-22
1414
*/
1515

16+
const getBasePath = (): string => {
17+
const path = window.location.pathname;
18+
let basePath: string;
19+
if (path.endsWith('/update/index.php')) {
20+
basePath = path.slice(0, -'/update/index.php'.length);
21+
} else if (path.endsWith('/update/')) {
22+
basePath = path.slice(0, -'/update/'.length);
23+
} else if (path.endsWith('/update')) {
24+
basePath = path.slice(0, -'/update'.length);
25+
} else {
26+
basePath = path;
27+
}
28+
29+
if (!basePath.endsWith('/')) {
30+
basePath += '/';
31+
}
32+
33+
return basePath;
34+
};
35+
1636
export const handleUpdateNextStepButton = (): void => {
1737
const nextStepButton = document.getElementById('phpmyfaq-update-next-step-button') as HTMLButtonElement | null;
1838
const nextStep = document.getElementById('phpmyfaq-update-next-step') as HTMLInputElement | null;
@@ -36,8 +56,10 @@ export const handleUpdateInformation = async (): Promise<void> => {
3656

3757
if (!installedVersion) return;
3858

59+
const basePath = getBasePath();
60+
3961
try {
40-
const response = await fetch('../api/setup/check', {
62+
const response = await fetch(`${basePath}api/setup/check`, {
4163
method: 'POST',
4264
headers: {
4365
Accept: 'application/json, text/plain, */*',
@@ -102,8 +124,10 @@ export const handleConfigBackup = async (): Promise<void> => {
102124

103125
if (!installedVersion) return;
104126

127+
const basePath = getBasePath();
128+
105129
try {
106-
const response = await fetch('../api/setup/backup', {
130+
const response = await fetch(`${basePath}api/setup/backup`, {
107131
method: 'POST',
108132
headers: {
109133
Accept: 'application/json, text/plain, */*',
@@ -131,8 +155,10 @@ export const handleDatabaseUpdate = async (): Promise<void> => {
131155

132156
if (!installedVersion) return;
133157

158+
const basePath = getBasePath();
159+
134160
try {
135-
const response = await fetch('../api/setup/update-database', {
161+
const response = await fetch(`${basePath}api/setup/update-database`, {
136162
method: 'POST',
137163
headers: {
138164
Accept: 'application/json, text/plain, */*',

phpmyfaq/src/phpMyFAQ/Controller/Api/SetupController.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@
3131

3232
final class SetupController extends AbstractController
3333
{
34+
/**
35+
* Setup endpoints must be accessible without authentication,
36+
* so we override the security check from AbstractController.
37+
*/
38+
protected function isSecured(): void
39+
{
40+
// No-op: setup/update API endpoints do not require login
41+
}
42+
3443
public function check(Request $request): JsonResponse
3544
{
3645
if (trim($request->getContent()) === '') {

0 commit comments

Comments
 (0)