Skip to content

Commit

Permalink
Merge branch '3.2'
Browse files Browse the repository at this point in the history
 Es sieht so aus, als committen Sie einen Merge.
  • Loading branch information
thorsten committed Aug 29, 2023
2 parents fe0d489 + def54d4 commit 31a7ac7
Show file tree
Hide file tree
Showing 23 changed files with 149 additions and 43 deletions.
1 change: 1 addition & 0 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 7 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion api-docs/faq/post.md
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
80 changes: 80 additions & 0 deletions api-docs/faq/put.md
Original file line number Diff line number Diff line change
@@ -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": "[email protected]",
"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"
}
```
7 changes: 4 additions & 3 deletions phpmyfaq/admin/assets/src/content/tags.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion phpmyfaq/admin/header.php
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
2 changes: 1 addition & 1 deletion phpmyfaq/admin/login.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
</span>
</div>
<div class="form-check mb-3">
<input class="form-check-input" id="faqrememberme" type="checkbox"
<input class="form-check-input" id="faqrememberme" name="faqrememberme" type="checkbox"
value="rememberMe" />
<label class="form-check-label"
for="faqrememberme"><?= Translation::get('rememberMe') ?></label>
Expand Down
10 changes: 5 additions & 5 deletions phpmyfaq/admin/record.edit.php
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@
$faq->getRecord($faqData['id'], null, true);

$faqData = $faq->faqRecord;
$faqData['tags'] = implode(', ', $tagging->getAllTagsById($faqData['id']));
$queryString = 'insertentry';
} else {
$logging = new AdminLog($faqConfig);
Expand Down Expand Up @@ -227,7 +228,7 @@
}

// Set data for forms
$faqData['title'] = (isset($faqData['title']) ? Strings::htmlentities($faqData['title']) : '');
$faqData['title'] = (isset($faqData['title']) ? Strings::htmlentities($faqData['title'], ENT_HTML5 | ENT_COMPAT) : '');
$faqData['content'] =
(isset($faqData['content']) ? trim(Strings::htmlentities($faqData['content'], ENT_COMPAT, 'utf-8', true)) : '');
$faqData['tags'] = (isset($faqData['tags']) ? Strings::htmlentities($faqData['tags']) : '');
Expand Down Expand Up @@ -329,7 +330,7 @@
<div class="tab-pane active" id="tab-question-answer">
<!-- Revision -->
<?php
if ($user->perm->hasPermission($currentUserId, 'changebtrevs')) {
if ($user->perm->hasPermission($currentUserId, 'changebtrevs') && $action === 'editentry') {
$faqRevision = new Revision($faqConfig);
$revisions = $faqRevision->get($faqData['id'], $faqData['lang'], $faqData['author']);
if (count($revisions)) { ?>
Expand Down Expand Up @@ -395,7 +396,7 @@ class="form-select">
<input type="text" name="question" id="question"
class="form-control form-control-lg"
placeholder="<?= Translation::get('ad_entry_theme') ?>"
value="<?= Strings::htmlentities($faqData['title'], ENT_COMPAT) ?>">
value="<?= $faqData['title'] ?>">
</div>

<!-- Answer -->
Expand Down Expand Up @@ -512,8 +513,7 @@ class="form-control">
<div class="col-lg-10">
<input type="text" name="tags" id="tags" value="<?= $faqData['tags'] ?>"
autocomplete="off"
class="form-control pmf-tags-autocomplete"
data-tag-list="<?= $faqData['tags'] ?>">
class="form-control pmf-tags-autocomplete">
<small id="tagsHelp"
class="form-text visually-hidden"><?= Translation::get('msgShowHelp') ?></small>
</div>
Expand Down
2 changes: 1 addition & 1 deletion phpmyfaq/admin/record.save.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@

// Create ChangeLog entry
$changelog = new Changelog($faqConfig);
$changelog->add($recordId, $user->getUserId(), nl2br((string) $changed), $recordLang, $revisionId);
$changelog->add($recordId, $user->getUserId(), (string) $changed, $recordLang, $revisionId);

// Create the visit entry
$visits = new Visits($faqConfig);
Expand Down
2 changes: 1 addition & 1 deletion phpmyfaq/admin/record.show.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@
]
);

if (is_numeric($searchTerm)) {
if (is_numeric($searchTerm) && $faqConfig->get('search.searchForSolutionId')) {
$search->setMatchingColumns([$fdTable . '.solution_id']);
} else {
$search->setMatchingColumns([$fdTable . '.thema', $fdTable . '.content', $fdTable . '.keywords']);
Expand Down
27 changes: 18 additions & 9 deletions phpmyfaq/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@
$faq->setUser($currentUser);
$faq->setGroups($currentGroups);

if ($recordId > 0) {
if ($request->getMethod() === 'GET' && $recordId > 0) {
$faq->getRecord($recordId);
$result = $faq->faqRecord;

Expand All @@ -310,7 +310,7 @@
}

//
// POST
// POST or PUT
//
if ($faqConfig->get('api.apiClientToken') !== $request->headers->get('x-pmf-token')) {
$response->setStatusCode(Response::HTTP_UNAUTHORIZED);
Expand All @@ -329,6 +329,11 @@

$postData = json_decode(file_get_contents('php://input'), true, 512, JSON_THROW_ON_ERROR);

if (isset($postData['faq-id'])) {
$faqId = Filter::filterVar($postData['faq-id'], FILTER_VALIDATE_INT);
} else {
$faqId = null;
}
$languageCode = Filter::filterVar($postData['language'], FILTER_SANITIZE_SPECIAL_CHARS);
$categoryId = Filter::filterVar($postData['category-id'], FILTER_VALIDATE_INT);
if (isset($postData['category-name'])) {
Expand Down Expand Up @@ -377,14 +382,18 @@
->setComment(false)
->setNotes('');

$faqId = $faq->create($faqData);
if (is_null($faqId)) {
$faqId = $faq->create($faqData);
} else {
$faqData->setId($faqId);
$faqData->setRevisionId(0);
$faq->update($faqData);
}

$faqMetaData = new FaqMetaData($faqConfig);
$faqMetaData
->setFaqId($faqId)
->setFaqLanguage($languageCode)
->setCategories($categories)
->save();
if ($request->getMethod() !== 'PUT') {
$faqMetaData = new FaqMetaData($faqConfig);
$faqMetaData->setFaqId($faqId)->setFaqLanguage($languageCode)->setCategories($categories)->save();
}

$result = [
'stored' => true
Expand Down
2 changes: 1 addition & 1 deletion phpmyfaq/faq.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
$currentCategory = $cat;

$request = Request::createFromGlobals();
$faqId = Filter::filterVar($request->query->get('id'), FILTER_VALIDATE_INT);
$faqId = Filter::filterVar($request->query->get('id'), FILTER_VALIDATE_INT, 0);
$solutionId = Filter::filterVar($request->query->get('solution_id'), FILTER_VALIDATE_INT);
$highlight = Filter::filterVar($request->query->get('highlight'), FILTER_SANITIZE_SPECIAL_CHARS);
$bookmarkAction = Filter::filterVar($request->query->get('bookmark_action'), FILTER_SANITIZE_SPECIAL_CHARS);
Expand Down
5 changes: 2 additions & 3 deletions phpmyfaq/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,8 @@
//
// Found a record ID?
//
$id = Filter::filterVar($request->query->get('id'), FILTER_VALIDATE_INT);
if (!is_null($id)) {
$id = Filter::filterVar($request->query->get('id'), FILTER_VALIDATE_INT, 0);
if ($id !== 0) {
$faq->getRecord($id);
$title = ' - ' . $faq->faqRecord['title'];
$keywords = ',' . $faq->faqRecord['keywords'];
Expand All @@ -350,7 +350,6 @@
$faqLink->itemTitle = $faq->faqRecord['title'];
$currentPageUrl = $faqLink->toString(true);
} else {
$id = '';
$title = ' - ' . System::getPoweredByString();
$keywords = '';
$metaDescription = str_replace('"', '', (string) $faqConfig->get('main.metaDescription'));
Expand Down
2 changes: 1 addition & 1 deletion phpmyfaq/search.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
$tagHelper->setTaggingIds($tagIds);

foreach ($tagIds as $tagId) {
if (!isset($tags[$tagId])) {
if (!isset($tags[$tagId]) && is_numeric($tagId)) {
$tags[$tagId] = $tagging->getTagNameById($tagId);
}
}
Expand Down
3 changes: 2 additions & 1 deletion phpmyfaq/show.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use phpMyFAQ\Helper\CategoryHelper;
use phpMyFAQ\Language\Plurals;
use phpMyFAQ\Link;
use phpMyFAQ\Strings;
use phpMyFAQ\Translation;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
Expand Down Expand Up @@ -114,7 +115,7 @@
[
'categoryHeader' => Translation::get('msgEntriesIn') . $categoryData->getName(),
'categoryFaqsHeader' => $categoryData->getName(),
'categoryDescription' => $categoryData->getDescription(),
'categoryDescription' => Strings::htmlentities($categoryData->getDescription()),
'categorySubsHeader' => Translation::get('msgSubCategories'),
'categoryContent' => $records,
'subCategoryContent' => $subCategoryContent,
Expand Down
2 changes: 1 addition & 1 deletion phpmyfaq/src/phpMyFAQ/Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@ public function getPath(
$categoryId[$key]
);
$oLink = new Link($url, $this->config);
$oLink->text = sprintf('<span>%s</span>', Strings::htmlentities($category));
$oLink->text = Strings::htmlentities($category);
$oLink->itemTitle = Strings::htmlentities($category);
$oLink->tooltip = Strings::htmlentities($description[$key] ?? '');
if (0 === $key) {
Expand Down
2 changes: 1 addition & 1 deletion phpmyfaq/src/phpMyFAQ/Database/Mysqli.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public function connect(
}

// change character set to UTF-8
if (!$this->conn->set_charset('utf8')) {
if (!$this->conn->set_charset('utf8mb4')) {
Database::errorPage($this->error());
}

Expand Down
4 changes: 2 additions & 2 deletions phpmyfaq/src/phpMyFAQ/Faq.php
Original file line number Diff line number Diff line change
Expand Up @@ -2404,8 +2404,8 @@ public function getStickyRecords(): array

if (count($result) > 0) {
foreach ($result as $row) {
$output['title'][] = Utils::makeShorterText($row['question'], 8);
$output['preview'][] = $row['question'];
$output['title'][] = Utils::makeShorterText(Strings::htmlentities($row['question']), 8);
$output['preview'][] = Strings::htmlentities($row['question']);
$output['url'][] = Strings::htmlentities($row['url']);
}
} else {
Expand Down
6 changes: 5 additions & 1 deletion phpmyfaq/src/phpMyFAQ/Helper/FaqHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,10 @@ public function createOverview(Category $category, Faq $faq, string $language =
$lastCategory = 0;
foreach ($faq->faqRecords as $data) {
if (!is_null($data['category_id']) && $data['category_id'] !== $lastCategory) {
$output .= sprintf('<h3>%s</h3>', $category->getPath($data['category_id'], ' &raquo; '));
$output .= sprintf(
'<h3>%s</h3>',
$this->cleanUpContent($category->getPath($data['category_id'], ' &raquo; '))
);
}

$output .= sprintf('<h4>%s</h4>', Strings::htmlentities($data['title']));
Expand Down Expand Up @@ -239,6 +242,7 @@ public function cleanUpContent(string $content): string
{
$htmlSanitizer = new HtmlSanitizer(
(new HtmlSanitizerConfig())
->withMaxInputLength(40000)
->allowSafeElements()
->allowStaticElements()
->allowRelativeLinks()
Expand Down
Loading

0 comments on commit 31a7ac7

Please sign in to comment.