[NC] Upgrade to Nextcloud 25.0.4

This still uses a fork of nextcloud/forms and reenables that plugin.

Since version 25 of Nextcloud uses the 2.X line of the nextcloud/mail
plugin, which already includes our patches, we can get rid of them to
easen future maintenance.
main
Evilham 2023-02-27 19:38:41 +01:00
parent a27f44262b
commit e5d2a20d37
No known key found for this signature in database
GPG Key ID: AE3EE30D970886BF
14 changed files with 106 additions and 514 deletions

View File

@ -82,11 +82,9 @@ COPY saml.sh /
COPY template.docx /
## Save current forms plugin hash
#RUN sh -c 'curl -sL https://api.github.com/repos/3iPunt/nextcloud_forms/commits/STABLE_25 | jq -r .sha > /forms.hash'
RUN sh -c 'curl -sL https://api.github.com/repos/3iPunt/nextcloud_forms/commits/STABLE_25 | jq -r .sha > /forms.hash'
## And current forms code
#RUN sh -c 'curl -sL "https://github.com/3iPunt/nextcloud_forms/archive/$(cat /forms.hash).zip" > /forms.zip'
# Mail app patches. To remove in NC 25
COPY nc_mail/ /nc_mail/
RUN sh -c 'curl -sL "https://github.com/3iPunt/nextcloud_forms/archive/$(cat /forms.hash).zip" > /forms.zip'
# Setup cron as documented in:
# https://github.com/nextcloud/docker/blob/master/.examples/dockerfiles/cron/fpm-alpine/Dockerfile

View File

@ -2,7 +2,4 @@
# file license author source
nginx.conf AGPL-3.0-or-later https://github.com/nextcloud/ https://raw.githubusercontent.com/nextcloud/docker/04ab3157e4f1197a9f8f4b91cf2430586356dd9a/.examples/docker-compose/with-nginx-proxy/postgres/fpm/web/nginx.conf
supervisord.conf AGPL-3.0-or-later https://github.com/nextcloud/ https://raw.githubusercontent.com/nextcloud/docker/04ab3157e4f1197a9f8f4b91cf2430586356dd9a/.examples/dockerfiles/cron/fpm-alpine/supervisord.conf
nc_mail/appinfo/info.xml AGPL-3.0-or-later https://github.com/nextcloud/ https://raw.githubusercontent.com/nextcloud/mail/v1.15.2/appinfo/info.xml
nc_mail/lib/Command/UpdateAccount.php AGPL-3.0-or-later https://github.com/nextcloud/ https://raw.githubusercontent.com/nextcloud/mail/1e777a1783254bd4b7f69f39a6c5123323f8b701/lib/Command/UpdateAccount.php
nc_mail/lib/Db/MailAccountMapper.php AGPL-3.0-or-later https://github.com/nextcloud/ https://raw.githubusercontent.com/nextcloud/mail/1e777a1783254bd4b7f69f39a6c5123323f8b701/lib/Db/MailAccountMapper.php
src/themes/dd/core/templates/layout.user.php AGPL-3.0-or-later https://github.com/nextcloud/ https://raw.githubusercontent.com/nextcloud/server/v21.0.9/core/templates/layout.user.php
src/themes/dd/core/templates/layout.user.php AGPL-3.0-or-later https://github.com/nextcloud/ https://raw.githubusercontent.com/nextcloud/server/v25.0.4/core/templates/layout.user.php

View File

@ -20,7 +20,10 @@ plugin_status() {
printf "%s\t%s" "enabled" "${version}"
else
version="$(echo "${plugins_state}" | jq -r ".disabled.${plugin}")"
if [ "${version}" != "null" ]; then
is_available="$(echo "${plugins_state}" | jq -r \
--arg plugin "${plugin}" \
'.disabled | to_entries[] | select(.key == $plugin) | .key')"
if [ "${is_available}" = "${plugin}" ]; then
printf "%s\t%s" "disabled" "${version}"
else
printf "%s\t%s" "n/a" "n/a"
@ -57,7 +60,7 @@ occupgrade
# Operators should instead rely on the environment variables to ease deployment
# EXTRA_PLUGINS_ENABLE and EXTRA_PLUGINS_DISABLE
CORE_PLUGINS_ENABLE="user_saml,bruteforcesettings,polls,calendar,spreed,bbb,mail,ownpad,onlyoffice"
CORE_PLUGINS_DISABLE="firstrunwizard,recommendations,dashboard,circles,forms"
CORE_PLUGINS_DISABLE="firstrunwizard,recommendations,dashboard,circles"
if [ "${DISABLE_CLAMAV:-true}" = "false" ]; then
CORE_PLUGINS_ENABLE="${CORE_PLUGINS_ENABLE},files_antivirus"
@ -72,7 +75,7 @@ PLUGINS="${CORE_PLUGINS_ENABLE},${CORE_PLUGINS_DISABLE},${EXTRA_PLUGINS_ENABLE:-
# Install all plugins
# shellcheck disable=SC2086 # We do want multiple arguments
for plugin in $(echo "${PLUGINS}" | tr ',' '\n'); do
if plugin_status "${plugin}" | grep -q "n/a"; then
if plugin_status "${plugin}" | grep -qE "^n/a"; then
echo "--> Installing ${plugin}"
./occ --no-warnings app:install "${plugin}"
fi
@ -117,40 +120,32 @@ done
occupgrade
# Temporary patch while upstream lands our changes
# See: https://github.com/nextcloud/mail/pull/6908
for f in appinfo/info.xml lib/Command/UpdateAccount.php lib/Db/MailAccountMapper.php; do
install -m 0644 -o www-data -g www-data "/nc_mail/$f" "/var/www/html/custom_apps/mail/$f"
done
occupgrade
## Forms
# TODO: This is broken in NC 24 due to:
# https://github.com/nextcloud/forms/pull/1149/files
## TODO: request explanations and reduce upstream diff
## This is what is being used: https://github.com/juanan3ip/form
#FORMS_EXPECTED_HASH="$(cat /forms.hash)"
#FORMS_DIR="/var/www/html/custom_apps/forms"
#FORMS_HASH=""
#if [ -f "${FORMS_DIR}.hash" ]; then
# FORMS_HASH="$(cat "${FORMS_DIR}.hash")"
#fi
#if [ "${FORMS_EXPECTED_HASH}" != "${FORMS_HASH}" ]; then
# # Remove old plugin
# rm -rf "${FORMS_DIR}"
# # Install new one
# unzip -o /forms.zip -d /tmp
# mv "/tmp/form-${FORMS_EXPECTED_HASH}" "${FORMS_DIR}"
# # Perform config / install
# npm --prefix "${FORMS_DIR}" install
# composer --ignore-platform-req=ext-dom -d"${FORMS_DIR}" install --no-dev -o
# # Place hash marker
# cp /forms.hash "${FORMS_DIR}.hash"
#fi
#if plugin_status "${plugin}" | grep -qE "^disabled"; then
# ./occ app:enable forms
#fi
## This should be upstreamed, see:
## https://github.com/juanan3ip/form/issues/76
## This is what is being used: https://github.com/3iPunt/nextcloud_forms
FORMS_EXPECTED_HASH="$(cat /forms.hash)"
FORMS_DIR="/var/www/html/custom_apps/forms"
FORMS_HASH=""
if [ -f "${FORMS_DIR}.hash" ]; then
FORMS_HASH="$(cat "${FORMS_DIR}.hash")"
fi
if [ "${FORMS_EXPECTED_HASH}" != "${FORMS_HASH}" ]; then
# Remove old plugin
rm -rf "${FORMS_DIR}"
# Install new one
unzip -o /forms.zip -d /tmp
mv "/tmp/nextcloud_forms-${FORMS_EXPECTED_HASH}" "${FORMS_DIR}"
# Perform config / install
npm --prefix "${FORMS_DIR}" install
composer --ignore-platform-req=ext-dom -d"${FORMS_DIR}" install --no-dev -o
# Place hash marker
cp /forms.hash "${FORMS_DIR}.hash"
fi
if plugin_status "${plugin}" | grep -qE "^disabled"; then
./occ app:enable forms
fi
#
#occupgrade

View File

@ -1,75 +0,0 @@
<?xml version="1.0"?>
<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>mail</id>
<name>Mail</name>
<summary>💌 A mail app for Nextcloud</summary>
<description><![CDATA[**💌 A mail app for Nextcloud**
- **🚀 Integration with other Nextcloud apps!** Currently Contacts, Calendar & Files more to come.
- **📥 Multiple mail accounts!** Personal and company account? No problem, and a nice unified inbox. Connect any IMAP account.
- **🔒 Send & receive encrypted mails!** Using the great [Mailvelope](https://mailvelope.com) browser extension.
- **🙈 Were not reinventing the wheel!** Based on the great [Horde](https://horde.org) libraries.
- **📬 Want to host your own mail server?** We do not have to reimplement this as you could set up [Mail-in-a-Box](https://mailinabox.email)!
]]></description>
<version>1.15.2</version>
<licence>agpl</licence>
<author>Greta Doçi</author>
<author homepage="https://github.com/nextcloud/groupware">Nextcloud Groupware Team</author>
<namespace>Mail</namespace>
<documentation>
<user>https://github.com/nextcloud/mail/blob/main/doc/user.md</user>
<admin>https://github.com/nextcloud/mail/blob/main/doc/admin.md</admin>
<developer>https://github.com/nextcloud/mail/blob/main/doc/developer.md</developer>
</documentation>
<category>social</category>
<category>office</category>
<website>https://github.com/nextcloud/mail#readme</website>
<bugs>https://github.com/nextcloud/mail/issues</bugs>
<repository type="git">https://github.com/nextcloud/mail.git</repository>
<screenshot>https://user-images.githubusercontent.com/1374172/79554966-278e1600-809f-11ea-82ea-7a0d72a2704f.png</screenshot>
<dependencies>
<php min-version="7.4" max-version="8.1" />
<nextcloud min-version="23" max-version="25" />
</dependencies>
<background-jobs>
<job>OCA\Mail\BackgroundJob\CleanupJob</job>
<job>OCA\Mail\BackgroundJob\OutboxWorkerJob</job>
</background-jobs>
<repair-steps>
<post-migration>
<step>OCA\Mail\Migration\AddMissingDefaultTags</step>
<step>OCA\Mail\Migration\AddMissingMessageIds</step>
<step>OCA\Mail\Migration\FixCollectedAddresses</step>
<step>OCA\Mail\Migration\FixBackgroundJobs</step>
<step>OCA\Mail\Migration\MakeItineraryExtractorExecutable</step>
<step>OCA\Mail\Migration\ProvisionAccounts</step>
<step>OCA\Mail\Migration\RepairMailTheads</step>
</post-migration>
</repair-steps>
<commands>
<command>OCA\Mail\Command\AddMissingTags</command>
<command>OCA\Mail\Command\CleanUp</command>
<command>OCA\Mail\Command\CreateAccount</command>
<command>OCA\Mail\Command\CreateTagMigrationJobEntry</command>
<command>OCA\Mail\Command\DeleteAccount</command>
<command>OCA\Mail\Command\DiagnoseAccount</command>
<command>OCA\Mail\Command\ExportAccount</command>
<command>OCA\Mail\Command\ExportAccountThreads</command>
<command>OCA\Mail\Command\SyncAccount</command>
<command>OCA\Mail\Command\TrainAccount</command>
<command>OCA\Mail\Command\Thread</command>
<command>OCA\Mail\Command\UpdateAccount</command>
</commands>
<settings>
<admin>OCA\Mail\Settings\AdminSettings</admin>
</settings>
<navigations>
<navigation>
<name>Mail</name>
<route>mail.page.index</route>
<icon>mail.svg</icon>
<order>3</order>
</navigation>
</navigations>
</info>

View File

@ -1,179 +0,0 @@
<?php
/**
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Maadix
*
* Mail
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OCA\Mail\Command;
use OCA\Mail\Db\MailAccountMapper;
use OCP\Security\ICrypto;
use OCP\AppFramework\Db\DoesNotExistException;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class UpdateAccount extends Command {
public const ARGUMENT_ACCOUNT_ID = 'account-id';
public const ARGUMENT_NAME = 'name';
public const ARGUMENT_EMAIL = 'email';
public const ARGUMENT_AUTH_METHOD = 'auth-method';
public const ARGUMENT_IMAP_HOST = 'imap-host';
public const ARGUMENT_IMAP_PORT = 'imap-port';
public const ARGUMENT_IMAP_SSL_MODE = 'imap-ssl-mode';
public const ARGUMENT_IMAP_USER = 'imap-user';
public const ARGUMENT_IMAP_PASSWORD = 'imap-password';
public const ARGUMENT_SMTP_HOST = 'smtp-host';
public const ARGUMENT_SMTP_PORT = 'smtp-port';
public const ARGUMENT_SMTP_SSL_MODE = 'smtp-ssl-mode';
public const ARGUMENT_SMTP_USER = 'smtp-user';
public const ARGUMENT_SMTP_PASSWORD = 'smtp-password';
/** @var mapper */
private $mapper;
/** @var ICrypto */
private $crypto;
public function __construct(MailAccountMapper $mapper, ICrypto $crypto) {
parent::__construct();
$this->mapper = $mapper;
$this->crypto = $crypto;
}
/**
* @return void
*/
protected function configure() {
$this->setName('mail:account:update');
$this->setDescription('Update a user\'s IMAP account');
$this->addArgument(self::ARGUMENT_ACCOUNT_ID, InputArgument::REQUIRED);
$this->addOption(self::ARGUMENT_NAME, '', InputOption::VALUE_OPTIONAL);
$this->addOption(self::ARGUMENT_EMAIL, '', InputOption::VALUE_OPTIONAL);
$this->addOption(self::ARGUMENT_IMAP_HOST, '', InputOption::VALUE_OPTIONAL);
$this->addOption(self::ARGUMENT_IMAP_PORT, '', InputOption::VALUE_OPTIONAL);
$this->addOption(self::ARGUMENT_IMAP_SSL_MODE, '', InputOption::VALUE_OPTIONAL);
$this->addOption(self::ARGUMENT_IMAP_USER, '', InputOption::VALUE_OPTIONAL);
$this->addOption(self::ARGUMENT_IMAP_PASSWORD, '', InputOption::VALUE_OPTIONAL);
$this->addOption(self::ARGUMENT_SMTP_HOST, '', InputOption::VALUE_OPTIONAL);
$this->addOption(self::ARGUMENT_SMTP_PORT, '', InputOption::VALUE_OPTIONAL);
$this->addOption(self::ARGUMENT_SMTP_SSL_MODE, '', InputOption::VALUE_OPTIONAL);
$this->addOption(self::ARGUMENT_SMTP_USER, '', InputOption::VALUE_OPTIONAL);
$this->addOption(self::ARGUMENT_SMTP_PASSWORD, '', InputOption::VALUE_OPTIONAL);
$this->addOption(self::ARGUMENT_AUTH_METHOD, '', InputOption::VALUE_OPTIONAL);
}
protected function execute(InputInterface $input, OutputInterface $output): int {
$accountId = (int)$input->getArgument(self::ARGUMENT_ACCOUNT_ID);
$name = $input->getOption(self::ARGUMENT_NAME);
$email = $input->getOption(self::ARGUMENT_EMAIL);
$imapHost = $input->getOption(self::ARGUMENT_IMAP_HOST);
$imapPort = $input->getOption(self::ARGUMENT_IMAP_PORT);
$imapSslMode = $input->getOption(self::ARGUMENT_IMAP_SSL_MODE);
$imapUser = $input->getOption(self::ARGUMENT_IMAP_USER);
$imapPassword = $input->getOption(self::ARGUMENT_IMAP_PASSWORD);
$smtpHost = $input->getOption(self::ARGUMENT_SMTP_HOST);
$smtpPort = $input->getOption(self::ARGUMENT_SMTP_PORT);
$smtpSslMode = $input->getOption(self::ARGUMENT_SMTP_SSL_MODE);
$smtpUser = $input->getOption(self::ARGUMENT_SMTP_USER);
$smtpPassword = $input->getOption(self::ARGUMENT_SMTP_PASSWORD);
$authMethod = $input->getOption(self::ARGUMENT_AUTH_METHOD);
try {
$mailAccount = $this->mapper->findById($accountId);
} catch (DoesNotExistException $e) {
$output->writeln("<error>No Email Account found with ID $accountId </error>");
return 1;
}
$output->writeLn("<info>Found account with email: " . $mailAccount->getEmail() . "</info>");
//ACCOUNT OPTIONS
if ($input->getOption(self::ARGUMENT_NAME)) {
$mailAccount->setName($name);
}
if ($input->getOption(self::ARGUMENT_EMAIL)) {
$mailAccount->setEmail($email);
}
//AUTH METHOD
if ($input->getOption(self::ARGUMENT_AUTH_METHOD)) {
$mailAccount->setAuthMethod($authMethod);
}
//INBOUND
if ($input->getOption(self::ARGUMENT_IMAP_HOST)) {
$mailAccount->setInboundHost($imapHost);
}
if ($input->getOption(self::ARGUMENT_IMAP_PORT)) {
$mailAccount->setInboundPort((int) $imapPort);
}
if ($input->getOption(self::ARGUMENT_IMAP_SSL_MODE)) {
$mailAccount->setInboundSslMode($imapSslMode);
}
if ($input->getOption(self::ARGUMENT_IMAP_PASSWORD)) {
$mailAccount->setInboundPassword($this->crypto->encrypt($imapPassword));
}
if ($input->getOption(self::ARGUMENT_SMTP_USER)) {
$mailAccount->setInboundUser($imapUser);
}
// OUTBOUND
if ($input->getOption(self::ARGUMENT_SMTP_HOST)) {
$mailAccount->setOutboundHost($smtpHost);
}
if ($input->getOption(self::ARGUMENT_SMTP_PORT)) {
$mailAccount->setOutboundPort((int) $smtpPort);
}
if ($input->getOption(self::ARGUMENT_SMTP_SSL_MODE)) {
$mailAccount->setOutboundSslMode($smtpSslMode);
}
if ($input->getOption(self::ARGUMENT_SMTP_PASSWORD)) {
$mailAccount->setOutboundPassword($this->crypto->encrypt($smtpPassword));
}
if ($input->getOption(self::ARGUMENT_SMTP_USER)) {
$mailAccount->setOutboundUser($smtpUser);
}
$this->mapper->save($mailAccount);
$output->writeln("<info>Account " . $mailAccount->getEmail() . " with ID $accountId succesfully updated </info>");
return 0;
}
}

View File

@ -1,171 +0,0 @@
<?php
declare(strict_types=1);
/**
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Christoph Wurst <wurst.christoph@gmail.com>
* @author Lukas Reschke <lukas@owncloud.com>
* @author Thomas Müller <thomas.mueller@tmit.eu>
*
* Mail
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OCA\Mail\Db;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
use OCP\AppFramework\Db\QBMapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
use OCP\IUser;
/**
* @template-extends QBMapper<MailAccount>
*/
class MailAccountMapper extends QBMapper {
/**
* @param IDBConnection $db
*/
public function __construct(IDBConnection $db) {
parent::__construct($db, 'mail_accounts');
}
/** Finds an Mail Account by id
*
* @param string $userId
* @param int $accountId
*
* @return MailAccount
*
* @throws DoesNotExistException
*/
public function find(string $userId, int $accountId): MailAccount {
$qb = $this->db->getQueryBuilder();
$query = $qb
->select('*')
->from($this->getTableName())
->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId)))
->andWhere($qb->expr()->eq('id', $qb->createNamedParameter($accountId)));
return $this->findEntity($query);
}
/**
* Finds an mail account by id
*
* @return MailAccount
* @throws DoesNotExistException
*/
public function findById(int $id): MailAccount {
$qb = $this->db->getQueryBuilder();
$query = $qb
->select('*')
->from($this->getTableName())
->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
return $this->findEntity($query);
}
/**
* Finds all Mail Accounts by user id existing for this user
*
* @param string $userId the id of the user that we want to find
*
* @return MailAccount[]
*/
public function findByUserId(string $userId): array {
$qb = $this->db->getQueryBuilder();
$query = $qb
->select('*')
->from($this->getTableName())
->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId)));
return $this->findEntities($query);
}
/**
* @throws DoesNotExistException
* @throws MultipleObjectsReturnedException
*/
public function findProvisionedAccount(IUser $user): MailAccount {
$qb = $this->db->getQueryBuilder();
$query = $qb
->select('*')
->from($this->getTableName())
->where(
$qb->expr()->eq('user_id', $qb->createNamedParameter($user->getUID())),
$qb->expr()->isNotNull('provisioning_id')
);
return $this->findEntity($query);
}
/**
* Saves an User Account into the database
*
* @param MailAccount $account
*
* @return MailAccount
*/
public function save(MailAccount $account): MailAccount {
if ($account->getId() === null) {
return $this->insert($account);
}
return $this->update($account);
}
public function deleteProvisionedAccounts(int $provisioningId): void {
$qb = $this->db->getQueryBuilder();
$delete = $qb->delete($this->getTableName())
->where($qb->expr()->eq('provisioning_id', $qb->createNamedParameter($provisioningId, IQueryBuilder::PARAM_INT)));
$delete->execute();
}
public function deleteProvisionedAccountsByUid(string $uid): void {
$qb = $this->db->getQueryBuilder();
$delete = $qb->delete($this->getTableName())
->where(
$qb->expr()->eq('user_id', $qb->createNamedParameter($uid)),
$qb->expr()->isNotNull('provisioning_id')
);
$delete->execute();
}
public function getAllAccounts(): array {
$qb = $this->db->getQueryBuilder();
$query = $qb
->select('*')
->from($this->getTableName());
return $this->findEntities($query);
}
public function getAllUserIdsWithAccounts(): array {
$qb = $this->db->getQueryBuilder();
$query = $qb
->selectDistinct('user_id')
->from($this->getTableName());
return $this->findEntities($query);
}
}

View File

@ -26,7 +26,7 @@ services:
dockerfile: Dockerfile
args:
# Update dd.conf.sample when bumping this version in main
- IMG=${NEXTCLOUD_IMG_OVERRIDE-nextcloud:24.0.10-fpm-alpine}
- IMG=${NEXTCLOUD_IMG_OVERRIDE-nextcloud:25.0.4-fpm-alpine}
container_name: dd-apps-nextcloud-app
image: registry.dd-work.space/dd/apps-nextcloud:${DD_BUILD:-latest}
restart: unless-stopped

View File

@ -1,3 +1,17 @@
[data-action="onlyofficeDocxf"]{
display: none !important;
}
/* Fix logo misplacement */
header#header a#nextcloud {
margin-left: 0;
}
/* Force visual aesthetic */
body#body-user header#header {
background-image: none !important;
}
/* Fix icon colours */
header#header #navbar-nextcloud span.material-design-icon,
header#header #navbar-nextcloud #contactsmenu div.menutoggle::before {
filter: invert();
}

View File

@ -23,7 +23,7 @@ document.addEventListener("DOMContentLoaded", () => {
base_url = `${window.location.protocol}//${window.location.host.replace(/^nextcloud\./, 'api.')}`
$.getJSON(`${base_url}/json`, (result) => {
if (result.logo) {
$("#navbar-logo img").attr('src', result.logo)
$("#navbar-logo #nextcloud img").attr('src', result.logo)
}
if (result.product_logo) {
$("#product-logo img").attr("src", result.product_logo)

View File

@ -21,25 +21,30 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
*/
$api_url = "https://" . preg_replace('/^nextcloud\./', 'api.', $_SERVER['HTTP_HOST']);
$avatar_url = "https://" . preg_replace('/^nextcloud\./', 'sso.', $_SERVER['HTTP_HOST']) . "/auth/realms/master/avatar-provider";
// Remove user menu Settings item for non-administrator users
if(!array_key_exists('core_apps', $_["settingsnavigation"])){
unset($_["settingsnavigation"]["settings"]);
}
?>
<!DOCTYPE html>
$getUserAvatar = static function (int $size) use ($_): string {
$avatar_url = "https://" . preg_replace('/^nextcloud\./', 'sso.', $_SERVER['HTTP_HOST']) . "/auth/realms/master/avatar-provider";
return $avatar_url;
}
?><!DOCTYPE html>
<html class="ng-csp" data-placeholder-focus="false" lang="<?php p($_['language']); ?>" data-locale="<?php p($_['locale']); ?>" >
<head data-user="<?php p($_['user_uid']); ?>" data-user-displayname="<?php p($_['user_displayname']); ?>" data-requesttoken="<?php p($_['requesttoken']); ?>">
<meta charset="utf-8">
<title>
<?php
p(!empty($_['pageTitle'])?$_['pageTitle'].' - ':'');
p(!empty($_['application'])?$_['application'].' - ':'');
p($theme->getTitle());
?>
</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<?php if ($theme->getiTunesAppId() !== '') { ?>
<meta name="apple-itunes-app" content="app-id=<?php p($theme->getiTunesAppId()); ?>">
<?php } ?>
@ -54,8 +59,8 @@
<link rel="mask-icon" sizes="any" href="<?php print_unescaped(image_path($_['appid'], 'favicon-mask.svg')); ?>" color="<?php p($theme->getColorPrimary()); ?>">
<link rel="manifest" href="<?php print_unescaped(image_path($_['appid'], 'manifest.json')); ?>">
<link rel="stylesheet" href="<?php p($api_url) ?>/css/font-awesome-4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="<?php p($api_url) ?>/css/dd.css">
<link rel="stylesheet" href="/themes/dd/core/ddstyles.css">
<link rel="stylesheet" href="<?php p($api_url) ?>/css/dd.css?2303">
<link rel="stylesheet" href="/themes/dd/core/ddstyles.css?2303">
<script nonce="<?php p(\OC::$server->getContentSecurityPolicyNonceManager()->getNonce()) ?>" src="/themes/dd/core/js/navbar.js"></script>
<?php emit_css_loading_tags($_); ?>
<?php emit_script_loading_tags($_); ?>
@ -69,34 +74,36 @@
}
</style>
</head>
<body id="<?php p($_['bodyid']);?>">
<?php array_push($_['enabledThemes'], "light");?>
<body id="<?php p($_['bodyid']);?>" <?php foreach ($_['enabledThemes'] as $themeId) {
p("data-theme-$themeId ");
}?> data-themes=<?php p(join(',', $_['enabledThemes'])) ?>>
<?php include 'layout.noscript.warning.php'; ?>
<?php foreach ($_['initialStates'] as $app => $initialState) { ?>
<input type="hidden" id="initial-state-<?php p($app); ?>" value="<?php p(base64_encode($initialState)); ?>">
<?php }?>
<a href="#app-content" class="button primary skip-navigation skip-content"><?php p($l->t('Skip to main content')); ?></a>
<a href="#app-navigation" class="button primary skip-navigation"><?php p($l->t('Skip to navigation of app')); ?></a>
<div id="notification-container">
<div id="notification"></div>
<div id="skip-actions">
<?php if ($_['id-app-content'] !== null) { ?><a href="<?php p($_['id-app-content']); ?>" class="button primary skip-navigation skip-content"><?php p($l->t('Skip to main content')); ?></a><?php } ?>
<?php if ($_['id-app-navigation'] !== null) { ?><a href="<?php p($_['id-app-navigation']); ?>" class="button primary skip-navigation"><?php p($l->t('Skip to navigation of app')); ?></a><?php } ?>
</div>
<header role="banner" id="header">
<div id="navbar-logo" class="header-left">
<a href="<?php print_unescaped(link_to('', 'index.php')); ?>"
<header role="banner" id="header">
<div class="header-left" id="navbar-logo">
<a href="<?php print_unescaped($_['logoUrl'] ?: link_to('', 'index.php')); ?>"
id="nextcloud">
<img src="<?php p($api_url) ?>/img/logo.png" alt="" style="height: 39px;">
</a>
<!--<nav id="header-left__appmenu"></nav>-->
</div>
<div id="navbar-nextcloud" class="header-right">
<div id="notifications"></div>
<div class="header-right" id="navbar-nextcloud">
<div id="unified-search"></div>
<div id="notifications"></div>
<div id="contactsmenu">
<div class="icon-contacts menutoggle" tabindex="0" role="button"
<div class="menutoggle" tabindex="0" role="button"
aria-haspopup="true" aria-controls="contactsmenu-menu" aria-expanded="false">
<span class="hidden-visually"><?php p($l->t('Contacts'));?></span>
</div>
@ -105,27 +112,34 @@
</div>
<div id="settings">
<div id="expand" tabindex="0" role="button" class="menutoggle"
aria-label="<?php p($l->t('Settings'));?>"
aria-label="<?php p($l->t('Open settings menu'));?>"
aria-haspopup="true" aria-controls="expanddiv" aria-expanded="false">
<div class="avatardiv<?php if ($_['userAvatarSet']) {
<div id="avatardiv-menu" class="avatardiv<?php if ($_['userAvatarSet']) {
print_unescaped(' avatardiv-shown');
} else {
print_unescaped('" style="display: none');
} ?>">
<?php if ($_['userAvatarSet']): ?>
} ?>"
data-user="<?php p($_['user_uid']); ?>"
data-displayname="<?php p($_['user_displayname']); ?>"
<?php
if ($_['userAvatarSet']) {
$avatar32 = $getUserAvatar(32); ?> data-avatar="<?php p($avatar32); ?>"
<?php
} ?>>
<?php
if ($_['userAvatarSet']) {?>
<img alt="" width="32" height="32"
src="<?php p($avatar_url)?>"
src="<?php p($avatar32);?>"
srcset="<?php p($getUserAvatar(64));?> 2x, <?php p($getUserAvatar(128));?> 4x"
>
<?php endif; ?>
<?php } ?>
</div>
<div id="expandDisplayName" class="icon-settings-white"></div>
</div>
<nav class="settings-menu" id="expanddiv" style="display:none;"
aria-label="<?php p($l->t('Settings menu'));?>">
<nav class="settings-menu" id="expanddiv" style="display:none;">
<ul>
<?php foreach ($_['settingsnavigation'] as $entry):?>
<li data-id="<?php p($entry['id']); ?>">
<a href="<?php print_unescaped($entry['href']); ?>"
<a href="<?php print_unescaped($entry['href'] !== '' ? $entry['href'] : '#'); ?>"
<?php if ($entry["active"]): ?> class="active"<?php endif; ?>>
<img alt="" src="<?php print_unescaped($entry['icon'] . '?v=' . $_['versionHash']); ?>">
<?php p($entry['name']) ?>
@ -153,9 +167,12 @@
<input class="confirm" value="<?php p($l->t('Confirm')); ?>" type="submit">
</form>
<div id="content" class="app-<?php p($_['appid']) ?>" role="main">
<main id="content" class="app-<?php p($_['appid']) ?>">
<h1 class="hidden-visually">
<?php p($l->t('%s\'s homepage', [$theme->getName()])); ?>
</h1>
<?php print_unescaped($_['content']); ?>
</div>
</main>
<div id="profiler-toolbar"></div>
</body>
</html>

View File

@ -52,7 +52,7 @@
<!-- Custom Theme Style -->
<link href="/build/css/custom.css" rel="stylesheet">
<!-- Isard Style Sheet-->
<link href="/static/dd.css" rel="stylesheet">
<link href="/static/dd.css?2303" rel="stylesheet">
</head>
<body class="nav-md">

View File

@ -41,7 +41,7 @@
<!-- Custom Theme Style -->
<link href="/build/css/custom.min.css" rel="stylesheet">
<!-- Isard Style Sheet-->
<link href="/static/dd.css" rel="stylesheet">
<link href="/static/dd.css?2303" rel="stylesheet">
</head>
<body class="login">

View File

@ -67,12 +67,6 @@
margin-right: 16px;
}
#navbar-nextcloud #unified-search svg {
fill: black;
width: 16px;
height: 16px;
}
#navbar-nextcloud #unified-search a.header-menu__trigger .magnify-icon {
width: 16px;
height: 16px;
@ -178,6 +172,8 @@
#header div#navbar-menu-apps {
display: flex;
align-items: center;
width: 50px;
margin-right: 10px;
}
#header #navbar-menu-apps #menu-apps-btn {
@ -187,7 +183,7 @@
border-radius: 5px;
background-color: #f0f0f0;
position: relative;
left: -15px;
margin: auto;
top: 1px;
display: flex;
align-items: center;

View File

@ -169,7 +169,7 @@ MOODLE_MEMORY_LIMIT=128M
## NEXTCLOUD
# If enabled overrides nextcloud.yaml default image.
# You usually do not want to change this, but instead rely on DD's version.
#NEXTCLOUD_IMG_OVERRIDE=nextcloud:24.0.10-fpm-alpine
#NEXTCLOUD_IMG_OVERRIDE=nextcloud:25.0.4-fpm-alpine
## ONLYOFFICE
ONLYOFFICE_IMG=alehoho/oo-ce-docker-license:6.3.1.32