Fix OIDC login callback handling on Element Desktop (#33332)

* Fix OIDC login callback handling on Element Desktop

* Add unit tests

* Iterate

* Fix lcov reporter

* Fix coverage paths

* Fix coverage upload

* Ensure `.test.ts` files don't get included in the desktop package

* Fix coverage artifact name

* Delint

* Tidy coverage name

* Improve coverage
This commit is contained in:
Michael Telatynski 2026-04-29 15:05:38 +01:00 committed by GitHub
parent 5ff302539e
commit 6aee85aef5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 395 additions and 32 deletions

View File

@ -93,7 +93,7 @@ jobs:
if: env.ENABLE_COVERAGE == 'true'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: coverage-${{ matrix.runner }}
name: coverage-jest-${{ matrix.runner }}
path: |
apps/web/coverage
!apps/web/coverage/lcov-report
@ -124,9 +124,10 @@ jobs:
name: Vitest
strategy:
matrix:
package:
- shared-components
- module-api
path:
- apps/desktop
- packages/shared-components
- packages/module-api
runs-on: ubuntu-24.04
steps:
- name: Checkout code
@ -149,30 +150,39 @@ jobs:
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
with:
path: |
packages/${{ matrix.package }}/node_modules/.cache
packages/${{ matrix.package }}/node_modules/.vite/vitest
key: ${{ hashFiles('pnpm-lock.yaml') }}
${{ matrix.path }}/node_modules/.cache
${{ matrix.path }}/node_modules/.vite/vitest
key: ${{ matrix.path }}-${{ hashFiles('pnpm-lock.yaml') }}
- name: Setup playwright
uses: ./.github/actions/setup-playwright
if: matrix.package == 'shared-components'
if: matrix.path == 'packages/shared-components'
with:
write-cache: ${{ github.event_name != 'merge_group' }}
- name: Run tests
working-directory: "packages/${{ matrix.package }}"
working-directory: ${{ matrix.path }}
run: pnpm test:unit --coverage=$ENABLE_COVERAGE
# Dump the disk usage on failure, because this job seems to fail with disk fills sometimes
- name: df
run: df
run: df -h && df -i
if: ${{ failure() }}
- name: Calculate artifact name
if: env.ENABLE_COVERAGE == 'true'
id: artifact
run: |
NAME=$(basename "$MATRIX_PATH")
echo "name=$NAME" >> $GITHUB_OUTPUT
env:
MATRIX_PATH: ${{ matrix.path }}
- name: Upload Artifact
if: env.ENABLE_COVERAGE == 'true'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: coverage-${{ matrix.package }}
name: coverage-${{ steps.artifact.outputs.name }}
path: |
packages/${{ matrix.package }}/coverage
!packages/${{ matrix.package }}/coverage/lcov-report
${{ matrix.path }}/coverage
!${{ matrix.path }}/coverage/lcov-report

View File

@ -86,5 +86,12 @@ module.exports = {
"@typescript-eslint/no-non-null-assertion": "off",
},
},
{
files: ["src/**/*.test.ts", "electron-builder.ts", "vitest.config.ts"],
extends: ["plugin:matrix-org/typescript"],
parserOptions: {
project: ["tsconfig.node.json"],
},
},
],
};

View File

@ -52,6 +52,7 @@ interface Variant extends Metadata {
}
type Writable<T> = NonNullable<
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
T extends Function ? T : T extends object ? { -readonly [K in keyof T]: Writable<T[K]> } : T
>;
@ -74,7 +75,7 @@ if (process.env.VARIANT_PATH) {
}
for (const key in variant) {
console.log(`${key}: ${variant[key]}`);
console.log(`${key}: ${variant[key as keyof Variant]}`);
}
interface Configuration extends BaseConfiguration {

View File

@ -32,8 +32,9 @@
"lint": "pnpm lint:types && pnpm lint:js",
"lint:js": "eslint --max-warnings 0 src hak playwright scripts",
"lint:js-fix": "eslint --fix --max-warnings 0 src hak playwright scripts && prettier --log-level=warn --write .",
"lint:types": "pnpm lint:types:src && pnpm lint:types:test && pnpm lint:types:scripts && pnpm lint:types:hak",
"lint:types": "pnpm lint:types:src && pnpm lint:types:node && pnpm lint:types:test && pnpm lint:types:scripts && pnpm lint:types:hak",
"lint:types:src": "tsc --noEmit",
"lint:types:node": "tsc --noEmit -p tsconfig.node.json",
"lint:types:test": "tsc --noEmit -p playwright/tsconfig.json",
"lint:types:scripts": "tsc --noEmit -p scripts/tsconfig.json",
"lint:types:hak": "tsc --noEmit -p hak/tsconfig.json",
@ -49,6 +50,7 @@
"docker:install": "scripts/in-docker.sh pnpm install",
"clean": "rimraf webapp.asar dist packages deploys lib",
"hak": "node scripts/hak/index.ts",
"test:unit": "vitest",
"test:playwright": "nx test:playwright --",
"test:playwright:open": "nx test:playwright -- --ui",
"test:playwright:screenshots": "nx test:playwright:screenshots --",
@ -79,6 +81,7 @@
"@types/pacote": "^11.1.1",
"@typescript-eslint/eslint-plugin": "^8.0.0",
"@typescript-eslint/parser": "^8.0.0",
"@vitest/coverage-v8": "^4.1.5",
"app-builder-lib": "26.9.0",
"chokidar": "^5.0.0",
"detect-libc": "^2.0.0",
@ -95,12 +98,16 @@
"eslint-plugin-unicorn": "^56.0.0",
"glob": "^13.0.0",
"matrix-web-i18n": "catalog:",
"memfs": "^4.57.2",
"mkdirp": "^3.0.0",
"pacote": "^21.0.0",
"prettier": "^3.0.0",
"rimraf": "^6.0.0",
"tar": "^7.5.8",
"typescript": "6.0.3"
"typescript": "6.0.3",
"vite": "^8.0.9",
"vitest": "^4.1.5",
"vitest-sonar-reporter": "^3.0.0"
},
"hakDependencies": {
"matrix-seshat": "4.2.0"

View File

@ -0,0 +1,87 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import { expect, describe, it, beforeEach, vi } from "vitest";
import { fs as memfs, vol } from "memfs";
import ProtocolHandler from "./protocol.js";
const TEST_PROTOCOL = "test.proto";
const TEST_SESSION_ID = "test_session_id";
const USER_DATA_DIR = "/Users/name/Library/Application Support/Element";
vi.mock("node:fs", () => ({ default: memfs }));
vi.mock("electron", () => ({
app: {
getPath: vi.fn().mockReturnValue("/Users/name/Library/Application Support/Element"),
on: vi.fn(),
},
ipcMain: {
handle: vi.fn(),
},
}));
beforeEach(() => {
// Reset the state of the in-memory fs
vol.reset();
});
describe("ProtocolHandler", () => {
describe("getProfileFromDeeplink", () => {
const handler = new ProtocolHandler(TEST_PROTOCOL);
beforeEach(() => {
vol.fromJSON(
{
"./sso-sessions.json": JSON.stringify({ [TEST_SESSION_ID]: USER_DATA_DIR }),
},
USER_DATA_DIR,
);
});
it("should handle legacy SSO URIs", () => {
expect(
handler.getProfileFromDeeplink([
"Element.app",
`element://vector/webapp/?element-desktop-ssoid=${TEST_SESSION_ID}`,
]),
).toBe(USER_DATA_DIR);
});
it("should handle OIDC URIs with response_mode=query", () => {
expect(
handler.getProfileFromDeeplink([
"Element.app",
`${TEST_PROTOCOL}:/vector/webapp/?no_universal_links=true&code=DEADBEEF&state=foobar:element-desktop-ssoid:${TEST_SESSION_ID}`,
]),
).toBe(USER_DATA_DIR);
});
it("should handle OIDC URIs with response_mode=fragment", () => {
expect(
handler.getProfileFromDeeplink([
"Element.app",
`${TEST_PROTOCOL}:/vector/webapp/?no_universal_links=true#code=DEADBEEF&state=foobar:element-desktop-ssoid:${TEST_SESSION_ID}`,
]),
).toBe(USER_DATA_DIR);
});
it("should handle malformed OIDC URIs gracefully", () => {
expect(
handler.getProfileFromDeeplink([
"Element.app",
`${TEST_PROTOCOL}:/vector/webapp/?no_universal_links=true#code=DEADBEEF:element-desktop-ssoid:${TEST_SESSION_ID}`,
]),
).toBeUndefined();
});
it("should handle unrelated URIs gracefully", () => {
expect(handler.getProfileFromDeeplink(["Element.app", `${TEST_PROTOCOL}:/vector/webapp/`])).toBeUndefined();
expect(handler.getProfileFromDeeplink(["Element.app", `test.unrelated:/vector/webapp/`])).toBeUndefined();
});
});
});

View File

@ -97,7 +97,8 @@ export default class ProtocolHandler {
const s = fs.readFileSync(storePath, { encoding: "utf8" });
const o = JSON.parse(s);
return typeof o === "object" ? o : {};
} catch {
} catch (e) {
console.warn("Unable to read protocol store, starting with empty store: ", e);
return {};
}
}
@ -130,10 +131,26 @@ export default class ProtocolHandler {
let sessionId = parsedUrl.searchParams.get(SEARCH_PARAM);
if (!sessionId) {
// In OIDC, we must shuttle the value in the `state` param rather than `element-desktop-ssoid`
// We encode it as a suffix like `:element-desktop-ssoid:XXYYZZ`
sessionId = parsedUrl.searchParams.get("state")!.split(`:${SEARCH_PARAM}:`)[1];
// We encode it as a suffix like `:element-desktop-ssoid:XXYYZZ`.
// The OIDC flow may have used response_mode=fragment or query, so we need to handle both cases.
let searchParams = parsedUrl.searchParams;
if (parsedUrl.hash.includes("=")) {
const [params] = parsedUrl.hash.substring(1).split("?", 2);
searchParams = new URLSearchParams(params);
}
const state = searchParams.get("state");
if (state) {
sessionId = state.split(`:${SEARCH_PARAM}:`)[1];
}
}
console.log("Forwarding to profile: ", store[sessionId]);
if (!sessionId) {
console.warn("Unable to read session ID in deeplink url:", deeplinkUrl);
return undefined;
}
console.log("Forwarding to profile:", store[sessionId]);
return store[sessionId];
}
}

View File

@ -14,5 +14,6 @@
"lib": ["es2022", "es2024.promise"],
"strict": true
},
"include": ["./src/**/*.ts", "./src/**/*.cts"]
"include": ["./src/**/*.ts", "./src/**/*.cts"],
"exclude": ["./src/**/*.test.ts"]
}

View File

@ -0,0 +1,15 @@
{
"compilerOptions": {
"resolveJsonModule": true,
"module": "nodenext",
"moduleResolution": "NodeNext",
"target": "es2022",
"sourceMap": false,
"typeRoots": [],
"types": [],
"skipLibCheck": true,
"noEmit": true,
"strict": true
},
"include": ["./electron-builder.ts", "./vitest.config.ts", "./src/**/*.d.ts", "./src/**/*.test.ts"]
}

View File

@ -0,0 +1,64 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import { defineConfig } from "vitest/config";
import { type UserConfig } from "vite";
import { type Reporter } from "vitest/reporters";
import { env } from "node:process";
const reporters: NonNullable<UserConfig["test"]>["reporters"] = [["default"]];
const slowTestReporter: Reporter = {
onTestRunEnd(testModules, unhandledErrors, reason) {
const tests = testModules
.flatMap((m) => Array.from(m.children.allTests()))
.filter((test) => test.diagnostic()?.slow);
tests.sort((x, y) => x.diagnostic()!.duration! - y.diagnostic()!.duration!);
tests.reverse();
if (tests.length > 0) {
console.warn("Slowest 10 tests:");
}
for (const t of tests.slice(0, 10)) {
console.warn(`${t.module.moduleId} > ${t.fullName}: ${t.diagnostic()?.duration.toFixed(0)}ms`);
}
},
};
// if we're running under GHA, enable the GHA & Sonar reporters
if (env["GITHUB_ACTIONS"] !== undefined) {
reporters.push(["github-actions", { silent: false }]);
reporters.push([
"vitest-sonar-reporter",
{
outputFile: "coverage/sonar-report.xml",
onWritePath: (path): string => `apps/desktop/${path}`,
},
]);
// if we're running against the develop branch, also enable the slow test reporter
if (env["GITHUB_REF"] == "refs/heads/develop") {
reporters.push(slowTestReporter);
}
}
export default defineConfig({
test: {
coverage: {
provider: "v8",
include: ["src/**/*"],
// The coverage report currently chokes on this file as it doesn't process it as TypeScript
exclude: ["src/preload.cts"],
reporter: [["lcov", { projectRoot: "../../" }]],
},
environment: "node",
reporters,
globals: true,
pool: "threads",
include: ["src/**/*.test.ts"],
},
});

149
pnpm-lock.yaml generated
View File

@ -243,6 +243,9 @@ importers:
'@typescript-eslint/parser':
specifier: ^8.0.0
version: 8.58.2(eslint@8.57.1)(typescript@6.0.3)
'@vitest/coverage-v8':
specifier: ^4.1.5
version: 4.1.5(@vitest/browser@4.1.5)(vitest@4.1.5)
app-builder-lib:
specifier: 26.9.0
version: 26.9.0(patch_hash=2dfb3fcdfe573cca6c248cecf63ddea5c8fa0276859695fba6c9664d0ff285d6)(dmg-builder@26.9.0)(electron-builder-squirrel-windows@26.9.0)
@ -291,6 +294,9 @@ importers:
matrix-web-i18n:
specifier: 'catalog:'
version: 3.6.0
memfs:
specifier: ^4.57.2
version: 4.57.2(tslib@2.8.1)
mkdirp:
specifier: ^3.0.0
version: 3.0.1
@ -309,6 +315,15 @@ importers:
typescript:
specifier: 6.0.3
version: 6.0.3
vite:
specifier: ^8.0.9
version: 8.0.9(@types/node@18.19.130)(esbuild@0.27.4)(jiti@2.6.1)(sugarss@5.0.1(postcss@8.5.10))(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
vitest:
specifier: ^4.1.5
version: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@18.19.130)(@vitest/browser-playwright@4.1.5)(@vitest/coverage-v8@4.1.5)(jsdom@26.1.0(patch_hash=040623e87b1c8b676c2a705513c0276c0704dd1b23fc3a1bb77cde8128b64b5f))(vite@8.0.9(@types/node@18.19.130)(esbuild@0.27.4)(jiti@2.6.1)(sugarss@5.0.1(postcss@8.5.10))(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
vitest-sonar-reporter:
specifier: ^3.0.0
version: 3.0.0(vitest@4.1.5)
apps/web:
dependencies:
@ -446,7 +461,7 @@ importers:
version: 1.0.3
matrix-js-sdk:
specifier: github:matrix-org/matrix-js-sdk#develop
version: https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/60993dd10ada731e37db81873fede2a0afa93a6b
version: https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/69985ee350a33ba75f1ad11f96468344f0c92a8d
matrix-widget-api:
specifier: ^1.17.0
version: 1.17.0
@ -2987,48 +3002,96 @@ packages:
peerDependencies:
tslib: '2'
'@jsonjoy.com/fs-core@4.57.2':
resolution: {integrity: sha512-SVjwklkpIV5wrynpYtuYnfYH1QF4/nDuLBX7VXdb+3miglcAgBVZb/5y0cOsehRV/9Vb+3UqhkMq3/NR3ztdkQ==}
engines: {node: '>=10.0'}
peerDependencies:
tslib: '2'
'@jsonjoy.com/fs-fsa@4.56.10':
resolution: {integrity: sha512-/FVK63ysNzTPOnCCcPoPHt77TOmachdMS422txM4KhxddLdbW1fIbFMYH0AM0ow/YchCyS5gqEjKLNyv71j/5Q==}
engines: {node: '>=10.0'}
peerDependencies:
tslib: '2'
'@jsonjoy.com/fs-fsa@4.57.2':
resolution: {integrity: sha512-fhO8+iR2I+OCw668ISDJdn1aArc9zx033sWejIyzQ8RBeXa9bDSaUeA3ix0poYOfrj1KdOzytmYNv2/uLDfV6g==}
engines: {node: '>=10.0'}
peerDependencies:
tslib: '2'
'@jsonjoy.com/fs-node-builtins@4.56.10':
resolution: {integrity: sha512-uUnKz8R0YJyKq5jXpZtkGV9U0pJDt8hmYcLRrPjROheIfjMXsz82kXMgAA/qNg0wrZ1Kv+hrg7azqEZx6XZCVw==}
engines: {node: '>=10.0'}
peerDependencies:
tslib: '2'
'@jsonjoy.com/fs-node-builtins@4.57.2':
resolution: {integrity: sha512-xhiegylRmhw43Ki2HO1ZBL7DQ5ja/qpRsL29VtQ2xuUHiuDGbgf2uD4p9Qd8hJI5P6RCtGYD50IXHXVq/Ocjcg==}
engines: {node: '>=10.0'}
peerDependencies:
tslib: '2'
'@jsonjoy.com/fs-node-to-fsa@4.56.10':
resolution: {integrity: sha512-oH+O6Y4lhn9NyG6aEoFwIBNKZeYy66toP5LJcDOMBgL99BKQMUf/zWJspdRhMdn/3hbzQsZ8EHHsuekbFLGUWw==}
engines: {node: '>=10.0'}
peerDependencies:
tslib: '2'
'@jsonjoy.com/fs-node-to-fsa@4.57.2':
resolution: {integrity: sha512-18LmWTSONhoAPW+IWRuf8w/+zRolPFGPeGwMxlAhhfY11EKzX+5XHDBPAw67dBF5dxDErHJbl40U+3IXSDRXSQ==}
engines: {node: '>=10.0'}
peerDependencies:
tslib: '2'
'@jsonjoy.com/fs-node-utils@4.56.10':
resolution: {integrity: sha512-8EuPBgVI2aDPwFdaNQeNpHsyqPi3rr+85tMNG/lHvQLiVjzoZsvxA//Xd8aB567LUhy4QS03ptT+unkD/DIsNg==}
engines: {node: '>=10.0'}
peerDependencies:
tslib: '2'
'@jsonjoy.com/fs-node-utils@4.57.2':
resolution: {integrity: sha512-rsPSJgekz43IlNbLyAM/Ab+ouYLWGp5DDBfYBNNEqDaSpsbXfthBn29Q4muFA9L0F+Z3mKo+CWlgSCXrf+mOyQ==}
engines: {node: '>=10.0'}
peerDependencies:
tslib: '2'
'@jsonjoy.com/fs-node@4.56.10':
resolution: {integrity: sha512-7R4Gv3tkUdW3dXfXiOkqxkElxKNVdd8BDOWC0/dbERd0pXpPY+s2s1Mino+aTvkGrFPiY+mmVxA7zhskm4Ue4Q==}
engines: {node: '>=10.0'}
peerDependencies:
tslib: '2'
'@jsonjoy.com/fs-node@4.57.2':
resolution: {integrity: sha512-nX2AdL6cOFwLdju9G4/nbRnYevmCJbh7N7hvR3gGm97Cs60uEjyd0rpR+YBS7cTg175zzl22pGKXR5USaQMvKg==}
engines: {node: '>=10.0'}
peerDependencies:
tslib: '2'
'@jsonjoy.com/fs-print@4.56.10':
resolution: {integrity: sha512-JW4fp5mAYepzFsSGrQ48ep8FXxpg4niFWHdF78wDrFGof7F3tKDJln72QFDEn/27M1yHd4v7sKHHVPh78aWcEw==}
engines: {node: '>=10.0'}
peerDependencies:
tslib: '2'
'@jsonjoy.com/fs-print@4.57.2':
resolution: {integrity: sha512-wK9NSow48i4DbDl9F1CQE5TqnyZOJ04elU3WFG5aJ76p+YxO/ulyBBQvKsessPxdo381Bc2pcEoyPujMOhcRqQ==}
engines: {node: '>=10.0'}
peerDependencies:
tslib: '2'
'@jsonjoy.com/fs-snapshot@4.56.10':
resolution: {integrity: sha512-DkR6l5fj7+qj0+fVKm/OOXMGfDFCGXLfyHkORH3DF8hxkpDgIHbhf/DwncBMs2igu/ST7OEkexn1gIqoU6Y+9g==}
engines: {node: '>=10.0'}
peerDependencies:
tslib: '2'
'@jsonjoy.com/fs-snapshot@4.57.2':
resolution: {integrity: sha512-GdduDZuoP5V/QCgJkx9+BZ6SC0EZ/smXAdTS7PfMqgMTGXLlt/bH/FqMYaqB9JmLf05sJPtO0XRbAwwkEEPbVw==}
engines: {node: '>=10.0'}
peerDependencies:
tslib: '2'
'@jsonjoy.com/json-pack@1.21.0':
resolution: {integrity: sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==}
engines: {node: '>=10.0'}
@ -9934,8 +9997,8 @@ packages:
matrix-events-sdk@0.0.1:
resolution: {integrity: sha512-1QEOsXO+bhyCroIe2/A5OwaxHvBm7EsSQ46DEDn8RBIfQwN5HWBpFvyWWR4QY0KHPPnnJdI99wgRiAl7Ad5qaA==}
matrix-js-sdk@https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/60993dd10ada731e37db81873fede2a0afa93a6b:
resolution: {tarball: https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/60993dd10ada731e37db81873fede2a0afa93a6b}
matrix-js-sdk@https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/69985ee350a33ba75f1ad11f96468344f0c92a8d:
resolution: {tarball: https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/69985ee350a33ba75f1ad11f96468344f0c92a8d}
version: 41.4.0
engines: {node: '>=22.0.0'}
@ -9980,6 +10043,11 @@ packages:
peerDependencies:
tslib: '2'
memfs@4.57.2:
resolution: {integrity: sha512-2nWzSsJzrukurSDna4Z0WywuScK4Id3tSKejgu74u8KCdW4uNrseKRSIDg75C6Yw5ZRqBe0F0EtMNlTbUq8bAQ==}
peerDependencies:
tslib: '2'
memoize-one@5.2.1:
resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==}
@ -15586,6 +15654,13 @@ snapshots:
thingies: 2.5.0(tslib@2.8.1)
tslib: 2.8.1
'@jsonjoy.com/fs-core@4.57.2(tslib@2.8.1)':
dependencies:
'@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1)
'@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1)
thingies: 2.5.0(tslib@2.8.1)
tslib: 2.8.1
'@jsonjoy.com/fs-fsa@4.56.10(tslib@2.8.1)':
dependencies:
'@jsonjoy.com/fs-core': 4.56.10(tslib@2.8.1)
@ -15594,10 +15669,22 @@ snapshots:
thingies: 2.5.0(tslib@2.8.1)
tslib: 2.8.1
'@jsonjoy.com/fs-fsa@4.57.2(tslib@2.8.1)':
dependencies:
'@jsonjoy.com/fs-core': 4.57.2(tslib@2.8.1)
'@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1)
'@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1)
thingies: 2.5.0(tslib@2.8.1)
tslib: 2.8.1
'@jsonjoy.com/fs-node-builtins@4.56.10(tslib@2.8.1)':
dependencies:
tslib: 2.8.1
'@jsonjoy.com/fs-node-builtins@4.57.2(tslib@2.8.1)':
dependencies:
tslib: 2.8.1
'@jsonjoy.com/fs-node-to-fsa@4.56.10(tslib@2.8.1)':
dependencies:
'@jsonjoy.com/fs-fsa': 4.56.10(tslib@2.8.1)
@ -15605,11 +15692,23 @@ snapshots:
'@jsonjoy.com/fs-node-utils': 4.56.10(tslib@2.8.1)
tslib: 2.8.1
'@jsonjoy.com/fs-node-to-fsa@4.57.2(tslib@2.8.1)':
dependencies:
'@jsonjoy.com/fs-fsa': 4.57.2(tslib@2.8.1)
'@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1)
'@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1)
tslib: 2.8.1
'@jsonjoy.com/fs-node-utils@4.56.10(tslib@2.8.1)':
dependencies:
'@jsonjoy.com/fs-node-builtins': 4.56.10(tslib@2.8.1)
tslib: 2.8.1
'@jsonjoy.com/fs-node-utils@4.57.2(tslib@2.8.1)':
dependencies:
'@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1)
tslib: 2.8.1
'@jsonjoy.com/fs-node@4.56.10(tslib@2.8.1)':
dependencies:
'@jsonjoy.com/fs-core': 4.56.10(tslib@2.8.1)
@ -15621,12 +15720,29 @@ snapshots:
thingies: 2.5.0(tslib@2.8.1)
tslib: 2.8.1
'@jsonjoy.com/fs-node@4.57.2(tslib@2.8.1)':
dependencies:
'@jsonjoy.com/fs-core': 4.57.2(tslib@2.8.1)
'@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1)
'@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1)
'@jsonjoy.com/fs-print': 4.57.2(tslib@2.8.1)
'@jsonjoy.com/fs-snapshot': 4.57.2(tslib@2.8.1)
glob-to-regex.js: 1.2.0(tslib@2.8.1)
thingies: 2.5.0(tslib@2.8.1)
tslib: 2.8.1
'@jsonjoy.com/fs-print@4.56.10(tslib@2.8.1)':
dependencies:
'@jsonjoy.com/fs-node-utils': 4.56.10(tslib@2.8.1)
tree-dump: 1.1.0(tslib@2.8.1)
tslib: 2.8.1
'@jsonjoy.com/fs-print@4.57.2(tslib@2.8.1)':
dependencies:
'@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1)
tree-dump: 1.1.0(tslib@2.8.1)
tslib: 2.8.1
'@jsonjoy.com/fs-snapshot@4.56.10(tslib@2.8.1)':
dependencies:
'@jsonjoy.com/buffers': 17.65.0(tslib@2.8.1)
@ -15635,6 +15751,14 @@ snapshots:
'@jsonjoy.com/util': 17.65.0(tslib@2.8.1)
tslib: 2.8.1
'@jsonjoy.com/fs-snapshot@4.57.2(tslib@2.8.1)':
dependencies:
'@jsonjoy.com/buffers': 17.65.0(tslib@2.8.1)
'@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1)
'@jsonjoy.com/json-pack': 17.65.0(tslib@2.8.1)
'@jsonjoy.com/util': 17.65.0(tslib@2.8.1)
tslib: 2.8.1
'@jsonjoy.com/json-pack@1.21.0(tslib@2.8.1)':
dependencies:
'@jsonjoy.com/base64': 1.1.2(tslib@2.8.1)
@ -23553,7 +23677,7 @@ snapshots:
matrix-events-sdk@0.0.1: {}
matrix-js-sdk@https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/60993dd10ada731e37db81873fede2a0afa93a6b:
matrix-js-sdk@https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/69985ee350a33ba75f1ad11f96468344f0c92a8d:
dependencies:
'@babel/runtime': 7.29.2
'@matrix-org/matrix-sdk-crypto-wasm': 18.2.0
@ -23633,6 +23757,23 @@ snapshots:
tree-dump: 1.1.0(tslib@2.8.1)
tslib: 2.8.1
memfs@4.57.2(tslib@2.8.1):
dependencies:
'@jsonjoy.com/fs-core': 4.57.2(tslib@2.8.1)
'@jsonjoy.com/fs-fsa': 4.57.2(tslib@2.8.1)
'@jsonjoy.com/fs-node': 4.57.2(tslib@2.8.1)
'@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1)
'@jsonjoy.com/fs-node-to-fsa': 4.57.2(tslib@2.8.1)
'@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1)
'@jsonjoy.com/fs-print': 4.57.2(tslib@2.8.1)
'@jsonjoy.com/fs-snapshot': 4.57.2(tslib@2.8.1)
'@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1)
'@jsonjoy.com/util': 1.9.0(tslib@2.8.1)
glob-to-regex.js: 1.2.0(tslib@2.8.1)
thingies: 2.5.0(tslib@2.8.1)
tree-dump: 1.1.0(tslib@2.8.1)
tslib: 2.8.1
memoize-one@5.2.1: {}
memoize-one@6.0.0: {}

View File

@ -5,8 +5,14 @@ sonar.organization=element-hq
#sonar.sourceEncoding=UTF-8
sonar.sources=.
sonar.tests=apps/web/test,apps/web/playwright,apps/desktop/playwright,packages
sonar.test.inclusions=apps/web/test/*,apps/web/playwright/*,apps/desktop/playwright/*,packages/*/src/**/*.test.*,packages/*/src/test/**/*
sonar.tests=apps/web/test,apps/web/playwright,apps/desktop,packages
sonar.test.inclusions=\
apps/web/test/*,\
apps/web/playwright/*,\
apps/desktop/playwright/*,\
apps/desktop/src/**/*.test.ts,\
packages/*/src/**/*.test.*,\
packages/*/src/test/**/*
sonar.exclusions=\
apps/web/__mocks__,\
docs,\
@ -40,16 +46,23 @@ sonar.coverage.exclusions=\
apps/web/playwright/**/*,\
apps/web/res/**/*,\
apps/web/scripts/**/*,\
apps/desktop/scripts/**/*,\
apps/desktop/playwright/**/*,\
apps/desktop/hak/**/*,\
scripts/**/*,\
apps/web/__mocks__/**/*,\
apps/web/I18nWebpackPlugin.ts,\
apps/web/recorder-worklet-loader.cjs,\
apps/web/src/components/views/dialogs/devtools/**/*,\
apps/web/src/utils/SessionLock.ts,\
apps/web/src/**/*.d.ts,\
apps/web/src/vector/mobile_guide/**/*,\
apps/desktop/electron-builder.ts,\
apps/desktop/scripts/**/*,\
apps/desktop/playwright/**/*,\
apps/desktop/hak/**/*,\
packages/shared-components/src/test/**/*,\
packages/shared-components/src/**/*.stories.tsx,\
packages/shared-components/scripts/**/*,\
packages/playwright-common/**/*,\
**/*.config.ts
scripts/**/*,\
docs/**/*,\
**/*.config.*,\
knip.ts
sonar.testExecutionReportPaths=apps/web/coverage/jest-sonar-report.xml