Skip to content

Commit

Permalink
Merge branch '6.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
dtdesign committed Jun 15, 2024
2 parents 9fbed01 + b171e96 commit 838607b
Show file tree
Hide file tree
Showing 14 changed files with 162 additions and 49 deletions.
59 changes: 41 additions & 18 deletions ts/WoltLabSuite/Core/Acp/Ui/Package/QuickInstallation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { isPlainObject } from "../../../Core";
import * as Language from "../../../Language";
import { innerError } from "../../../Dom/Util";
import UiDialog from "../../../Ui/Dialog";
import { StatusNotOk } from "WoltLabSuite/Core/Ajax/Error";

let codeInput: HTMLInputElement;

Expand All @@ -32,7 +33,7 @@ type Response =
type: string;
};

function detectCode(): void {
function detectCode(versionNumber: string): void {
const value = codeInput.value.trim();
if (value === "") {
innerError(codeInput, false);
Expand All @@ -55,7 +56,7 @@ function detectCode(): void {
if (json.package && json.password && json.username) {
isValid = true;

void prepareInstallation(json);
void prepareInstallation(json, versionNumber);
}
}
}
Expand All @@ -78,27 +79,49 @@ function refreshPackageDatabase() {
return refreshedPackageDatabase;
}

async function prepareInstallation(data: InstallationCode): Promise<void> {
async function prepareInstallation(data: InstallationCode, versionNumber: string): Promise<void> {
try {
AjaxStatus.show();
await refreshPackageDatabase();
} finally {
AjaxStatus.hide();
}

const response = (await dboAction("prepareInstallation", "wcf\\data\\package\\update\\PackageUpdateAction")
.payload({
packages: {
[data.package]: "",
},
authData: {
username: data.username,
password: data.password,
saveCredentials: false,
isStoreCode: true,
},
})
.dispatch()) as Response;
let response: Response;
try {
response = (await dboAction("prepareInstallation", "wcf\\data\\package\\update\\PackageUpdateAction")
.payload({
packages: {
[data.package]: "",
},
authData: {
username: data.username,
password: data.password,
saveCredentials: false,
isStoreCode: true,
},
})
.dispatch()) as Response;
} catch (e) {
if (e instanceof StatusNotOk) {
try {
const json = await e.response.clone().json();
if (typeof json.message === "string" && json.message.startsWith("Cannot find the package '")) {
codeInput.value = "";
innerError(
codeInput,
Language.getPhrase("wcf.acp.package.error.incompatibleStoreProduct", { versionNumber }),
);

return;
}
} catch {
throw e;
}
}

throw e;
}

if ("queueID" in response) {
if (response.queueID === null) {
Expand Down Expand Up @@ -129,7 +152,7 @@ async function prepareInstallation(data: InstallationCode): Promise<void> {
}
}

export function setup(): void {
export function setup(versionNumber: string): void {
codeInput = document.getElementById("quickInstallationCode") as HTMLInputElement;

codeInput.addEventListener("focus", () => {
Expand All @@ -140,6 +163,6 @@ export function setup(): void {
});

codeInput.addEventListener("input", () => {
detectCode();
detectCode(versionNumber);
});
}
1 change: 1 addition & 0 deletions ts/WoltLabSuite/Core/Ui/Reaction/Handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ class UiReactionHandler {

return false;
},
preventScroll: true,
});
}

Expand Down
3 changes: 2 additions & 1 deletion wcfsetup/install/files/acp/templates/packageStartInstall.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@
require([
"WoltLabSuite/Core/Acp/Ui/Package/QuickInstallation", "WoltLabSuite/Core/Acp/Ui/Package/Search"],
(AcpUiPackageQuickInstallation, AcpUiPackageSearch) => {
{jsphrase name='wcf.acp.package.error.incompatibleStoreProduct'}
{jsphrase name='wcf.acp.package.error.uniqueAlreadyInstalled'}
{jsphrase name='wcf.acp.package.install.title'}
{jsphrase name='wcf.acp.package.quickInstallation.code.error.invalid'}
{jsphrase name='wcf.acp.package.update.excludedPackages'}
{jsphrase name='wcf.acp.package.update.title'}
{jsphrase name='wcf.acp.package.update.unauthorized'}
AcpUiPackageQuickInstallation.setup();
AcpUiPackageQuickInstallation.setup('{$majorMinorVersion}');
new AcpUiPackageSearch();
{if $errorField === 'uploadPackage'}
Expand Down
4 changes: 2 additions & 2 deletions wcfsetup/install/files/js/WoltLabSuite.Core.min.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions wcfsetup/install/files/js/WoltLabSuite.Core.tiny.min.js

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,12 @@ public function assignVariables()
{
parent::assignVariables();

$majorMinorVersion = \preg_replace('/^(\d+\.\d+)\..*$/', '\\1', \WCF_VERSION);

WCF::getTPL()->assign([
'package' => $this->package,
'installingImportedStyle' => $this->stylePackageImportLocation != '',
'majorMinorVersion' => $majorMinorVersion,
]);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,38 @@ static function (\DOMElement $element) use ($nestedLinks) {
*/
private function isSuspiciousValue(string $value, UriInterface $href): bool
{
if (!\preg_match(FileUtil::LINK_REGEX, $value)) {
$regexMatches = \preg_match(FileUtil::LINK_REGEX, $value, $matches);
if (!$regexMatches) {
return false;
}

// The match can occur somewhere inside the value, therefore we need to
// verify that the value contains substantially more than just the link.
$testValue = StringUtil::trim($value);
$position = \mb_strpos($testValue, $matches[0]);
if ($position !== false) {
$testValue = \mb_substr($testValue, 0, $position) . \mb_substr($testValue, $position + \mb_strlen($matches[0]));
if ($testValue !== '') {
// Allow the value if the remaining string contains characters
// equal or greather than 10% of the length of the URL itself.
//
// The motivation behind this is to prevent a bad actor from
// sneaking in a few padding characters to masquerade the URL
// which could still look like part of the URL to the untrained
// eye.
//
// The minimum required characters is set to 10 to avoid short
// URLs being used to bypass this check.
$threshold = \max(
\mb_strlen($matches[0]) * 0.1,
10,
);
if (\mb_strlen($testValue) >= $threshold) {
return false;
}
}
}

try {
$value = new Uri($value);
} catch (MalformedUriException) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public function getFormElement(Option $option, $value)
WCF::getTPL()->assign([
'bbCodes' => $this->bbCodes,
'option' => $option,
'selectedBBCodes' => \explode(',', $value),
'selectedBBCodes' => \explode(',', $value ?: ''),
]);

return WCF::getTPL()->fetch('bbCodeSelectOptionType');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ class UserGroupOptionACPSearchResultProvider extends AbstractCategorizedACPSearc
*/
protected $listClassName = UserGroupOptionCategoryList::class;

private array $restrictedOptionNames = [
'admin.configuration.package.canUpdatePackage',
'admin.configuration.package.canEditServer',
'admin.user.canMailUser',
'admin.management.canManageCronjob',
'admin.management.canRebuildData',
'admin.management.canImportData',
];

/**
* @inheritDoc
*/
Expand Down Expand Up @@ -89,6 +98,10 @@ public function search($query)
continue;
}

if ($this->isUnavailableOption($userGroupOption)) {
continue;
}

$link = LinkHandler::getInstance()->getLink('UserGroupOption', ['id' => $userGroupOption->optionID]);
$categoryName = $userGroupOption->categoryName;
$parentCategories = [];
Expand Down Expand Up @@ -119,4 +132,29 @@ public function search($query)

return $results;
}

/**
* @since 6.0
*/
private function isUnavailableOption(UserGroupOption $userGroupOption): bool
{
if (!\defined('ENABLE_ENTERPRISE_MODE') || !\ENABLE_ENTERPRISE_MODE) {
return false;
}

if (!\in_array($userGroupOption->optionName, $this->restrictedOptionNames, true)) {
return false;
}

if (WCF::getUser()->hasOwnerAccess()) {
return false;
}

// Allow the option to appear if the user has this permission.
if (WCF::getSession()->getPermission($userGroupOption->optionName)) {
return false;
}

return true;
}
}
7 changes: 2 additions & 5 deletions wcfsetup/install/files/style/bbcode/code.scss
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,9 @@
}
}

.icon {
.toggleButton,
button {
flex: 0 0 auto;

&:not(:last-child) {
margin-right: 10px;
}
}
}

Expand Down
1 change: 1 addition & 0 deletions wcfsetup/install/lang/de.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1823,6 +1823,7 @@ Die Datenbestände werden sorgfältig gepflegt, aber es ist nicht ausgeschlossen
<item name="wcf.acp.package.error.noValidInstall"><![CDATA[Das angegebene Paket lässt keine Neuinstallation zu.]]></item>
<item name="wcf.acp.package.error.noValidUpdate"><![CDATA[Paket „{$package->getName()}“ kann mit dem angegebenen Archiv nicht aktualisiert werden.]]></item>
<item name="wcf.acp.package.error.majorUpgrade"><![CDATA[Das Paket aktualisiert die Installation auf eine neue Major-Version. Aus Stabilitätsgründen können Major-Upgrades ausschließlich über die Paketserver durchgeführt werden. Detaillierte Informationen zur Durchführung des Upgrades finden sich <a href="https://manual.woltlab.com/de/updates/" class="externalURL">in unserem Handbuch</a>.]]></item>
<item name="wcf.acp.package.error.incompatibleStoreProduct"><![CDATA[Das zu installierende Paket ist nicht kompatibel. {if LANGUAGE_USE_INFORMAL_VARIANT}Du kannst{else}Sie können{/if} nur Pakete installieren, die als kompatibel mit WoltLab Suite {literal}{$versionNumber}{/literal} angegeben werden.]]></item>
<item name="wcf.acp.package.identifier"><![CDATA[Bezeichner]]></item>
<item name="wcf.acp.package.information.properties"><![CDATA[Eigenschaften]]></item>
<item name="wcf.acp.package.information.title"><![CDATA[Informationen]]></item>
Expand Down
1 change: 1 addition & 0 deletions wcfsetup/install/lang/en.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1806,6 +1806,7 @@ The database is carefully maintained, but there will be always be a margin of er
<item name="wcf.acp.package.error.noValidInstall"><![CDATA[The selected package does not support an installation.]]></item>
<item name="wcf.acp.package.error.noValidUpdate"><![CDATA[Package “{$package->getName()}” cannot be updated using the selected archive.]]></item>
<item name="wcf.acp.package.error.majorUpgrade"><![CDATA[The package updates your community to a new major version. For stability reasons major upgrades may only be performed via the update servers. Detailed information regarding the upgrade process can be found <a href="https://manual.woltlab.com/en/updates/" class="externalURL">in our manual</a>.]]></item>
<item name="wcf.acp.package.error.incompatibleStoreProduct"><![CDATA[The package is incompatible and cannot be installed. You can only install packages that are listed as compatible with WoltLab Suite {literal}{$versionNumber}{/literal}.]]></item>
<item name="wcf.acp.package.identifier"><![CDATA[Identifier]]></item>
<item name="wcf.acp.package.information.properties"><![CDATA[Properties]]></item>
<item name="wcf.acp.package.information.title"><![CDATA[Details]]></item>
Expand Down

0 comments on commit 838607b

Please sign in to comment.