[NC] Upgrade to Nextcloud 25.0.5
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
parent
010a04bf37
commit
7196db9c14
|
@ -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
|
||||
|
|
|
@ -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.5/core/templates/layout.user.php
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
- **🙈 We’re 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>
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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.5-fpm-alpine}
|
||||
container_name: dd-apps-nextcloud-app
|
||||
image: registry.dd-work.space/dd/apps-nextcloud:${DD_BUILD:-latest}
|
||||
restart: unless-stopped
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,9 +59,9 @@
|
|||
<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">
|
||||
<script nonce="<?php p(\OC::$server->getContentSecurityPolicyNonceManager()->getNonce()) ?>" src="/themes/dd/core/js/navbar.js"></script>
|
||||
<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($_); ?>
|
||||
<?php print_unescaped($_['headers']); ?>
|
||||
|
@ -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')); ?>"
|
||||
<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>
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.5-fpm-alpine
|
||||
|
||||
## ONLYOFFICE
|
||||
ONLYOFFICE_IMG=alehoho/oo-ce-docker-license:6.3.1.32
|
||||
|
|
Loading…
Reference in New Issue