diff --git a/API.md b/API.md
index 796a444d92..d64ba6697a 100644
--- a/API.md
+++ b/API.md
@@ -52,6 +52,7 @@ be acquired from the admin configuration.
### FAQ related APIs
- [Add FAQ](api-docs/faq/post.md): `POST /api/v2.2/faq`
+- [Update FAQ](api-docs/faq/put.md): `PUT /api/v2.2/faq/:categoryId/:faqId`
- [Add question](api-docs/question/post.md): `POST /api/v2.2/question`
### Groups related APIs
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4c6cc57623..331b5a6d96 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,7 +15,7 @@ This is a log of major user-visible changes in each phpMyFAQ release.
- added experimental support for PHP 8.3 (Thorsten)
- updated to PNPM (Thorsten)
-### phpMyFAQ v3.2.0 - 2023-07-
+### phpMyFAQ v3.2.0-RC.4 - 2023-08-
- changed PHP requirement to PHP 8.1.0 or later (Thorsten)
- changed to HTTPS as new default (Thorsten)
@@ -28,7 +28,7 @@ This is a log of major user-visible changes in each phpMyFAQ release.
- added 2FA (Two-Factor Authentication) (Jan Harms)
- added experimental Azure AD login (Thorsten)
- added option to use Google ReCaptcha (Thorsten)
-- added REST API v2.2 to fetch groups and add categories (Thorsten)
+- added REST API v2.2 to fetch groups, add categories, and update FAQs (Thorsten)
- added verification of backup files (Thorsten)
- added option to disable questions and notifications (Thorsten)
- added new options for more flexibility (Jan Harms)
@@ -47,6 +47,11 @@ This is a log of major user-visible changes in each phpMyFAQ release.
- updated Japanese translation (Advanced Bear)
- updated Dutch translation (Bob Coret)
+### phpMyFAQ v3.1.17 - 2023-08-27
+
+- fixed multiple security vulnerabilities (Thorsten)
+- fixed minor bugs (Thorsten)
+
### phpMyFAQ v3.1.16 - 2023-07-16
- fixed multiple security vulnerabilities (Thorsten)
diff --git a/api-docs/faq/post.md b/api-docs/faq/post.md
index e94fbe9d22..bd3d7f1e13 100644
--- a/api-docs/faq/post.md
+++ b/api-docs/faq/post.md
@@ -41,7 +41,7 @@ mapped, the category ID from the name will be used. If the category name cannot
```json
{
"language": "de",
- "category-id": "1",
+ "category-id": 1,
"category-name": "Queen Songs",
"question": "Is this the world we created?",
"answer": "What did we do it for, is this the world we invaded, against the law, so it seems in the end, is this what we're all living for today",
diff --git a/api-docs/faq/put.md b/api-docs/faq/put.md
new file mode 100644
index 0000000000..3c49882758
--- /dev/null
+++ b/api-docs/faq/put.md
@@ -0,0 +1,80 @@
+# Update a FAQ
+
+Used to update a FAQ in one existing category.
+
+**URL** : `/api/v2.1/faq`
+
+**HTTP Header** :
+
+```
+Accept-Language: [language code]
+X-PMF-Token: [phpMyFAQ client API Token, generated in admin backend]
+Content-Type: application/json
+```
+
+**Method** : `POST`
+
+**Auth required** : NO
+
+**Data constraints**
+
+```json
+{
+ "faq-id": "[faq id as integer value, required value]",
+ "language": "[language code, required value]",
+ "category-id": "[category id as integer value, required value]",
+ "question": "[question in plain text, required value]",
+ "answer": "[question in plain text, required value]",
+ "keywords": "[keywords in comma separated plain text or empty string, required value]",
+ "author": "[author name in plain text, required value]",
+ "email": "[author email in plain text, required value]",
+ "is-active": "true/false, required value",
+ "is-sticky": "true/false, required value"
+}
+```
+
+**Data example**
+
+```json
+{
+ "faq-id": 1,
+ "language": "de",
+ "category-id": 1,
+ "question": "Is this the world we created?",
+ "answer": "What did we do it for, is this the world we invaded, against the law, so it seems in the end, is this what we're all living for today",
+ "keywords": "phpMyFAQ, FAQ, Foo, Bar",
+ "author": "Freddie Mercury",
+ "email": "freddie.mercury@example.org",
+ "is-active": "true",
+ "is-sticky": "false"
+}
+```
+
+## Success Response
+
+**Condition** : If all putted data is correct.
+
+**Code** : `200 OK`
+
+**Content example**
+
+```json
+{
+ "stored": true
+}
+```
+
+## Error Responses
+
+**Condition** : If FAQ ID or category id cannot be mapped to valid IDs
+
+**Code** : `404 Not Found`
+
+**Content** :
+
+```json
+{
+ "stored": false,
+ "error": "error message"
+}
+```
diff --git a/phpmyfaq/admin/assets/src/content/tags.js b/phpmyfaq/admin/assets/src/content/tags.js
index 7afd275402..b27c013853 100644
--- a/phpmyfaq/admin/assets/src/content/tags.js
+++ b/phpmyfaq/admin/assets/src/content/tags.js
@@ -110,14 +110,15 @@ export const handleTags = () => {
input: tagsAutocomplete,
minLength: 1,
onSelect: async (item, input) => {
- let currentTags = input.getAttribute('data-tag-list');
+ let currentTags = input.value;
+ let currentTagsArray = currentTags.split(',');
if (currentTags.length === 0) {
currentTags = item.tagName;
} else {
- currentTags = currentTags + ', ' + item.tagName;
+ currentTagsArray[currentTagsArray.length - 1] = item.tagName;
+ currentTags = currentTagsArray.join(',');
}
input.value = currentTags;
- input.setAttribute('data-tag-list', currentTags);
},
fetch: async (text, callback) => {
let match = text.toLowerCase();
diff --git a/phpmyfaq/admin/header.php b/phpmyfaq/admin/header.php
index 9ede23ad98..7537b1a8f2 100644
--- a/phpmyfaq/admin/header.php
+++ b/phpmyfaq/admin/header.php
@@ -110,7 +110,7 @@
$secLevelEntries['backup'] = $adminHelper->addMenuEntry('editconfig', 'backup', 'ad_menu_backup', $action);
$secLevelEntries['config'] = $adminHelper->addMenuEntry('editconfig', 'config', 'ad_menu_editconfig', $action);
-$secLevelEntries['config'] .= $adminHelper->addMenuEntry('editconfig', 'system', 'ad_system_info', $action, false);
+$secLevelEntries['config'] .= $adminHelper->addMenuEntry('editconfig', 'system', 'ad_system_info', $action);
$secLevelEntries['config'] .= $adminHelper->addMenuEntry(
'editinstances+addinstances+delinstances',
'instances',
diff --git a/phpmyfaq/admin/login.php b/phpmyfaq/admin/login.php
index 1373a15492..ea75b1c0a5 100644
--- a/phpmyfaq/admin/login.php
+++ b/phpmyfaq/admin/login.php
@@ -75,7 +75,7 @@