diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3be72010459c85fbe24c3bed968b2bff9a783c9d..0a4370578ab23da720843e6c5803310c6426511e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,10 +5,10 @@ variables: DOCKER_TLS_CERTDIR: "/certs" default: - image: docker:19.03.12 + image: docker:24.0.6 services: - - docker:19.03.12-dind + - docker:24.0.6-dind before_script: - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY tags: diff --git a/Dockerfile b/Dockerfile index d4ce14277352d9199e526bf5b2fda7cd4ab9ea47..e58ef6bba1e44983604829f7d172344e51be365e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,21 +1,21 @@ -FROM nextcloud:25.0.8-fpm AS nextcloud +FROM nextcloud:26.0.8-fpm AS nextcloud ARG BASE_DIR="/usr/src/nextcloud" ARG TMP_PATCH_DIR="/tmp/build_patches" -ARG THEME_HELPER_JOB_ID="652534" +ARG THEME_HELPER_JOB_ID="744739" ARG NOTES_VERSION="4.8.1" -ARG CONTACTS_JOB_ID="682723" -ARG CALENDAR_JOB_ID="684933" -ARG EMAIL_RECOVERY_JOB_ID="582038" -ARG EA_JOB_ID="716935" -ARG LAUNCHER_JOB_ID="651032" -ARG GOOGLE_INTEGRATION_VERSION="1.0.9" -ARG DASHBOARD_JOB_ID="651040" +ARG CONTACTS_JOB_ID="740210" +ARG CALENDAR_JOB_ID="738789" +ARG EMAIL_RECOVERY_JOB_ID="738840" +ARG EA_JOB_ID="738865" +ARG LAUNCHER_JOB_ID="738816" +ARG GOOGLE_INTEGRATION_VERSION="2.1.0" +ARG DASHBOARD_JOB_ID="748055" ARG SNAPPY_VERSION="2.29.1" -ARG SNAPPY_THEME_VERSION="2.0.8" +ARG SNAPPY_THEME_VERSION="3.0.0" ARG USER_MIGRATION_JOB_ID="608716" ARG MEMORIES_VERSION="5.4.1" -RUN sed -i 's/25,0,8,2/25,0,8,24/' ${BASE_DIR}/version.php +RUN sed -i 's/26,0,8,2/26,0,8,9/' ${BASE_DIR}/version.php COPY custom_entrypoint.sh / RUN chmod +x /custom_entrypoint.sh RUN mkdir -p /var/www/skeleton/Documents && mkdir -p /var/www/skeleton/Images @@ -60,7 +60,7 @@ RUN curl -fsSL -o murena_launcher.zip \ rm murena_launcher.zip; RUN curl -fsSL -o integration_google.tar.gz \ - "https://github.com/nextcloud/integration_google/releases/download/v${GOOGLE_INTEGRATION_VERSION}/integration_google-${GOOGLE_INTEGRATION_VERSION}.tar.gz" && \ + "https://github.com/nextcloud-releases/integration_google/releases/download/v${GOOGLE_INTEGRATION_VERSION}/integration_google-v${GOOGLE_INTEGRATION_VERSION}.tar.gz" && \ tar -xf integration_google.tar.gz -C ${BASE_DIR}/custom_apps/ && \ chown -R www-data:www-data ${BASE_DIR}/custom_apps/integration_google && \ rm integration_google.tar.gz; @@ -121,7 +121,7 @@ CMD ["php-fpm"] From nextcloud as selfhost ARG BASE_DIR="/usr/src/nextcloud" ARG TMP_PATCH_DIR="/tmp/build_patches" -ARG THEME_VERSION="25.0.16" +ARG THEME_VERSION="26.0.0" ARG USER_BACKEND_RAW_SQL_VERSION="1.3.0" ARG SELFHOST_THEME_VERSION="1.0.0" ARG IS_SELFHOST=true @@ -136,12 +136,14 @@ RUN patch -u ${BASE_DIR}/lib/private/Updater.php -i ${TMP_PATCH_DIR}/010-disable RUN cd ${BASE_DIR} && patch -p0 < ${TMP_PATCH_DIR}/011-privacy-settings.patch RUN patch -u ${BASE_DIR}/lib/private/Authentication/Token/PublicKeyTokenProvider.php -i ${TMP_PATCH_DIR}/013-revert-token-password-update.patch RUN patch -u ${BASE_DIR}/lib/private/legacy/OC_Helper.php -i ${TMP_PATCH_DIR}/014-add-mail-usage.patch -RUN cd ${BASE_DIR} && patch -u ${BASE_DIR}/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php -i ${TMP_PATCH_DIR}/015-email-mail-template.patch +RUN cd ${BASE_DIR} && patch -p0 < ${TMP_PATCH_DIR}/015-email-mail-template.patch RUN patch -u ${BASE_DIR}/core/Command/User/Setting.php -i ${TMP_PATCH_DIR}/018-occ-user-setting.patch RUN patch -u ${BASE_DIR}/apps/files/js/files.js -i ${TMP_PATCH_DIR}/021-repeated-storage-dialog-fix.patch RUN cd ${BASE_DIR} && patch -u ${BASE_DIR}/3rdparty/sabre/vobject/lib/ITip/Broker.php -i ${TMP_PATCH_DIR}/022-significantchange.patch RUN patch -u ${BASE_DIR}/apps/dav/lib/CalDAV/Reminder/ReminderService.php -i ${TMP_PATCH_DIR}/024-reminder-service-handle-exception.patch RUN patch -u ${BASE_DIR}/apps/theming/lib/Themes/CommonThemeTrait.php -i ${TMP_PATCH_DIR}/026-primary-color-fix.patch +RUN patch -u ${BASE_DIR}/lib/private/Preview/Watcher.php -i ${TMP_PATCH_DIR}/030-preview-watcher-null-check.patch +RUN patch -u ${BASE_DIR}/lib/private/Template/JSResourceLocator.php -i ${TMP_PATCH_DIR}/031-theme-custom-app-translations.patch RUN rm -rf ${TMP_PATCH_DIR} @@ -177,22 +179,22 @@ RUN sed -i 's/settings-hint/settings-hint hidden/' ${BASE_DIR}/apps/settings/tem RUN sed -i 's/ in Nextcloud/ /' ${BASE_DIR}/custom_apps/integration_google/js/integration_google-personalSettings.js RUN sed -i 's/Nextcloud administrator/administrator/' ${BASE_DIR}/custom_apps/integration_google/js/integration_google-personalSettings.js -#replace error class in schedule response error file to fix error color -RUN sed -i 's/update/error/g' ${BASE_DIR}/apps/dav/templates/schedule-response-error.php # Fix the navbar entries RUN sed -i 's/this.appLimit=e/this.appLimit=this.appList.length/' ${BASE_DIR}/dist/core-main.js # Fix total quota value for users in settings and files -RUN sed -i "s/'total'/'quota'/" ${BASE_DIR}/apps/files/lib/Controller/ViewController.php RUN sed -i "s/'total'/'quota'/" ${BASE_DIR}/apps/settings/lib/Settings/Personal/PersonalInfo.php RUN sed -i "s/\['total'\]/\['quota'\]/" ${BASE_DIR}/apps/provisioning_api/lib/Controller/AUserData.php +# Fix API call in files script +RUN sed -i "s/ajax\/getstoragestats/api\/v1\/stats/g" ${BASE_DIR}/apps/files/js/files.js + From selfhost as ecloud ARG BASE_DIR="/usr/src/nextcloud" ARG TMP_PATCH_DIR="/tmp/build_patches" -ARG THEME_VERSION="25.0.16" -ARG LDAP_WRITE_SUPPORT_VERSION="1.7.0" +ARG THEME_VERSION="26.0.0" +ARG LDAP_WRITE_SUPPORT_VERSION="1.8.0" ARG OIDC_LOGIN_VERSION="2.6.0" ARG IS_SELFHOST=false @@ -233,13 +235,12 @@ RUN sed -i 's/https:\/\/nextcloud.com\/signup\//https:\/\/e\.foundation\/registerAlternativeLogin(OIDCLoginOption::class);/\/\/$context->registerAlternativeLogin(OIDCLoginOption::class);/' ${BASE_DIR}/custom_apps/oidc_login/lib/AppInfo/Application.php # add attr about how many notifications to notif icon -RUN sed -i 's/attrs:{id:"notifications",/attrs:{id:"notifications","data-has-notifications":0!==e.notifications.length,/' ${BASE_DIR}/apps/notifications/js/notifications-main.js +RUN sed -i 's/attrs:{id:"notifications",/attrs:{id:"notifications","data-has-notifications":0!==t.notifications.length,/' ${BASE_DIR}/apps/notifications/js/notifications-node_modules_moment_locale_sync_recursive_-src_NotificationsApp_vue.js # Add data-object-type to notification -RUN sed -i 's/"data-id":e.notificationId,/"data-id":e.notificationId,"data-object-type":e.objectType,/' ${BASE_DIR}/apps/notifications/js/notifications-main.js +RUN sed -i 's/"data-id":t.notificationId,/"data-id":t.notificationId,"data-object-type":t.objectType,/' ${BASE_DIR}/apps/notifications/js/notifications-node_modules_moment_locale_sync_recursive_-src_NotificationsApp_vue.js #Hide Archive/Unarchive feature in memories app RUN sed -i 's/{name:(0,O.Iu)("memories","Archive"),icon:Yo,callback:this.archiveSelection.bind(this),if:()=>!this.routeIsArchiveFolder()&&!this.routeIsAlbums},{name:(0,O.Iu)("memories","Unarchive"),icon:Ko,callback:this.archiveSelection.bind(this),if:()=>this.routeIsArchiveFolder()},//g' ${BASE_DIR}/custom_apps/memories/js/memories-main.js RUN sed -i 's/{name:"archive",icon:Yo,title:(0,O.Iu)("memories","Archive")},//g' ${BASE_DIR}/custom_apps/memories/js/memories-main.js - # Rename Memories to Gallery RUN sed -i 's/Memories<\/name>/Gallery<\/name>/g' ${BASE_DIR}/custom_apps/memories/appinfo/info.xml RUN cd ${BASE_DIR}/custom_apps/memories/js && sed -i 's/Memories has been/Gallery has been/g' memories-main.js && sed -i 's/Memories has been/Gallery has been/g' memories-admin.js @@ -247,9 +248,9 @@ RUN cd ${BASE_DIR}/custom_apps/memories/js && sed -i 's/Memories Settings/Galler # autocomplete leak tweak apps frontend with sed, disable group suggestion -RUN cd ${BASE_DIR}/custom_apps/contacts && sed -i 's/"GROUP","INDIVIDUAL"/"INDIVIDUAL"/g' js/contacts-main.js +RUN cd ${BASE_DIR}/custom_apps/contacts && sed -i ' s/"GROUP","INDIVIDUAL"/"INDIVIDUAL"/g' js/contacts-main.js RUN cd ${BASE_DIR}/custom_apps/calendar && sed -i 's/"GROUP","INDIVIDUAL"/"INDIVIDUAL"/g' js/calendar-main.js -RUN cd ${BASE_DIR}/custom_apps/calendar && sed -i 's/{name:\[o,"displayname"\]},//' js/calendar-main.js +RUN cd ${BASE_DIR}/custom_apps/calendar && sed -i 's/{name:\[a,"displayname"\]},//' js/calendar-main.js RUN cd ${BASE_DIR}/custom_apps/notes && sed -i 's/OCA\\Notes\\Migration\\EditorHint<\/step>//g' appinfo/info.xml RUN cd ${BASE_DIR}/apps/theming && sed -i 's/OCA\\Theming\\Migration\\MigrateUserConfig<\/step>//g' appinfo/info.xml @@ -258,8 +259,9 @@ RUN cd ${BASE_DIR}/apps/theming && sed -i 's/OCA\\Theming\\Migration\\Migr RUN cd ${BASE_DIR}/custom_apps/memories && sed -i 's/shareTypes:\[bc\.D\.SHARE_TYPE_USER,bc\.D\.SHARE_TYPE_GROUP\]}});/shareTypes:[bc.D.SHARE_TYPE_USER,bc.D.SHARE_TYPE_EMAIL]}}),n=e.data.ocs.data.filter((e=>"emails"!==e.source)),r={data:{ocs:{meta:e.data.ocs.meta,data:n}}};/g' js/memories-main.js RUN cd ${BASE_DIR}/custom_apps/memories && sed -i 's/this\.currentSearchResults=e\.data\./this\.currentSearchResults=r\.data\./g' js/memories-main.js + # Remove colored background from email template logo -RUN sed -i 's/$this->header, \[$this->themingDefaults->getColorPrimary()/$this->header, \["none"/' ${BASE_DIR}/lib/private/Mail/EMailTemplate.php +RUN sed -i 's/$this->header, \[$this->themingDefaults->getDefaultColorPrimary()/$this->header, \["none"/' ${BASE_DIR}/lib/private/Mail/EMailTemplate.php # Remove changeAvatar in changeUserHook of ldap_write_support as it throws errors RUN sed -i 's/$this->changeAvatar/\/\/ $this->changeAvatar/' ${BASE_DIR}/custom_apps/ldap_write_support/lib/LDAPUserManager.php diff --git a/patches/015-email-mail-template.patch b/patches/015-email-mail-template.patch index 646253b9ceb9ca205c295b904408975d64843e36..fe4c6df1438eb87f4ede77352e38bb8e10a828c7 100644 --- a/patches/015-email-mail-template.patch +++ b/patches/015-email-mail-template.patch @@ -4,11 +4,11 @@ Subject: [PATCH] To implement custom email template design for calendar invite This patch is allowing to customize the email template design for invitation ---- apps/dav-4/lib/CalDAV/Schedule/IMipPlugin.php 2022-11-10 10:39:19.134653000 +0530 -+++ apps/dav-4/lib/CalDAV/Schedule/iMipPluginNew.php 2022-11-25 15:05:11.443768000 +0530 -@@ -237,6 +237,13 @@ - ]; - +--- ./apps/dav/lib/CalDAV/Schedule/IMipPlugin.php 2023-10-19 14:18:20 ++++ ./apps/dav/lib/CalDAV/Schedule/IMipPlugin-new.php 2023-10-19 14:21:42 +@@ -235,6 +235,13 @@ + $data['invitee_name'] = ($senderName ?: $sender); + $fromEMail = Util::getDefaultEmailAddress('invitations-noreply'); + //if sender name is empty sometimes in case of email client + if ($senderName === null || empty(trim($senderName))) { @@ -17,189 +17,114 @@ This patch is allowing to customize the email template design for invitation + $senderName = $users[0]->getDisplayName(); + } + } - $fromName = $l10n->t('%1$s via %2$s', [$senderName, $this->defaults->getName()]); - + $fromName = $this->imipService->getFrom($senderName, $this->defaults->getName()); + $message = $this->mailer->createMessage() -@@ -252,7 +259,21 @@ - - $summary = ((string) $summary !== '') ? (string) $summary : $l10n->t('Untitled event'); - -- $this->addSubjectAndHeading($template, $l10n, $method, $summary); -+ if ( count($vevent)>1) { -+ $this->addSubjectAndHeadingUpdated($template, $l10n, $method, $summary); +@@ -255,7 +262,22 @@ + $template = $this->mailer->createEMailTemplate('dav.calendarInvite.' . $method, $data); + $template->addHeader(); + +- $this->imipService->addSubjectAndHeading($template, $method, $data['invitee_name'], $data['meeting_title']); ++ $l10n = \OC::$server->getL10N('dav'); ++ if ( count($vEvent)>1) { ++ $this->imipService->addSubjectAndHeadingUpdated($template, $method, $data['invitee_name'], $data['meeting_title']); + } else { -+ $this->addSubjectAndHeading($template, $l10n, $method, $summary); ++ $this->imipService->addSubjectAndHeading($template, $method, $data['invitee_name'], $data['meeting_title']); + } + if ($method === self::METHOD_CANCEL) { + $template->addHeadingBanner('#FFC2B9','#7D1000',$l10n->t('The invitation has been cancelled')); + } -+ if ($method !== self::METHOD_CANCEL && $method !== self::METHOD_REPLY && count($vevent)>1) { ++ if ($method !== self::METHOD_CANCEL && $method !== self::METHOD_REPLY && count($vEvent)>1) { + $template->addHeadingBanner('#EFFFDB','#293618',$l10n->t('This recurring event has been updated, please review the information below:')); + } -+ $sequence = $vevent->SEQUENCE ? $vevent->SEQUENCE->getValue() : NULL; -+ if ($sequence && $method !== self::METHOD_CANCEL && $method !== self::METHOD_REPLY && count($vevent)==1 && ($sequence > 2)) { ++ $sequence = $vEvent->SEQUENCE ? $vEvent->SEQUENCE->getValue() : NULL; ++ if ($sequence && $method !== self::METHOD_CANCEL && $method !== self::METHOD_REPLY && count($vEvent)==1 && ($sequence > 2)) { + $template->addHeadingBanner('#EFFFDB','#293618',$l10n->t('This event has been updated, please review the information below:')); + } - $this->addBulletList($template, $l10n, $vevent); - + $this->imipService->addBulletList($template, $vEvent, $data); + // Only add response buttons to invitation requests: Fix Issue #11230 -@@ -516,6 +537,7 @@ - return $dtStart->format('Y-m-d') === $dtEnd->format('Y-m-d'); - } -+ - /** - * @param IEMailTemplate $template - * @param IL10N $l10n -@@ -542,24 +564,86 @@ +--- ./apps/dav/lib/CalDAV/Schedule/IMipService.php 2023-10-19 11:40:39 ++++ ./apps/dav/lib/CalDAV/Schedule/IMipService-new.php 2023-10-19 13:47:17 +@@ -382,6 +382,30 @@ + } + /** - * @param IEMailTemplate $template - * @param IL10N $l10n ++ * @param IEMailTemplate $template + * @param string $method ++ * @param string $sender + * @param string $summary ++ * @param string|null $partstat + */ -+ private function addSubjectAndHeadingUpdated(IEMailTemplate $template, IL10N $l10n, -+ $method, $summary) { -+ if ($method === self::METHOD_CANCEL) { -+ //TRANSLATORS Subject for email, when an invitation is cancelled. Ex: "Cancelled: {{Event Name}}" -+ $template->setSubject($l10n->t('Cancelled: %1$s', [$summary])); -+ $template->addHeading($l10n->t('Invitation canceled')); -+ } elseif ($method === self::METHOD_REPLY) { -+ // TRANSLATORS Subject for email, when an invitation is updated. Ex: "Re: {{Event Name}}" -+ $template->setSubject($l10n->t('Re: %1$s', [$summary])); -+ $template->addHeading($l10n->t('Invitation updated')); ++ public function addSubjectAndHeadingUpdated(IEMailTemplate $template, ++ string $method, string $sender, string $summary): void { ++ if ($method === IMipPlugin::METHOD_CANCEL) { ++ // TRANSLATORS Subject for email, when an invitation is cancelled. Ex: "Cancelled: {{Event Name}}" ++ $template->setSubject($this->l10n->t('Cancelled: %1$s', [$summary])); ++ $template->addHeading($this->l10n->t('"%1$s" has been canceled', [$summary])); ++ } elseif ($method === IMipPlugin::METHOD_REPLY) { ++ // TRANSLATORS Subject for email, when an invitation is replied to. Ex: "Re: {{Event Name}}" ++ $template->setSubject($this->l10n->t('Re: %1$s', [$summary])); ++ $template->addHeading($this->l10n->t('%1$s has responded to your invitation', [$sender])); + } else { + // TRANSLATORS Subject for email, when an invitation is sent. Ex: "Invitation: {{Event Name}}" -+ $template->setSubject($l10n->t('Invitation: %1$s', [$summary])); -+ $template->addHeading($l10n->t('Invitation Update')); ++ $template->setSubject($this->l10n->t('Invitation Updated: %1$s', [$summary])); ++ $template->addHeading($this->l10n->t('%1$s would like to invite you to "%2$s"', [$sender, $summary])); + } + } + + /** -+ * @param IEMailTemplate $template -+ * @param IL10N $l10n - * @param VEVENT $vevent + * @param string $path + * @return string */ - private function addBulletList(IEMailTemplate $template, IL10N $l10n, $vevent) { -- if ($vevent->SUMMARY) { -- $template->addBodyListItem($vevent->SUMMARY, $l10n->t('Title:'), -- $this->getAbsoluteImagePath('caldav/title.png'),'','',self::IMIP_INDENT); -+ $lastmodified=0; -+ $selectedEvent = $parentevent = $vevent; -+ foreach( $vevent as $currentevent) { -+ $dtstamp= $currentevent->{'LAST-MODIFIED'}; -+ $dtstampTime = strtotime($dtstamp); -+ if ($dtstampTime>$lastmodified) { -+ $lastmodified=$dtstampTime; -+ $selectedEvent = $currentevent; -+ } -+ } -+ if ($selectedEvent->SUMMARY) { -+ if (trim($selectedEvent->SUMMARY) == trim($parentevent->SUMMARY)) { -+ $template->addBodyListItem($selectedEvent->SUMMARY, $l10n->t('Title:'), -+ $this->getAbsoluteImagePath('caldav/title.png'),'','',self::IMIP_INDENT); -+ } else { -+ $template->addBodyListItemModified($selectedEvent->SUMMARY, $l10n->t('Updated Title:'), -+ $this->getAbsoluteImagePath('caldav/title.png'),'','',self::IMIP_INDENT); -+ } +@@ -479,8 +503,13 @@ + $this->getAbsoluteImagePath('caldav/time.png'), $data['meeting_when'], '', IMipPlugin::IMIP_INDENT); } -- $meetingWhen = $this->generateWhenString($l10n, $vevent); -+ $meetingWhen = $this->generateWhenString($l10n, $selectedEvent); - if ($meetingWhen) { -- $template->addBodyListItem($meetingWhen, $l10n->t('Time:'), -- $this->getAbsoluteImagePath('caldav/time.png'),'','',self::IMIP_INDENT); -+ $selectedtimestart= substr(($selectedEvent->DTSTART), strpos(($selectedEvent->DTSTART), "T") + 1); -+ $parenttimestart= substr(($parentevent->DTSTART), strpos(($parentevent->DTSTART), "T") + 1); -+ $selectedtimeend= substr(($selectedEvent->DTEND), strpos(($selectedEvent->DTEND), "T") + 1); -+ $parenttimeend= substr(($parentevent->DTEND), strpos(($parentevent->DTEND), "T") + 1); -+ if (trim($selectedtimestart)==trim($parenttimestart) && trim($selectedtimeend)==trim($parenttimeend)) { -+ $template->addBodyListItem($meetingWhen, $l10n->t('Time:'), -+ $this->getAbsoluteImagePath('caldav/time.png'),'','',self::IMIP_INDENT); + if ($data['meeting_location'] !== '') { +- $template->addBodyListItem($data['meeting_location_html'] ?? $data['meeting_location'], $this->l10n->t('Location:'), +- $this->getAbsoluteImagePath('caldav/location.png'), $data['meeting_location'], '', IMipPlugin::IMIP_INDENT); ++ if(filter_var(trim($data['meeting_location']), FILTER_VALIDATE_URL)) { ++ $template->addBodyListItem($data['meeting_location_html'] ?? $data['meeting_location'], $this->l10n->t('Location:'), ++ $this->getAbsoluteImagePath('caldav/videocall.png'), $data['meeting_location'], '', IMipPlugin::IMIP_INDENT); + } else { -+ $template->addBodyListItemModified($meetingWhen, $l10n->t('Updated Time:'), -+ $this->getAbsoluteImagePath('caldav/time.png'),'','',self::IMIP_INDENT); -+ } ++ $template->addBodyListItem($data['meeting_location_html'] ?? $data['meeting_location'], $this->l10n->t('Location:'), ++ $this->getAbsoluteImagePath('caldav/location.png'), $data['meeting_location'], '', IMipPlugin::IMIP_INDENT); ++ } } -- if ($vevent->LOCATION) { -- $template->addBodyListItem($vevent->LOCATION, $l10n->t('Location:'), -- $this->getAbsoluteImagePath('caldav/location.png'),'','',self::IMIP_INDENT); -+ if ($selectedEvent->LOCATION) { -+ if (trim($selectedEvent->LOCATION) == trim($parentevent->LOCATION)) { -+ if (filter_var(trim($selectedEvent->LOCATION), FILTER_VALIDATE_URL)) { -+ $template->addBodyListItem($selectedEvent->LOCATION, $l10n->t('Location:'), -+ $this->getAbsoluteImagePath('caldav/videocall.png'),'','',self::IMIP_INDENT); -+ } else { -+ $template->addBodyListItem($selectedEvent->LOCATION, $l10n->t('Location:'), -+ $this->getAbsoluteImagePath('caldav/location.png'),'','',self::IMIP_INDENT); -+ } -+ } else { -+ if (filter_var(trim($selectedEvent->LOCATION), FILTER_VALIDATE_URL)) { -+ $template->addBodyListItemModified($selectedEvent->LOCATION, $l10n->t('Updated Location:'), -+ $this->getAbsoluteImagePath('caldav/videocall.png'),'','',self::IMIP_INDENT); -+ } else { -+ $template->addBodyListItemModified($selectedEvent->LOCATION, $l10n->t('Updated Location:'), -+ $this->getAbsoluteImagePath('caldav/location.png'),'','',self::IMIP_INDENT); -+ } -+ } - } -- if ($vevent->URL) { -- $url = $vevent->URL->getValue(); -+ if ($selectedEvent->URL) { -+ $url = $selectedEvent->URL->getValue(); - $template->addBodyListItem(sprintf('%s', - htmlspecialchars($url), - htmlspecialchars($url)), -@@ -567,13 +651,16 @@ - $this->getAbsoluteImagePath('caldav/link.png'), - $url,'',self::IMIP_INDENT); - } -- -- $this->addAttendees($template, $l10n, $vevent); -- -+ $this->addAttendees($template, $l10n, $selectedEvent); - /* Put description last, like an email body, since it can be arbitrarily long */ -- if ($vevent->DESCRIPTION) { -- $template->addBodyListItem($vevent->DESCRIPTION->getValue(), $l10n->t('Description:'), -- $this->getAbsoluteImagePath('caldav/description.png'),'','',self::IMIP_INDENT); -+ if ($selectedEvent->DESCRIPTION) { -+ if (trim($selectedEvent->DESCRIPTION)==trim($parentevent->DESCRIPTION)) { -+ $template->addBodyListItem($selectedEvent->DESCRIPTION->getValue(), $l10n->t('Description:'), -+ $this->getAbsoluteImagePath('caldav/description.png'),'','',self::IMIP_INDENT); -+ } else { -+ $template->addBodyListItemModified($selectedEvent->DESCRIPTION, $l10n->t('Updated Description:'), -+ $this->getAbsoluteImagePath('caldav/description.png'),'','',self::IMIP_INDENT); -+ } - } - } - -@@ -662,7 +749,7 @@ - Message $iTipMessage, $lastOccurrence) { - $token = $this->createInvitationToken($iTipMessage, $lastOccurrence); - + if ($data['meeting_url'] !== '') { + $template->addBodyListItem($data['meeting_url_html'] ?? $data['meeting_url'], $this->l10n->t('Link:'), +@@ -575,7 +604,7 @@ + * @param $token + */ + public function addResponseButtons(IEMailTemplate $template, $token) { - $template->addBodyButtonGroup( + $template->addBodyButtonGroupTentative( - $l10n->t('Accept'), + $this->l10n->t('Accept'), $this->urlGenerator->linkToRouteAbsolute('dav.invitation_response.accept', [ 'token' => $token, -@@ -670,18 +757,10 @@ - $l10n->t('Decline'), +@@ -583,19 +612,12 @@ + $this->l10n->t('Decline'), $this->urlGenerator->linkToRouteAbsolute('dav.invitation_response.decline', [ 'token' => $token, - ]) + ]), -+ $l10n->t('Maybe'), ++ $this->l10n->t('MayBe'), + $this->urlGenerator->getAbsoluteUrl('apps/calendar/invitation/tentative/'.$token) ); -- + } + + public function addMoreOptionsButton(IEMailTemplate $template, $token) { - $moreOptionsURL = $this->urlGenerator->linkToRouteAbsolute('dav.invitation_response.options', [ - 'token' => $token, - ]); - $html = vsprintf('%s', [ -- $moreOptionsURL, $l10n->t('More options …') +- $moreOptionsURL, $this->l10n->t('More options …') - ]); -- $text = $l10n->t('More options at %s', [$moreOptionsURL]); +- $text = $this->l10n->t('More options at %s', [$moreOptionsURL]); - - $template->addBodyText($html, $text); } + } +\ No newline at end of file - /** diff --git a/patches/026-primary-color-fix.patch b/patches/026-primary-color-fix.patch index 33ee6da62fcadb83c18eefd3169b04d82db9dfca..c474e1dbd3929fa7b81a41c2cf8427e10d8dc04b 100644 --- a/patches/026-primary-color-fix.patch +++ b/patches/026-primary-color-fix.patch @@ -4,13 +4,15 @@ Subject: [PATCH] To fix the primary color in nextcloud 25 onwards --- apps/theming/lib/Themes/CommonThemeTrait.php 2023-04-12 17:16:23.456078658 +0530 +++ apps/theming/lib/Themes/CommonThemeTrait-new.php 2023-04-12 17:17:30.456079957 +0530 -@@ -38,6 +38,9 @@ +@@ -38,7 +38,10 @@ * will change in between. */ protected function generatePrimaryVariables(string $colorMainBackground, string $colorMainText): array { -+ $defaults = new \OC_Defaults(); -+ $this->primaryColor = $defaults->getColorPrimary(); -+ $this->defaultPrimaryColor=$defaults->getColorPrimary(); - $colorPrimaryLight = $this->util->mix($this->primaryColor, $colorMainBackground, -80); - $colorPrimaryElement = $this->util->elementColor($this->primaryColor); - $colorPrimaryElementDefault = $this->util->elementColor($this->defaultPrimaryColor); +- $isBrightColor = $this->util->isBrightColor($colorMainBackground); ++ $isBrightColor = $this->util->isBrightColor($colorMainBackground); ++ $defaults = new \OC_Defaults(); ++ $this->primaryColor = $defaults->getColorPrimary(); ++ $this->defaultPrimaryColor=$defaults->getColorPrimary(); + $colorPrimaryElement = $this->util->elementColor($this->primaryColor, $isBrightColor); + $colorPrimaryLight = $this->util->mix($colorPrimaryElement, $colorMainBackground, -80); + $colorPrimaryElementLight = $this->util->mix($colorPrimaryElement, $colorMainBackground, -80); diff --git a/patches/030-preview-watcher-null-check.patch b/patches/030-preview-watcher-null-check.patch new file mode 100644 index 0000000000000000000000000000000000000000..e85cf6186c915eabb83e91e4c902b600ea10c4d1 --- /dev/null +++ b/patches/030-preview-watcher-null-check.patch @@ -0,0 +1,19 @@ +From: Akhil +Date: Fri, 25 June 2023 16:30:00 +0530 +Subject: [PATCH] Add a check for null in preview watcher + +If a null argument is passed, an rmdir happens on the entire preview directory. +This patch avoids this situation. + +--- lib/private/Preview/Watcher.php 2023-10-23 19:06:42.892424278 +0530 ++++ lib/private/Preview/Watcher-new.php 2023-10-23 19:59:31.903638761 +0530 +@@ -61,6 +61,9 @@ + } + + try { ++ if (is_null($node->getId())) { ++ return; ++ } + $folder = $this->appData->getFolder((string)$node->getId()); + $folder->delete(); + } catch (NotFoundException $e) { diff --git a/patches/031-theme-custom-app-translations.patch b/patches/031-theme-custom-app-translations.patch new file mode 100644 index 0000000000000000000000000000000000000000..ff9d4effd7336522543e8789789c9b9a889d073e --- /dev/null +++ b/patches/031-theme-custom-app-translations.patch @@ -0,0 +1,24 @@ +From: Akhil +Date: Fri, 25 June 2023 16:40:00 +0530 +Subject: [PATCH] Add custom app translation scripts from theme + +Check all app root paths defined in config when delivering translation scripts + +--- lib/private/Template/JSResourceLocator.php 2023-10-25 22:20:27.524870550 +0530 ++++ lib/private/Template/JSResourceLocator-new.php 2023-10-25 22:23:02.419067631 +0530 +@@ -57,8 +57,13 @@ + $found += $this->appendIfExist($this->serverroot, $theme_dir.'core/'.$script.'.js'); + $found += $this->appendIfExist($this->serverroot, $script.'.js'); + $found += $this->appendIfExist($this->serverroot, $theme_dir.$script.'.js'); +- $found += $this->appendIfExist($this->serverroot, 'apps/'.$script.'.js'); +- $found += $this->appendIfExist($this->serverroot, $theme_dir.'apps/'.$script.'.js'); ++ ++ foreach (\OC::$APPSROOTS as $appRoot) { ++ $dirName = basename($appRoot['path']); ++ $rootPath = dirname($appRoot['path']); ++ $found += $this->appendIfExist($rootPath, $dirName.'/'.$script.'.js'); ++ $found += $this->appendIfExist($this->serverroot, $theme_dir.$dirName.'/'.$script.'.js'); ++ } + + if ($found) { + return; \ No newline at end of file