diff --git a/files.js b/files.js index 0c8f6e0f5fb3..b45bb25d4426 100644 --- a/files.js +++ b/files.js @@ -65,7 +65,6 @@ const info = { "base1/test-locale.js", "base1/test-location.js", "base1/test-metrics.js", - "base1/test-no-jquery.js", "base1/test-path.ts", "base1/test-permissions.js", "base1/test-promise.ts", diff --git a/pkg/apps/appstream.js b/pkg/apps/appstream.js index 998e9f26818d..4ec85c1e02ba 100644 --- a/pkg/apps/appstream.js +++ b/pkg/apps/appstream.js @@ -50,11 +50,7 @@ export function get_metainfo_db() { debug("read metainfo_db:", metainfo_db); } }) - .fail(function (error) { - if (error != "closed") { - console.warn(error); - } - }); + .catch(error => console.warn("watch-appstream.py failed:", error)); } return metainfo_db; diff --git a/pkg/base1/test-no-jquery.js b/pkg/base1/test-no-jquery.js deleted file mode 100644 index 85ccb6a978d4..000000000000 --- a/pkg/base1/test-no-jquery.js +++ /dev/null @@ -1,29 +0,0 @@ -import cockpit from "cockpit"; -import QUnit from "qunit-tests"; - -QUnit.test("cockpit object without jQuery", assert => { - const done = assert.async(); - assert.expect(8); - - assert.equal(typeof jQuery, "undefined", "jQuery is not defined"); - assert.equal(typeof $, "undefined", "$ is not defined"); - assert.equal(typeof cockpit, "object", "cockpit is defined"); - assert.notEqual(cockpit.channel, undefined, "cockpit.channel is defined"); - assert.notEqual(cockpit.spawn, undefined, "cockpit.spawn is defined"); - - /* Actually try to do something useful */ - let got_message = false; - const channel = cockpit.channel({ payload: "stream", spawn: ["sh", "-c", "echo hello"] }); - channel.onmessage = ev => { - got_message = true; - assert.equal(ev.detail, "hello\n", "channel message correct"); - channel.onmessage = null; - }; - channel.onclose = ev => { - assert.equal(ev.detail.command, "close", "channel close data correct"); - assert.ok(got_message, "channel got message"); - done(); - }; -}); - -QUnit.start(); diff --git a/pkg/lib/cockpit.d.ts b/pkg/lib/cockpit.d.ts index a3fb4a00f871..a0fdda253b31 100644 --- a/pkg/lib/cockpit.d.ts +++ b/pkg/lib/cockpit.d.ts @@ -213,6 +213,12 @@ declare module 'cockpit' { changed(changes: { [property: string]: unknown }): void; } + interface DBusProxiesEvents extends EventMap { + added(proxy: DBusProxy): void; + changed(proxy: DBusProxy): void; + removed(proxy: DBusProxy): void; + } + interface DBusProxy extends EventSource { valid: boolean; [property: string]: unknown; @@ -232,10 +238,18 @@ declare module 'cockpit' { timeout?: number, }; + interface DBusProxies extends EventSource { + client: DBusClient; + iface: string; + path_namespace: string; + wait(callback?: () => void): Promise; + } + interface DBusClient { readonly unique_name: string; readonly options: DBusOptions; proxy(interface?: string, path?: string, options?: { watch?: boolean }): DBusProxy; + proxies(interface?: string, path_namespace?: string, options?: { watch?: boolean }): DBusProxies; call(path: string, iface: string, method: string, args?: unknown[] | null, options?: DBusCallOptions): Promise; watch(path: string): DeferredPromise, close(): void; diff --git a/pkg/lib/cockpit.js b/pkg/lib/cockpit.js index c40e4a479492..48da2e5fbe55 100644 --- a/pkg/lib/cockpit.js +++ b/pkg/lib/cockpit.js @@ -1547,21 +1547,23 @@ function factory() { const self = this; event_mixin(self, { }); + self.client = client; + self.iface = iface; + self.path_namespace = path_namespace; + let waits; + self.wait = function(func) { + if (func) + waits.always(func); + return waits; + }; + Object.defineProperties(self, { - client: { value: client, enumerable: false, writable: false }, - iface: { value: iface, enumerable: false, writable: false }, - path_namespace: { value: path_namespace, enumerable: false, writable: false }, - wait: { - enumerable: false, - writable: false, - value: function(func) { - if (func) - waits.always(func); - return waits; - } - } + client: { enumerable: false, writable: false }, + iface: { enumerable: false, writable: false }, + path_namespace: { enumerable: false, writable: false }, + wait: { enumerable: false, writable: false }, }); /* Subscribe to signals once for all proxies */ diff --git a/pkg/lib/cockpit/_internal/channel.js b/pkg/lib/cockpit/_internal/channel.js index db66981b519b..5a80002f233d 100644 --- a/pkg/lib/cockpit/_internal/channel.js +++ b/pkg/lib/cockpit/_internal/channel.js @@ -103,7 +103,12 @@ export function Channel(options) { /* Now open the channel */ const command = { }; for (const i in options) - command[i] = options[i]; + if (i !== "binary") + command[i] = options[i]; + /* handle binary specially: Our JS API has always been boolean, while the wire protocol is + * a string with the only valid value "raw". */ + if (binary) + command.binary = "raw"; command.command = "open"; command.channel = id; @@ -112,11 +117,6 @@ export function Channel(options) { command.host = transport_globals.default_host; } - if (binary) - command.binary = "raw"; - else - delete command.binary; - command["flow-control"] = true; transport.send_control(command); diff --git a/pkg/shell/machines/machines.d.ts b/pkg/shell/machines/machines.d.ts index 69967ec4b15b..6a8b7bac0a36 100644 --- a/pkg/shell/machines/machines.d.ts +++ b/pkg/shell/machines/machines.d.ts @@ -4,6 +4,8 @@ import { Manifests } from "../manifests"; export function generate_connection_string(user: string | null, port: string | null, addr: string) : string; export function split_connection_string (conn_to: string) : { address: string, user?: string, port?: number }; +export function get_init_superuser_for_options (options: {[key: string]: string }) : string | null; +export function host_superuser_storage_key (host: string): string; export interface Machine { key: string; diff --git a/pkg/storaged/crypto/keyslots.jsx b/pkg/storaged/crypto/keyslots.jsx index 7e78ac999132..63b91a713c29 100644 --- a/pkg/storaged/crypto/keyslots.jsx +++ b/pkg/storaged/crypto/keyslots.jsx @@ -387,6 +387,7 @@ function ensure_non_root_nbde_support(steps, progress, client, block) { .then(() => ensure_crypto_option(steps, progress, client, block, "_netdev")); } +/** @type (client: any, path: string) => boolean */ function contains_rootfs(client, path) { const block = client.blocks[path]; const crypto = client.blocks_crypto[path]; diff --git a/pkg/systemd/hwinfo.jsx b/pkg/systemd/hwinfo.jsx index 30196f0dc3d1..c32437ba5f42 100644 --- a/pkg/systemd/hwinfo.jsx +++ b/pkg/systemd/hwinfo.jsx @@ -125,9 +125,11 @@ const SystemInfo = ({ info, onSecurityClick }) => { ); }; +let cachedMitigations; + function availableMitigations() { - if (availableMitigations.cachedMitigations !== undefined) - return Promise.resolve(availableMitigations.cachedMitigations); + if (cachedMitigations !== undefined) + return Promise.resolve(cachedMitigations); /* nosmt */ const promises = [cockpit.spawn(["lscpu"], { environ: ["LC_ALL=C.UTF-8"], }), cockpit.file("/proc/cmdline").read()]; return Promise.all(promises).then(values => { @@ -146,12 +148,12 @@ function availableMitigations() { const nosmt_available = threads_per_core > 1 && (values[1].indexOf("nosmt=") === -1 || values[1].indexOf("nosmt=force") !== -1); const mitigations_match = values[1].match(/\bmitigations=(\S*)\b/); - availableMitigations.cachedMitigations = { + cachedMitigations = { available: nosmt_available, nosmt_enabled, mitigations_arg: mitigations_match ? mitigations_match[1] : undefined, }; - return availableMitigations.cachedMitigations; + return cachedMitigations; }); } @@ -172,7 +174,7 @@ const CPUSecurityMitigationsDialog = () => { options = ['set', 'nosmt']; } else { // this may either be an argument of its own, or part of mitigations= - const ma = availableMitigations.cachedMitigations.mitigations_arg; + const ma = cachedMitigations.mitigations_arg; if (ma && ma.indexOf("nosmt") >= 0) { const new_args = ma.split(',').filter(opt => opt != 'nosmt'); options = ['set', 'mitigations=' + new_args.join(',')]; diff --git a/pkg/systemd/services.jsx b/pkg/systemd/services.jsx index 03b226aa93b9..62084bdd29d0 100644 --- a/pkg/systemd/services.jsx +++ b/pkg/systemd/services.jsx @@ -790,7 +790,13 @@ const ServicesPageFilters = ({ const onDeleteChipGroup = (typeLabel) => { const type = getFilterLabelKey(typeLabel); - setFilters({ ...filters, [type]: [] }); + if (type) + setFilters({ ...filters, [type]: [] }); + else + setFilters({ + activeState: [], + fileState: [] + }); }; const onClearAllFilters = useCallback(() => { diff --git a/test/common/typecheck b/test/common/typecheck index 2105fe1f93f5..1126a1e76b6f 100755 --- a/test/common/typecheck +++ b/test/common/typecheck @@ -53,7 +53,6 @@ ignored_codes = [ "TS7005", # Variable '*' implicitly has an 'any[]' type. "TS7006", # Parameter '*' implicitly has an 'any' type. "TS7008", # Member '*' implicitly has an 'any[]' type. - "TS7009", # 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. "TS7010", # '*', which lacks return-type annotation, implicitly has an 'any' return type. "TS7015", # Element implicitly has an 'any' type because index expression is not of type '*'. "TS7016", # Could not find a declaration file for module '*'... @@ -72,13 +71,11 @@ javascript_ignored_codes = [ "TS7005", # Variable '*' implicitly has an 'any[]' type. "TS7006", # Parameter '*' implicitly has an 'any' type. "TS7008", # Member '*' implicitly has an 'any[]' type. - "TS7009", # 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. "TS7015", # Element implicitly has an 'any' type because index expression is not of type '*'. "TS7016", # Could not find a declaration file for module '*'... "TS7019", # Rest parameter '*' implicitly has an 'any[]' type "TS7022", # '*' implicitly has type 'any'... "TS7023", # '*' implicitly has return type 'any' because ... - "TS7024", # Function implicitly has return type 'any' because ... "TS7031", # Binding element '*' implicitly has an 'any' type. "TS7034", # Variable '*' implicitly has type 'any' in some locations where its type cannot be determined. "TS7053", # Element implicitly has an 'any' type because expression of type 'any' can't be used to @@ -99,15 +96,10 @@ javascript_ignored_codes = [ "TS2741", # Property 'X' is missing in type "TS2551", # Property 'X' does not exist on type "TS2304", # Cannot find name 'X' - "TS2581", # Cannot find name '$'. Do you need to install type definitions for jQuery? - "TS2305", # Module '"./machines/machines"' has no exported member 'get_init_superuser_for_options'. - "TS2790", # The operand of a 'delete' operator must be optional. - "TS2367", # This comparison appears to be unintentional because the types 'Error' and 'string' have no overlap. "TS2538", # Type 'null' cannot be used as an index type. "TS2559", # Type 'never[]' has no properties in common with type 'DBusCallOptions'. "TS2769", # No overload matches this call. "TS2739", # Type '{ title: string; value: string; }' is missing the following properties from type - "TS2464", # A computed property name must be of type 'string', 'number', 'symbol', or 'any'. "TS2488", # Type 'X' must have a '[Symbol.iterator]()' method that returns an iterator. "TS2349", # This expression is not callable. "TS2554", # Expected 0 arguments, but got 1.