diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 92d3ce8..60b4aae 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ on: jobs: build-and-test: - runs-on: ubuntu-latest + runs-on: parity-ubuntu steps: - uses: actions/checkout@v4 @@ -15,7 +15,8 @@ jobs: with: node-version: 22 - - uses: pnpm/action-setup@v4 + - name: Enable Corepack + run: corepack enable - name: Install dependencies run: pnpm install --frozen-lockfile @@ -36,7 +37,7 @@ jobs: run: pnpm pack && ls -lh *.tgz integration-tests: - runs-on: ubuntu-latest + runs-on: parity-ubuntu steps: - uses: actions/checkout@v4 @@ -44,7 +45,8 @@ jobs: with: node-version: 22 - - uses: pnpm/action-setup@v4 + - name: Enable Corepack + run: corepack enable - name: Install dependencies run: pnpm install --frozen-lockfile diff --git a/.github/workflows/npm-release.yml b/.github/workflows/npm-release.yml index 5a393ac..4b80c19 100644 --- a/.github/workflows/npm-release.yml +++ b/.github/workflows/npm-release.yml @@ -6,7 +6,7 @@ on: jobs: publish: - runs-on: ubuntu-latest + runs-on: parity-ubuntu steps: - uses: actions/checkout@v4 @@ -14,7 +14,8 @@ jobs: with: node-version: 22 - - uses: pnpm/action-setup@v4 + - name: Enable Corepack + run: corepack enable - name: Set version from release tag run: | diff --git a/src/browser/host-runtime.ts b/src/browser/host-runtime.ts index 6b22d6e..9273117 100644 --- a/src/browser/host-runtime.ts +++ b/src/browser/host-runtime.ts @@ -462,14 +462,6 @@ function setupContainer( // ── Sign payload (extrinsic) ───────────────────────────────── container.handleSignPayload((params, { ok, err }) => { - if (enforcePermissions && !grantedPermissions.has("ChainSubmit")) { - console.error( - "[test-host] Signing rejected: product did not request ChainSubmit permission. " + - "Call hostApi.permission([{ tag: 'ChainSubmit' }]) first.", - ); - return err(new SigningErr.PermissionDenied()); - } - // params.account is [dotnsId, derivationIndex] const [dotnsId, idx] = params.account; const pair = getPairForProductAccount(config, pairs, dotnsId, idx); @@ -514,13 +506,6 @@ function setupContainer( // ── Sign raw ───────────────────────────────────────────────── container.handleSignRaw((params, { ok, err }) => { - if (enforcePermissions && !grantedPermissions.has("ChainSubmit")) { - console.error( - "[test-host] Signing rejected: product did not request ChainSubmit permission.", - ); - return err(new SigningErr.PermissionDenied()); - } - // params.account is [dotnsId, derivationIndex] const [dotnsId, idx] = params.account; const pair = getPairForProductAccount(config, pairs, dotnsId, idx); @@ -551,10 +536,6 @@ function setupContainer( // ── Sign with legacy account (address-based) ─────────────── container.handleSignPayloadWithLegacyAccount((params, { ok, err }) => { - if (enforcePermissions && !grantedPermissions.has("ChainSubmit")) { - return err(new SigningErr.PermissionDenied()); - } - const pair = getPairByAddress(params.signer); if (!pair) { return err( @@ -589,10 +570,6 @@ function setupContainer( }); container.handleSignRawWithLegacyAccount((params, { ok, err }) => { - if (enforcePermissions && !grantedPermissions.has("ChainSubmit")) { - return err(new SigningErr.PermissionDenied()); - } - const pair = getPairByAddress(params.signer); if (!pair) { return err( diff --git a/test/integration.spec.ts b/test/integration.spec.ts index cf640d4..6923ccd 100644 --- a/test/integration.spec.ts +++ b/test/integration.spec.ts @@ -231,9 +231,9 @@ test.describe('Root (non-product) accounts', () => { // ── Permission enforcement ────────────────────────────────────────── -test.describe('Permission enforcement', () => { +test.describe('Permission handling', () => { - test('signing fails without ChainSubmit permission', async ({ page }) => { + test('signing works without explicit permission request', async ({ page }) => { const host = await createTestHostServer({ productUrl: productServer.url, accounts: ['alice'], @@ -242,15 +242,17 @@ test.describe('Permission enforcement', () => { try { const product = await loadHostAndProduct(page, host.url, productServer.url); - // Attempt signing without requesting permission first + // In v0.7, signing doesn't require ChainSubmit — that permission + // is enforced by the container at transaction_broadcast level. const result = await product.evaluate(() => window.__TEST_PRODUCT__.trySignRaw()); - expect(result.ok).toBe(false); + expect(result.ok).toBe(true); + expect(result.signature).toBeTruthy(); } finally { await host.close(); } }); - test('signing succeeds after requesting ChainSubmit permission', async ({ page }) => { + test('ChainSubmit permission request is logged', async ({ page }) => { const host = await createTestHostServer({ productUrl: productServer.url, accounts: ['alice'], @@ -259,45 +261,18 @@ test.describe('Permission enforcement', () => { try { const product = await loadHostAndProduct(page, host.url, productServer.url); - // Request permission first const permResult = await product.evaluate(() => window.__TEST_PRODUCT__.requestChainSubmit()); expect(permResult.ok).toBe(true); + expect(permResult.approved).toBe(true); - // Now signing should work - const signResult = await product.evaluate(() => window.__TEST_PRODUCT__.trySignRaw()); - expect(signResult.ok).toBe(true); - expect(signResult.signature).toBeTruthy(); - - // Verify permission was logged on host side const log = await page.evaluate(() => window.__TEST_HOST__.getPermissionLog()); - expect(log.length).toBeGreaterThanOrEqual(1); expect(log.some((e: any) => e.tag === 'ChainSubmit' && e.approved)).toBe(true); } finally { await host.close(); } }); - test('signing succeeds when enforcement is disabled', async ({ page }) => { - const host = await createTestHostServer({ - productUrl: productServer.url, - accounts: ['alice'], - }); - - try { - const product = await loadHostAndProduct(page, host.url, productServer.url); - - // Disable enforcement - await page.evaluate(() => window.__TEST_HOST__.setEnforcePermissions(false)); - - // Signing works without permission request - const result = await product.evaluate(() => window.__TEST_PRODUCT__.trySignRaw()); - expect(result.ok).toBe(true); - } finally { - await host.close(); - } - }); - - test('signing succeeds when permission is pre-granted via grantPermission', async ({ page }) => { + test('permission is rejected when behavior is reject-all', async ({ page }) => { const host = await createTestHostServer({ productUrl: productServer.url, accounts: ['alice'], @@ -306,38 +281,12 @@ test.describe('Permission enforcement', () => { try { const product = await loadHostAndProduct(page, host.url, productServer.url); - // Pre-grant without product requesting - await page.evaluate(() => window.__TEST_HOST__.grantPermission('ChainSubmit')); - - const result = await product.evaluate(() => window.__TEST_PRODUCT__.trySignRaw()); - expect(result.ok).toBe(true); - } finally { - await host.close(); - } - }); - - test('signing fails when permission is rejected', async ({ page }) => { - const host = await createTestHostServer({ - productUrl: productServer.url, - accounts: ['alice'], - }); - - try { - const product = await loadHostAndProduct(page, host.url, productServer.url); - - // Set reject-all behavior await page.evaluate(() => window.__TEST_HOST__.setPermissionBehavior('reject-all')); - // Product requests permission — protocol round-trip succeeds but permission is denied const permResult = await product.evaluate(() => window.__TEST_PRODUCT__.requestChainSubmit()); expect(permResult.ok).toBe(true); expect(permResult.approved).toBe(false); - // Signing should still fail since permission was rejected - const signResult = await product.evaluate(() => window.__TEST_PRODUCT__.trySignRaw()); - expect(signResult.ok).toBe(false); - - // Permission log shows rejection const log = await page.evaluate(() => window.__TEST_HOST__.getPermissionLog()); expect(log.some((e: any) => e.tag === 'ChainSubmit' && !e.approved)).toBe(true); } finally {