+
diff --git a/snappymail/v/0.0.0/app/templates/Views/User/SystemDropDown.html b/snappymail/v/0.0.0/app/templates/Views/User/SystemDropDown.html
index 8639eecb7..dbc72954d 100644
--- a/snappymail/v/0.0.0/app/templates/Views/User/SystemDropDown.html
+++ b/snappymail/v/0.0.0/app/templates/Views/User/SystemDropDown.html
@@ -18,7 +18,7 @@
-
diff --git a/snappymail/v/0.0.0/imapsync.php b/snappymail/v/0.0.0/imapsync.php
index 2325afc73..e7beb1178 100755
--- a/snappymail/v/0.0.0/imapsync.php
+++ b/snappymail/v/0.0.0/imapsync.php
@@ -154,8 +154,6 @@ function getImapClient(int $host)
{
global $options;
- $oConfig = \RainLoop\API::Config();
-
$type = SecurityType::AUTO_DETECT;
if (isset($options["tls{$host}"])) {
$type = SecurityType::STARTTLS;
@@ -168,6 +166,7 @@ function getImapClient(int $host)
'host' => $options["host{$host}"] ?? 'localhost',
'port' => $options["port{$host}"] ?? 143,
'type' => $type,
+// 'sasl' => [],
'ssl' => []
]);
if (993 === $ImapSettings->port) {
@@ -178,19 +177,8 @@ function getImapClient(int $host)
if (isset($options["timeout{$host}"])) {
$ImapSettings->timeout = (int) $options["timeout{$host}"];
}
- if ($oConfig->Get('labs', 'sasl_allow_scram_sha', false)) {
- \array_push($ImapSettings->SASLMechanisms, 'SCRAM-SHA3-512', 'SCRAM-SHA-512', 'SCRAM-SHA-256', 'SCRAM-SHA-1');
- }
- if ($oConfig->Get('labs', 'sasl_allow_cram_md5', false)) {
- $ImapSettings->SASLMechanisms[] = 'CRAM-MD5';
- }
- if ($oConfig->Get('labs', 'sasl_allow_plain', true)) {
- $ImapSettings->SASLMechanisms[] = 'PLAIN';
- }
- $ImapSettings->Login = $options["user{$host}"];
+ $ImapSettings->Login = $options["user{$host}"]; // convert to punycode?
$ImapSettings->Password = $options["password{$host}"];
-// $ImapSettings1->ProxyAuthUser = '';
-// $ImapSettings1->ProxyAuthPassword = '';
$ImapSettings->useAuth = true;
$oImapClient = new \MailSo\Imap\ImapClient;
diff --git a/snappymail/v/0.0.0/include.php b/snappymail/v/0.0.0/include.php
index 6c770f7c5..36fd600e1 100644
--- a/snappymail/v/0.0.0/include.php
+++ b/snappymail/v/0.0.0/include.php
@@ -4,10 +4,18 @@ if (defined('APP_VERSION_ROOT_PATH')) {
}
// PHP 8
-if (\PHP_VERSION_ID < 80000) {
+if (PHP_VERSION_ID < 80000) {
require __DIR__ . '/app/libraries/polyfill/php8.php';
}
+if (!extension_loaded('ctype')) {
+ require __DIR__ . '/app/libraries/polyfill/ctype.php';
+}
+
+if (!extension_loaded('intl')) {
+ require __DIR__ . '/app/libraries/polyfill/intl.php';
+}
+
if (!defined('APP_VERSION')) {
define('APP_VERSION', basename(__DIR__));
}
diff --git a/snappymail/v/0.0.0/setup.php b/snappymail/v/0.0.0/setup.php
index b073eaeac..5dfa799fd 100644
--- a/snappymail/v/0.0.0/setup.php
+++ b/snappymail/v/0.0.0/setup.php
@@ -107,7 +107,7 @@ if (defined('APP_VERSION')) {
}
}
- $sName = \SnappyMail\IDN::toAscii(mb_strtolower(gethostname()));
+ $sName = idn_to_ascii(mb_strtolower(gethostname()));
$sFile = APP_PRIVATE_DATA.'domains/'.$sName.'.json';
if (!file_exists($sFile) && !file_exists(APP_PRIVATE_DATA.'domains/'.$sName.'.ini')) {
$config = json_decode(file_get_contents(__DIR__ . '/app/domains/default.json'), true);
diff --git a/snappymail/v/0.0.0/themes/NextcloudV25+/styles.css b/snappymail/v/0.0.0/themes/NextcloudV25+/styles.css
index 7cb38a5a7..d86fd5b1d 100644
--- a/snappymail/v/0.0.0/themes/NextcloudV25+/styles.css
+++ b/snappymail/v/0.0.0/themes/NextcloudV25+/styles.css
@@ -1322,6 +1322,7 @@ html.rl-left-panel-disabled #rl-app .b-folders .b-toolbar {
#rl-app .b-folders .b-content {
top: 60px;
bottom: 162px;
+ color: unset;
}
#rl-app .b-folders .b-content.show-on-panel-disabled {
diff --git a/tasks/config.js b/tasks/config.js
index 638390983..01bd89b2a 100644
--- a/tasks/config.js
+++ b/tasks/config.js
@@ -64,6 +64,7 @@ config.paths.js = {
'vendors/knockout/build/output/knockout-latest.js',
// 'vendors/knockout/build/output/knockout-latest.debug.js',
'vendors/squire/build/squire-raw.js',
+ 'vendors/mathiasbynens/punycode.js',
'dev/External/SquireUI.js'
]
},
diff --git a/vendors/knockout/build/fragments/source-references.js b/vendors/knockout/build/fragments/source-references.js
index 0ed63d61b..71edd3e1f 100644
--- a/vendors/knockout/build/fragments/source-references.js
+++ b/vendors/knockout/build/fragments/source-references.js
@@ -1,7 +1,7 @@
knockoutDebugCallback([
'src/namespace.js',
'src/google-closure-compiler-utils.js',
- 'src/version.js',
+// 'src/version.js',
// 'src/options.js',
'src/utils.js',
'src/utils.domData.js',
diff --git a/vendors/knockout/build/output/knockout-latest.debug.js b/vendors/knockout/build/output/knockout-latest.debug.js
index a1ebe1f6a..f7fa32710 100644
--- a/vendors/knockout/build/output/knockout-latest.debug.js
+++ b/vendors/knockout/build/output/knockout-latest.debug.js
@@ -24,7 +24,6 @@ ko.exportSymbol = (koPath, object) => {
target = target[tokens[i]];
target[tokens[l]] = object;
};
-ko['version'] = "3.5.1-sm";
ko.utils = {
extend: (target, source) => source ? Object.assign(target, source) : target,
@@ -111,7 +110,7 @@ ko.utils = {
triggerEvent: (element, eventType) => {
if (!element?.nodeType)
- throw new Error("element must be a DOM node when calling triggerEvent");
+ throw Error("element must be a DOM node when calling triggerEvent");
element.dispatchEvent(new Event(eventType));
},
@@ -198,7 +197,7 @@ ko.utils.domNodeDisposal = (() => {
return {
'addDisposeCallback' : (node, callback) => {
if (typeof callback != "function")
- throw new Error("Callback must be a function");
+ throw Error("Callback must be a function");
getDisposeCallbacksCollection(node, 1).add(callback);
},
@@ -246,9 +245,8 @@ ko['extenders'] = {
}
};
-var primitiveTypes = { 'undefined':1, 'boolean':1, 'number':1, 'string':1 };
function valuesArePrimitiveAndEqual(a, b) {
- return (a === null || primitiveTypes[typeof(a)]) ? (a === b) : false;
+ return a === b && a !== Object(a);
}
function throttle(callback, timeout) {
@@ -484,7 +482,7 @@ ko.dependencyDetection = {
registerDependency: subscribable => {
if (currentFrame) {
if (!ko.isSubscribable(subscribable))
- throw new Error("Only subscribable things can act as dependencies");
+ throw Error("Only subscribable things can act as dependencies");
currentFrame.callback.call(currentFrame.callbackTarget, subscribable,
subscribable._id || (subscribable._id = ++lastId));
}
@@ -586,8 +584,8 @@ ko.exportSymbol('observable.fn', observableFn);
ko['observableArray'] = initialValues => {
initialValues = initialValues || [];
- if (typeof initialValues != 'object' || !('length' in initialValues))
- throw new Error("The argument passed when initializing an observable array must be an array, or null, or undefined.");
+ if (!Array.isArray(initialValues))
+ throw Error("The argument passed when initializing an observable array must be an array, or null, or undefined.");
return Object.setPrototypeOf(ko.observable(initialValues), ko['observableArray']['fn']).extend({'trackArrayChanges':true});
};
@@ -690,29 +688,28 @@ ko['extenders']['trackArrayChanges'] = (target, options) => {
}
};
- function trackChanges() {
+ function notifyChanges() {
+ if (pendingChanges) {
+ // Make a copy of the current contents and ensure it's an array
+ var currentContents = [].concat(target.peek() || []), changes;
- function notifyChanges() {
- if (pendingChanges) {
- // Make a copy of the current contents and ensure it's an array
- var currentContents = [].concat(target.peek() || []), changes;
+ // Compute the diff and issue notifications, but only if someone is listening
+ if (target.hasSubscriptionsForEvent(arrayChangeEventName)) {
+ changes = getChanges(previousContents, currentContents);
+ }
- // Compute the diff and issue notifications, but only if someone is listening
- if (target.hasSubscriptionsForEvent(arrayChangeEventName)) {
- changes = getChanges(previousContents, currentContents);
- }
+ // Eliminate references to the old, removed items, so they can be GCed
+ previousContents = currentContents;
+ cachedDiff = null;
+ pendingChanges = 0;
- // Eliminate references to the old, removed items, so they can be GCed
- previousContents = currentContents;
- cachedDiff = null;
- pendingChanges = 0;
-
- if (changes?.length) {
- target.notifySubscribers(changes, arrayChangeEventName);
- }
+ if (changes?.length) {
+ target.notifySubscribers(changes, arrayChangeEventName);
}
}
+ }
+ function trackChanges() {
if (trackingChanges) {
// Whenever there's a new subscription and there are pending notifications, make sure all previous
// subscriptions are notified of the change so that all subscriptions are in sync.
@@ -753,16 +750,15 @@ ko['extenders']['trackArrayChanges'] = (target, options) => {
var diff = [],
arrayLength = rawArray.length,
argsLength = args.length,
- offset = 0;
+ offset = 0,
+ pushDiff = (status, value, index) =>
+ diff[diff.length] = { 'status': status, 'value': value, 'index': index };
- function pushDiff(status, value, index) {
- return diff[diff.length] = { 'status': status, 'value': value, 'index': index };
- }
switch (operationName) {
case 'push':
offset = arrayLength;
case 'unshift':
- for (let index = 0; index < argsLength; index++) {
+ for (let index = 0; index < argsLength; ++index) {
pushDiff('added', args[index], offset + index);
}
break;
@@ -824,8 +820,8 @@ ko.computed = (evaluatorFunctionOrOptions, options) => {
pure: false,
isSleeping: false,
readFunction: options["read"],
- disposeWhenNodeIsRemoved: options["disposeWhenNodeIsRemoved"] || options.disposeWhenNodeIsRemoved || null,
- disposeWhen: options["disposeWhen"] || options.disposeWhen,
+ disposeWhenNodeIsRemoved: options.disposeWhenNodeIsRemoved || null,
+ disposeWhen: options.disposeWhen,
domNodeDisposalCallback: null,
dependencyTracking: {},
dependenciesCount: 0,
@@ -835,7 +831,7 @@ ko.computed = (evaluatorFunctionOrOptions, options) => {
function computedObservable() {
if (arguments.length > 0) {
if (typeof writeFunction !== "function") {
- throw new Error("Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.");
+ throw Error("Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.");
}
// Writing a value
writeFunction(...arguments);
@@ -1004,14 +1000,8 @@ var computedFn = {
return target['subscribe'](this.evaluatePossiblyAsync, this);
},
evaluatePossiblyAsync() {
- var computedObservable = this,
- throttleEvaluationTimeout = computedObservable['throttleEvaluation'];
- if (throttleEvaluationTimeout >= 0) {
- clearTimeout(this[computedState].evaluationTimeoutInstance);
- this[computedState].evaluationTimeoutInstance = setTimeout(() =>
- computedObservable.evaluateImmediate(true /*notifyChange*/)
- , throttleEvaluationTimeout);
- } else if (computedObservable._evalDelayed) {
+ var computedObservable = this;
+ if (computedObservable._evalDelayed) {
computedObservable._evalDelayed(true /*isChange*/);
} else {
computedObservable.evaluateImmediate(true /*notifyChange*/);
@@ -1285,7 +1275,7 @@ ko.selectExtensions = {
}
},
- writeValue: (element, value, allowUnset) => {
+ writeValue: (element, value) => {
switch (element.nodeName) {
case 'OPTION':
if (typeof value === "string") {
@@ -1314,7 +1304,7 @@ ko.selectExtensions = {
break;
}
}
- if (allowUnset || selection >= 0 || (noValue && element.size > 1)) {
+ if (selection >= 0 || (noValue && element.size > 1)) {
element.selectedIndex = selection;
}
break;
@@ -1438,9 +1428,6 @@ ko.expressionRewriting = (() => {
return result;
},
- // Two-way bindings include a write function that allow the handler to update the value even if it's not an observable.
-// twoWayBindings = new Set,
-
preProcessBindings = (bindingsStringOrKeyValueArray) => {
var resultStrings = [],
@@ -1448,16 +1435,6 @@ ko.expressionRewriting = (() => {
keyValueArray = parseObjectLiteral(bindingsStringOrKeyValueArray),
processKeyValue = (key, val) => {
- var /*writableVal,*/ obj = ko.bindingHandlers[key];
- if (obj?.['preprocess'] && !obj['preprocess'](val, key, processKeyValue))
- return;
-/*
- if (twoWayBindings.has(key) && (writableVal = getWriteableValue(val))) {
- // For two-way bindings, provide a write method in case the value
- // isn't a writable observable.
- propertyAccessorResultStrings.push("'" + key + "':function(_z){" + writableVal + "=_z}");
- }
-*/
// Values are wrapped in a function so that each value can be accessed independently
val = 'function(){return ' + val + ' }';
resultStrings.push("'" + key + "':" + val);
@@ -1474,10 +1451,6 @@ ko.expressionRewriting = (() => {
};
return {
- bindingRewriteValidators: [],
-
-// twoWayBindings: twoWayBindings,
-
parseObjectLiteral: parseObjectLiteral,
preProcessBindings: preProcessBindings,
@@ -1547,7 +1520,7 @@ ko.expressionRewriting = (() => {
++depth;
}
if (!allowUnbalanced)
- throw new Error("Cannot find closing comment tag to match: " + startComment.nodeValue);
+ throw Error("Cannot find closing comment tag to match: " + startComment.nodeValue);
return null;
}
@@ -1602,7 +1575,7 @@ ko.expressionRewriting = (() => {
}
let first = node.firstChild;
if (first && isEndComment(first)) {
- throw new Error("Found invalid end comment, as the first child of " + node);
+ throw Error("Found invalid end comment, as the first child of " + node);
}
return first;
},
@@ -1696,7 +1669,7 @@ ko.bindingHandlers = {};
// The ko.bindingContext constructor is only called directly to create the root context. For child
// contexts, use bindingContext.createChildContext or bindingContext.extend.
ko.bindingContext = class {
- constructor(dataItemOrAccessor, parentContext, dataItemAlias, extendCallback, options)
+ constructor(dataItemOrAccessor, parentContext, extendCallback, options)
{
var self = this,
shouldInheritData = dataItemOrAccessor === inheritParentVm,
@@ -1725,7 +1698,6 @@ ko.bindingContext = class {
self[contextAncestorBindingInfo] = parentContext[contextAncestorBindingInfo];
}
} else {
- self['$parents'] = [];
self['$root'] = dataItem;
// Export 'ko' in the binding context so it will be available in bindings and templates
@@ -1739,13 +1711,9 @@ ko.bindingContext = class {
if (shouldInheritData) {
dataItem = self['$data'];
} else {
- self['$rawData'] = dataItemOrObservable;
self['$data'] = dataItem;
}
- if (dataItemAlias)
- self[dataItemAlias] = dataItem;
-
// The extendCallback function is provided when creating a child context or extending a context.
// It handles the specific actions needed to finish setting up the binding context. Actions in this
// function could also add dependencies to this binding context.
@@ -1790,21 +1758,11 @@ ko.bindingContext = class {
// But this does not mean that the $data value of the child context will also get updated. If the child
// view model also depends on the parent view model, you must provide a function that returns the correct
// view model on each update.
- 'createChildContext'(dataItemOrAccessor, dataItemAlias, extendCallback, options) {
- if (!options && dataItemAlias && typeof dataItemAlias == "object") {
- options = dataItemAlias;
- dataItemAlias = options['as'];
- extendCallback = options['extend'];
- }
-
- return new ko.bindingContext(dataItemOrAccessor, this, dataItemAlias, (self, parentContext) => {
+ 'createChildContext'(dataItemOrAccessor, options) {
+ return new ko.bindingContext(dataItemOrAccessor, this, (self, parentContext) => {
// Extend the context hierarchy by setting the appropriate pointers
- self['$parentContext'] = parentContext;
self['$parent'] = parentContext['$data'];
- self['$parents'] = (parentContext['$parents'] || []).slice(0);
- self['$parents'].unshift(self['$parent']);
- if (extendCallback)
- extendCallback(self);
+ options['extend']?.(self);
}, options);
}
@@ -1812,7 +1770,7 @@ ko.bindingContext = class {
// Similarly to "child" contexts, provide a function here to make sure that the correct values are set
// when an observable view model is updated.
'extend'(properties, options) {
- return new ko.bindingContext(inheritParentVm, this, null, self =>
+ return new ko.bindingContext(inheritParentVm, this, self =>
ko.utils.extend(self, typeof(properties) == "function" ? properties(self) : properties)
, options);
}
@@ -1885,7 +1843,7 @@ ko.bindingEvent = {
} else if (bindingInfo.asyncContext === undefined && bindingInfo.eventSubscribable?.hasSubscriptionsForEvent(ko.bindingEvent.descendantsComplete)) {
// It's currently an error to register a descendantsComplete handler for a node that was never registered as completing asynchronously.
// That's because without the asyncContext, we don't have a way to know that all descendants have completed.
- throw new Error("descendantsComplete event not supported for bindings on this node");
+ throw Error("descendantsComplete event not supported for bindings on this node");
}
}
}
@@ -1909,12 +1867,6 @@ ko.bindingEvent = {
}
};
-function validateThatBindingIsAllowedForVirtualElements(bindingName) {
- var validator = ko.virtualElements.allowedBindings[bindingName];
- if (!validator)
- throw new Error("The binding '" + bindingName + "' cannot be used with virtual elements")
-}
-
function applyBindingsToDescendantsInternal(bindingContext, elementOrVirtualElement) {
var currentChild, nextInQueue = ko.virtualElements.firstChild(elementOrVirtualElement);
@@ -1935,7 +1887,7 @@ function applyBindingsToNodeAndDescendantsInternal(bindingContext, nodeVerified)
// (1) We need to store the binding info for the node (all element nodes)
// (2) It might have bindings (e.g., it has a data-bind attribute, or it's a marker for a containerless template)
if (isElement || ko.bindingProvider.nodeHasBindings(nodeVerified))
- bindingContextForDescendants = applyBindingsToNodeInternal(nodeVerified, null, bindingContext)['bindingContextForDescendants'];
+ bindingContextForDescendants = applyBindingsToNodeInternal(nodeVerified, null, bindingContext);
// Don't want bindings that operate on text nodes to mutate