Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ jobs:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@387aeee55b189f024a4f6d94890c5b18d73339cc # 1.92.0
uses: dtolnay/rust-toolchain@387aeee55b189f024a4f6d94890c5b18d73339cc
with:
toolchain: 1.93.0
components: clippy, rustfmt

- name: Install system dependencies (Linux)
Expand Down Expand Up @@ -77,7 +78,9 @@ jobs:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@387aeee55b189f024a4f6d94890c5b18d73339cc # 1.92.0
uses: dtolnay/rust-toolchain@387aeee55b189f024a4f6d94890c5b18d73339cc
with:
toolchain: 1.93.0

- name: Install system dependencies
run: |
Expand Down Expand Up @@ -149,6 +152,17 @@ jobs:
working-directory: mesh
run: npm run check:icons

- name: Check homeserver recovery scripts
working-directory: mesh
run: |
shellcheck -e SC1007 infra/homeserver/*.sh infra/homeserver/tests/*.sh
sh infra/homeserver/tests/backup-tools.test.sh
python -m unittest discover -s infra/homeserver/tests -p 'test_admission_service.py' -v
cp infra/homeserver/.env.example infra/homeserver/.env
trap 'rm -f infra/homeserver/.env' EXIT
docker compose \
-f infra/homeserver/docker-compose.yml config --quiet

- name: Run tests
working-directory: mesh
run: npm run test
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/matrix-federation-acceptance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ jobs:
cache: npm
cache-dependency-path: mesh/package-lock.json

- name: Install Rust 1.92
uses: dtolnay/rust-toolchain@387aeee55b189f024a4f6d94890c5b18d73339cc # 1.92.0
- name: Install Rust 1.93
uses: dtolnay/rust-toolchain@387aeee55b189f024a4f6d94890c5b18d73339cc
with:
toolchain: 1.93.0

- name: Install Matrix test build dependencies
run: |
Expand Down
22 changes: 20 additions & 2 deletions .github/workflows/nightly-soak.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ name: Nightly Soak
# 1. All 13 live libp2p tests (~70s)
# 2. 60-second leak-detection soak (Phase A baseline + Phase B churn)
# 3. 45-second topology churn soak
# 4. A real PostgreSQL dump and isolated Synapse restore drill
#
# Total runtime: ~4 minutes per run.
#
Expand Down Expand Up @@ -35,6 +36,19 @@ env:
RUST_LOG: warn

jobs:
homeserver-restore-drill:
name: Homeserver restore drill
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4

- name: Restore a real Synapse backup into isolated services
working-directory: mesh
env:
MESH_RUN_RESTORE_INTEGRATION: "1"
run: sh infra/homeserver/tests/restore-drill.integration.sh

soak:
name: Long-duration soak
runs-on: ubuntu-latest
Expand All @@ -43,7 +57,9 @@ jobs:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@387aeee55b189f024a4f6d94890c5b18d73339cc # 1.92.0
uses: dtolnay/rust-toolchain@387aeee55b189f024a4f6d94890c5b18d73339cc
with:
toolchain: 1.93.0

- name: Install system dependencies
run: |
Expand Down Expand Up @@ -108,7 +124,9 @@ jobs:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@387aeee55b189f024a4f6d94890c5b18d73339cc # 1.92.0
uses: dtolnay/rust-toolchain@387aeee55b189f024a4f6d94890c5b18d73339cc
with:
toolchain: 1.93.0

- name: Install system dependencies
run: |
Expand Down
11 changes: 7 additions & 4 deletions .github/workflows/release-beta.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ jobs:
cache: npm
cache-dependency-path: mesh/package-lock.json

- name: Install Rust 1.92 with Clippy
uses: dtolnay/rust-toolchain@387aeee55b189f024a4f6d94890c5b18d73339cc # 1.92.0
- name: Install Rust 1.93 with Clippy
uses: dtolnay/rust-toolchain@387aeee55b189f024a4f6d94890c5b18d73339cc
with:
toolchain: 1.93.0
components: clippy

- name: Install Tauri system dependencies
Expand Down Expand Up @@ -137,8 +138,10 @@ jobs:
cache: npm
cache-dependency-path: mesh/package-lock.json

- name: Install Rust 1.92
uses: dtolnay/rust-toolchain@387aeee55b189f024a4f6d94890c5b18d73339cc # 1.92.0
- name: Install Rust 1.93
uses: dtolnay/rust-toolchain@387aeee55b189f024a4f6d94890c5b18d73339cc
with:
toolchain: 1.93.0

- name: Install frontend dependencies
working-directory: mesh
Expand Down
12 changes: 9 additions & 3 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- uses: dtolnay/rust-toolchain@387aeee55b189f024a4f6d94890c5b18d73339cc # 1.92.0
- uses: dtolnay/rust-toolchain@387aeee55b189f024a4f6d94890c5b18d73339cc
with:
toolchain: 1.93.0
- name: Install Tauri system dependencies
run: |
sudo apt-get update
Expand All @@ -41,7 +43,9 @@ jobs:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
fetch-depth: 0
- uses: dtolnay/rust-toolchain@387aeee55b189f024a4f6d94890c5b18d73339cc # 1.92.0
- uses: dtolnay/rust-toolchain@387aeee55b189f024a4f6d94890c5b18d73339cc
with:
toolchain: 1.93.0
- name: Verify dependency advisory boundaries
working-directory: mesh/src-tauri
shell: bash
Expand Down Expand Up @@ -93,7 +97,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- uses: dtolnay/rust-toolchain@387aeee55b189f024a4f6d94890c5b18d73339cc # 1.92.0
- uses: dtolnay/rust-toolchain@387aeee55b189f024a4f6d94890c5b18d73339cc
with:
toolchain: 1.93.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 22
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ node_modules/
dist/
dist-ssr/
target/
__pycache__/
*.py[cod]

# Logs & temp output
*.log
Expand Down
29 changes: 24 additions & 5 deletions mesh/e2e/authenticated-shell.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ test.afterEach(async ({ page }) => {
expect(runtimeErrors.get(page) ?? [], 'authenticated shell emitted runtime errors').toEqual([])
})

async function installAuthenticatedMatrixMock(page: Page): Promise<void> {
await page.addInitScript(() => {
async function installAuthenticatedMatrixMock(
page: Page,
currentDeepLinks: string[] | null = null,
): Promise<void> {
await page.addInitScript((deepLinks) => {
const calls: IpcCall[] = []
const callbacks = new Map<number, (...args: unknown[]) => void>()
let nextCallbackId = 1
Expand Down Expand Up @@ -287,6 +290,8 @@ async function installAuthenticatedMatrixMock(page: Page): Promise<void> {
case 'matrix_clear_composer_draft':
case 'plugin:event|unlisten':
return null
case 'plugin:deep-link|get_current':
return deepLinks
case 'matrix_wait_for_room_update':
// The real command long-polls the SDK room-update stream. Keeping
// this promise pending models that boundary without a CPU-heavy loop.
Expand Down Expand Up @@ -343,11 +348,14 @@ async function installAuthenticatedMatrixMock(page: Page): Promise<void> {
}).__TAURI_EVENT_PLUGIN_INTERNALS__ = {
unregisterListener: () => {},
}
})
}, currentDeepLinks)
}

async function openAuthenticatedShell(page: Page): Promise<void> {
await installAuthenticatedMatrixMock(page)
async function openAuthenticatedShell(
page: Page,
currentDeepLinks: string[] | null = null,
): Promise<void> {
await installAuthenticatedMatrixMock(page, currentDeepLinks)
await page.goto('/')
await expect(
page.getByRole('navigation', { name: 'Communities and direct messages' }),
Expand Down Expand Up @@ -387,6 +395,17 @@ test.describe('authenticated desktop shell', () => {
await expect(page.getByText('Anonymous', { exact: true })).toHaveCount(0)
})

test('routes a cold-start Mesh invitation into the prefilled join flow', async ({ page }) => {
const invite =
'mesh://join?v=3&kind=matrix&room=!invited:mesh.test&via=mesh.test&service=https%3A%2F%2Fmatrix.mesh.test'
await openAuthenticatedShell(page, [invite])

const dialog = page.getByRole('dialog', { name: 'Join a community' })
await expect(dialog).toBeVisible()
await expect(dialog.getByLabel('Invite code or link')).toHaveValue(invite)
await expect(dialog.getByRole('button', { name: 'Join Community' })).toBeEnabled()
})

test('@a11y has no automated WCAG A/AA violations in the shell and settings', async ({ page }) => {
await openAuthenticatedShell(page)
await expectNoWcagViolations(page, 'Authenticated desktop shell')
Expand Down
2 changes: 2 additions & 0 deletions mesh/e2e/dm-message-keyboard-actions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@ async function installDmKeyboardActionsMock(page: Page): Promise<void> {
case 'matrix_clear_composer_draft':
case 'plugin:event|unlisten':
return null
case 'plugin:deep-link|get_current':
return null
case 'matrix_user_preferences':
return null
case 'matrix_update_user_preferences':
Expand Down
2 changes: 2 additions & 0 deletions mesh/e2e/matrix-messaging.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ async function installAuthenticatedMatrixMessagingMock(page: Page): Promise<void
case 'matrix_clear_composer_draft':
case 'plugin:event|unlisten':
return null
case 'plugin:deep-link|get_current':
return null
case 'matrix_user_preferences':
return null
case 'matrix_update_user_preferences':
Expand Down
2 changes: 2 additions & 0 deletions mesh/e2e/message-keyboard-actions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ async function installKeyboardActionsMock(page: Page): Promise<void> {
case 'matrix_clear_composer_draft':
case 'plugin:event|unlisten':
return null
case 'plugin:deep-link|get_current':
return null
case 'matrix_wait_for_room_update':
return new Promise(() => {})
case 'plugin:event|listen':
Expand Down
8 changes: 8 additions & 0 deletions mesh/infra/homeserver/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ MESH_RTC_ENABLED=0
MESH_PUBLIC_ENABLED=0
ACME_EMAIL=admin@dhawal.org

# setup.sh replaces these examples with the current host account identity so
# bind-mounted Synapse files remain private and readable after migration.
MESH_RUNTIME_UID=501
MESH_RUNTIME_GID=20

# Keep Synapse private on the Mac. Caddy is the only public HTTP entry point.
SYNAPSE_CONTROL_BIND=127.0.0.1
SYNAPSE_CACHE_FACTOR=0.25
Expand All @@ -19,3 +24,6 @@ POSTGRES_PASSWORD=REPLACE_WITH_RANDOM_SECRET
REGISTRATION_SHARED_SECRET=REPLACE_WITH_RANDOM_SECRET
MACAROON_SECRET_KEY=REPLACE_WITH_RANDOM_SECRET
FORM_SECRET=REPLACE_WITH_RANDOM_SECRET
MESH_ADMISSION_SIGNING_KEY=REPLACE_WITH_RANDOM_SECRET
# start.sh replaces this after creating the dedicated, non-human service account.
MESH_ADMISSION_ADMIN_ACCESS_TOKEN=REPLACE_DURING_FIRST_START
9 changes: 6 additions & 3 deletions mesh/infra/homeserver/Caddyfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@
respond `{"m.server":"{$MESH_HOMESERVER_HOST}:443"}` 200
}

handle /invite* {
header Content-Type "text/plain; charset=utf-8"
respond "Open Mesh, choose Create account, and paste this full invitation link into Invitation code." 200
handle_path /_mesh/admission/* {
reverse_proxy admission:8090
}

handle /invite/* {
reverse_proxy admission:8090
}

handle {
Expand Down
Loading
Loading