Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/OctoPrint/OctoPrint.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitHub Nightly Merge Action <actions@github.com>2022-10-14 03:20:54 +0300
committerGitHub Nightly Merge Action <actions@github.com>2022-10-14 03:20:54 +0300
commitc1a2c0ef7ada78b1999c50951851f5871fa06ee5 (patch)
tree95a5886443eb72dcb3e9ac5e761b1c728eb750bc
parenta9d0856b3d7c1788bac39ab291ff1e4c87f80061 (diff)
parent2e408096e182c767066850aa11b0f5c58d09a77c (diff)
Merge branch 'maintenance' into devel
-rw-r--r--.github/workflows/build.yml1
-rw-r--r--.github/workflows/nightly_merge.yml18
-rw-r--r--.pre-commit-config.yaml1
-rw-r--r--src/octoprint/plugins/backup/__init__.py26
-rw-r--r--src/octoprint/server/__init__.py1
-rw-r--r--src/octoprint/server/util/flask.py4
-rw-r--r--src/octoprint/static/js/app/client/base.js7
-rw-r--r--tests/cypress/package-lock.json15
-rw-r--r--tests/static/js/test-client-base.html18
-rw-r--r--tests/static/js/test-client-base.js110
10 files changed, 178 insertions, 23 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 9ef20ac0f..c6f89e6d6 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -77,6 +77,7 @@ jobs:
- name: ๐Ÿš€ Run helpers.js test suite
run: |
node-qunit-puppeteer tests/static/js/test-helpers.html
+ node-qunit-puppeteer tests/static/js/test-client-base.html
test-install:
name: ๐Ÿงช Installation tests
diff --git a/.github/workflows/nightly_merge.yml b/.github/workflows/nightly_merge.yml
index 089f44c8c..56821fbc0 100644
--- a/.github/workflows/nightly_merge.yml
+++ b/.github/workflows/nightly_merge.yml
@@ -23,6 +23,24 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: ๐Ÿ”€ Merge staging/bugfix into maintenance
+ uses: robotology/gh-action-nightly-merge@v1.3.3
+ with:
+ stable_branch: "staging/bugfix"
+ development_branch: "maintenance"
+ allow_ff: false
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: ๐Ÿ”€ Merge staging/maintenance into maintenance
+ uses: robotology/gh-action-nightly-merge@v1.3.3
+ with:
+ stable_branch: "staging/bugfix"
+ development_branch: "maintenance"
+ allow_ff: false
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
- name: ๐Ÿ”€ Merge maintenance into devel
uses: robotology/gh-action-nightly-merge@v1.3.3
with:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 42120070c..c04d91f59 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -54,6 +54,7 @@ repos:
- id: flake8
additional_dependencies:
- flake8-bugbear==22.3.20
+ - importlib-metadata<5.0
exclude: ^(docs/)
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v2.5.1
diff --git a/src/octoprint/plugins/backup/__init__.py b/src/octoprint/plugins/backup/__init__.py
index 19e1e69b3..643f9aa11 100644
--- a/src/octoprint/plugins/backup/__init__.py
+++ b/src/octoprint/plugins/backup/__init__.py
@@ -390,9 +390,7 @@ class BackupPlugin(
"as_attachment": True,
"path_validation": path_validation_factory(
lambda path: not is_hidden_path(path)
- and self._match_backup_filename(
- os.path.basename(path), self._settings
- ),
+ and self._valid_backup(path),
status_code=404,
),
"access_validation": access_validation_factory(
@@ -739,9 +737,7 @@ class BackupPlugin(
for entry in os.scandir(self.get_plugin_data_folder()):
if is_hidden_path(entry.path):
continue
- if not entry.is_file():
- continue
- if not entry.name.endswith(".zip"):
+ if not self._valid_backup(entry.path):
continue
backups.append(
@@ -1374,13 +1370,6 @@ class BackupPlugin(
)
@classmethod
- def _match_backup_filename(cls, path, settings):
- import re
-
- backup_prefix = cls._get_backup_prefix(settings)
- return re.match(re.escape(backup_prefix) + r"-backup-\d{8}-\d{6}.zip", path)
-
- @classmethod
def _get_backup_prefix(cls, settings):
if settings.global_get(["appearance", "name"]) == "":
backup_prefix = "octoprint"
@@ -1397,6 +1386,17 @@ class BackupPlugin(
not in valid_boolean_trues
)
+ @classmethod
+ def _valid_backup(cls, path):
+ if not path.endswith(".zip") or not zipfile.is_zipfile(path):
+ return False
+
+ try:
+ with zipfile.ZipFile(path) as z:
+ return "metadata.json" in z.namelist()
+ except Exception:
+ return False
+
def _send_client_message(self, message, payload=None):
if payload is None:
payload = {}
diff --git a/src/octoprint/server/__init__.py b/src/octoprint/server/__init__.py
index 9ae57cf8d..08dd56999 100644
--- a/src/octoprint/server/__init__.py
+++ b/src/octoprint/server/__init__.py
@@ -1476,6 +1476,7 @@ class Server:
app,
key_func=get_remote_address,
enabled=s.getBoolean(["devel", "enableRateLimiter"]),
+ storage_uri="memory://",
)
def _setup_i18n(self, app):
diff --git a/src/octoprint/server/util/flask.py b/src/octoprint/server/util/flask.py
index b14d84777..ec0d0b7e5 100644
--- a/src/octoprint/server/util/flask.py
+++ b/src/octoprint/server/util/flask.py
@@ -588,7 +588,9 @@ class OctoPrintFlaskResponse(flask.Response):
kwargs["samesite"] = samesite
# set secure if necessary
- kwargs["secure"] = settings().getBoolean(["server", "cookies", "secure"])
+ kwargs["secure"] = flask.request.environ.get(
+ "wsgi.url_scheme"
+ ) == "https" or settings().getBoolean(["server", "cookies", "secure"])
# tie account properties to remember me cookie (e.g. current password hash)
if key == current_app.config.get("REMEMBER_COOKIE_NAME", REMEMBER_COOKIE_NAME):
diff --git a/src/octoprint/static/js/app/client/base.js b/src/octoprint/static/js/app/client/base.js
index 79870fd86..9bc72ce2f 100644
--- a/src/octoprint/static/js/app/client/base.js
+++ b/src/octoprint/static/js/app/client/base.js
@@ -107,13 +107,14 @@
return url;
};
- OctoPrintClient.prototype.getParsedBaseUrl = function () {
+ OctoPrintClient.prototype.getParsedBaseUrl = function (location) {
if (!this.options.baseurl) return "";
try {
var url = new URL(this.options.baseurl);
} catch (e) {
- var parsed = new URL(window.location);
+ location = location || window.location;
+ var parsed = new URL(location);
var path = this.options.baseurl;
if (!path || path[0] !== "/") {
path = "/" + (path ? path : "");
@@ -135,7 +136,7 @@
if (path.endsWith("/")) {
path = path.substring(0, path.length - 1);
}
- return "_P" + port + "_R" + path.replace(/\//, "|");
+ return "_P" + port + "_R" + path.replace(/\//g, "|");
} else {
return "_P" + port;
}
diff --git a/tests/cypress/package-lock.json b/tests/cypress/package-lock.json
index 35f278b3c..5c20777e8 100644
--- a/tests/cypress/package-lock.json
+++ b/tests/cypress/package-lock.json
@@ -1571,9 +1571,12 @@
}
},
"node_modules/minimist": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
- "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
+ "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
},
"node_modules/ms": {
"version": "2.1.2",
@@ -3279,9 +3282,9 @@
}
},
"minimist": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
- "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
+ "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g=="
},
"ms": {
"version": "2.1.2",
diff --git a/tests/static/js/test-client-base.html b/tests/static/js/test-client-base.html
new file mode 100644
index 000000000..fa69c3fea
--- /dev/null
+++ b/tests/static/js/test-client-base.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>src/octoprint/static/js/app/client/base.js Tests</title>
+ <link rel="stylesheet" href="lib/qunit-1.18.0.css" />
+ </head>
+ <body>
+ <div id="qunit"></div>
+ <div id="qunit-fixture"></div>
+ <script src="lib/qunit-1.18.0.js"></script>
+ <script src="lib/qunit-parameterize.js"></script>
+ <script src="../../../src/octoprint/static/js/lib/lodash.min.js"></script>
+ <script src="../../../src/octoprint/static/js/lib/sprintf.min.js"></script>
+ <script src="../../../src/octoprint/static/js/app/client/base.js"></script>
+ <script src="test-client-base.js"></script>
+ </body>
+</html>
diff --git a/tests/static/js/test-client-base.js b/tests/static/js/test-client-base.js
new file mode 100644
index 000000000..6d39fa39f
--- /dev/null
+++ b/tests/static/js/test-client-base.js
@@ -0,0 +1,110 @@
+_.mixin({sprintf: sprintf, vsprintf: vsprintf});
+
+QUnit.module("getParsedBaseUrl");
+QUnit.cases(
+ (function () {
+ return [
+ {
+ title: "fully qualified baseurl",
+ baseurl: "https://example.com",
+ location: undefined,
+ expected: "https://example.com/"
+ },
+ {
+ title: "fully qualified baseurl with http",
+ baseurl: "http://example.com",
+ location: undefined,
+ expected: "http://example.com/"
+ },
+ {
+ title: "fully qualified baseurl with custom port",
+ baseurl: "https://example.com:5000",
+ location: undefined,
+ expected: "https://example.com:5000/"
+ },
+ {
+ title: "website root",
+ baseurl: "/",
+ location: "https://example.com",
+ expected: "https://example.com/"
+ },
+ {
+ title: "website root with custom port",
+ baseurl: "/",
+ location: "https://example.com:5000",
+ expected: "https://example.com:5000/"
+ },
+ {
+ title: "single level prefix",
+ baseurl: "/octoprint/",
+ location: "https://example.com",
+ expected: "https://example.com/octoprint/"
+ },
+ {
+ title: "multi level prefix",
+ baseurl: "/path/to/octoprint/",
+ location: "https://example.com",
+ expected: "https://example.com/path/to/octoprint/"
+ },
+ {
+ title: "multi level prefix with http and custom port",
+ baseurl: "/path/to/octoprint/",
+ location: "http://example.com:5000",
+ expected: "http://example.com:5000/path/to/octoprint/"
+ },
+ {
+ title: "multi level prefix with https, custom port, no trailing slash",
+ baseurl: "/path/to/octoprint",
+ location: "https://example.com:5001",
+ expected: "https://example.com:5001/path/to/octoprint"
+ }
+ ];
+ })()
+).test("getParsedBaseUrl", function (params, assert) {
+ OctoPrint.options.baseurl = params.baseurl;
+ assert.equal(
+ OctoPrint.getParsedBaseUrl(params.location).toString(),
+ params.expected,
+ "Expected: " + String(params.expected)
+ );
+});
+
+QUnit.module("getCookieSuffix");
+QUnit.cases(
+ (function () {
+ return [
+ {
+ title: "http with default port",
+ baseurl: "http://example.com",
+ expected: "_P80"
+ },
+ {
+ title: "https with default port",
+ baseurl: "https://example.com",
+ expected: "_P443"
+ },
+ {
+ title: "custom port",
+ baseurl: "http://example.com:5000",
+ expected: "_P5000"
+ },
+ {
+ title: "single level prefix",
+ baseurl: "https://example.com/octoprint/",
+ expected: "_P443_R|octoprint"
+ },
+ {
+ title: "multi level prefix",
+ baseurl: "https://example.com/path/to/octoprint",
+ expected: "_P443_R|path|to|octoprint"
+ }
+ ];
+ })()
+).test("getCookieSuffix", function (params, assert) {
+ OctoPrint.options.baseurl = params.baseurl;
+ assert.equal(
+ OctoPrint.getCookieSuffix(),
+ params.expected,
+ "Expected: " + String(params.expected)
+ );
+});