diff --git a/apps/extension/package.json b/apps/extension/package.json index 698e3369..06f8e247 100644 --- a/apps/extension/package.json +++ b/apps/extension/package.json @@ -1,6 +1,6 @@ { "name": "@browser-skill/extension", - "version": "0.4.2", + "version": "0.4.3", "private": true, "type": "module", "scripts": { diff --git a/apps/extension/src/entrypoints/popup/connection-settings.test.tsx b/apps/extension/src/entrypoints/popup/connection-settings.test.tsx index 4432d6d0..3cca1de4 100644 --- a/apps/extension/src/entrypoints/popup/connection-settings.test.tsx +++ b/apps/extension/src/entrypoints/popup/connection-settings.test.tsx @@ -48,7 +48,7 @@ beforeEach(() => { vi.mocked(readLocalPairingInfo) .mockReset() .mockResolvedValue({ - policy: { skip: false, everPaired: false, legacyCompat: false }, + policy: { skip: false }, devices: [], }); vi.mocked(readSavedRemoteConnection) @@ -323,7 +323,7 @@ it("pair: opens local pairing immediately and recognizes local links from either }); function pairedInfo(skip = false) { vi.mocked(readLocalPairingInfo).mockResolvedValue({ - policy: { skip, everPaired: true, legacyCompat: false }, + policy: { skip }, devices: [{ daemonId: v.daemon_id, deviceId: v.device_id, endpoint: "ws://127.0.0.1:52800/" }], }); } diff --git a/apps/extension/src/entrypoints/popup/local-pairing.tsx b/apps/extension/src/entrypoints/popup/local-pairing.tsx index f4136510..09a13f77 100644 --- a/apps/extension/src/entrypoints/popup/local-pairing.tsx +++ b/apps/extension/src/entrypoints/popup/local-pairing.tsx @@ -6,7 +6,7 @@ import type { LocalAuthStatus } from "@/transport/local-auth"; import { Switch } from "./switch"; export interface LocalPairingInfo { - policy: { skip: boolean; everPaired: boolean; legacyCompat: boolean }; + policy: { skip: boolean }; devices: { daemonId: string; deviceId: string; endpoint: string }[]; } export async function localPairingRequest(request: Record) { diff --git a/apps/extension/src/lib/local-pairing-bridge.ts b/apps/extension/src/lib/local-pairing-bridge.ts index a2042357..ac1f212f 100644 --- a/apps/extension/src/lib/local-pairing-bridge.ts +++ b/apps/extension/src/lib/local-pairing-bridge.ts @@ -1,9 +1,5 @@ import { LocalAuthError } from "@/transport/local-auth"; -import { - initializeLocalMigration, - readLocalState, - setSkipLocalVerification, -} from "@/transport/local-credentials"; +import { readLocalState, setSkipLocalVerification } from "@/transport/local-credentials"; import { verifyLocalPairing } from "@/transport/pairing-verifier"; import { writeRemoteConnection } from "@/transport/remote-storage"; import type { WSTransport } from "@/transport/ws-transport"; @@ -19,14 +15,6 @@ export function trustedPopup(sender: chrome.runtime.MessageSender): boolean { ); } export function attachLocalPairing(controller: ConnectionController, transport: WSTransport): void { - const initialize = () => - initializeLocalMigration().catch(() => controller.setLocalAuth({ state: "server_unverified" })); - void initialize(); - chrome.runtime.onInstalled.addListener((details) => { - void initializeLocalMigration(details).catch(() => - controller.setLocalAuth({ state: "server_unverified" }), - ); - }); chrome.runtime.onMessage.addListener((message, sender, reply) => { if (message?.kind !== LOCAL_PAIRING_MESSAGE) return false; if (!trustedPopup(sender)) { diff --git a/apps/extension/src/transport/local-auth-daemon.test.ts b/apps/extension/src/transport/local-auth-daemon.test.ts index 85f6b8a8..ed95bb5c 100644 --- a/apps/extension/src/transport/local-auth-daemon.test.ts +++ b/apps/extension/src/transport/local-auth-daemon.test.ts @@ -12,7 +12,7 @@ import WebSocket from "ws"; import { EXTENSION_VERSION, PROTOCOL_VERSION } from "./handshake"; import { authenticateLocal, createLocalAuthenticator, LocalAuthError } from "./local-auth"; import * as localCredentials from "./local-credentials"; -import { initializeLocalMigration, readLocalState } from "./local-credentials"; +import { readLocalState } from "./local-credentials"; import { verifyLocalPairing } from "./pairing-verifier"; // Opt-in process tests: BSK_TEST_BINARY is a current build; BSK_TEST_OLD_BINARY @@ -64,7 +64,9 @@ async function start(binary: string) { let port = 0; await vi.waitFor( async () => { - port = JSON.parse(await readFile(join(home, "daemon.json"), "utf8")).ws_port; + const info = JSON.parse(await readFile(join(home, "daemon.json"), "utf8")); + expect(info.pid).toBe(daemon!.pid); + port = info.ws_port; expect(port).toBeGreaterThan(0); }, { timeout: 10_000 }, @@ -178,7 +180,7 @@ it.skipIf(!current)( // survive durable cleanup as well as an ordinary credential read. const clock = vi.spyOn(Date, "now").mockReturnValue(staged!.createdAt + 24 * 60 * 60_000); try { - await initializeLocalMigration(); + await localCredentials.setSkipLocalVerification(false); const credentials = (await readLocalState()).credentials; expect(credentials).toEqual(before); const ws = await opened(url); @@ -219,3 +221,64 @@ it.skipIf(!old)( }, 20_000, ); + +it.skipIf(!current)( + "optional pairing: a rejected link preserves unpaired use and successful pairing verifies reconnects", + async () => { + const url = await start(current!); + const status = vi.fn(); + const authenticate = createLocalAuthenticator({ + instanceId: async () => instance, + origin, + status, + }); + const unpaired = await opened(url); + await authenticate(browserSocket(unpaired), AbortSignal.timeout(5000)); + expect(status).toHaveBeenLastCalledWith({ state: "unverified_local", reason: "unpaired" }); + expect((await handshake(unpaired)).result).toBeDefined(); + const link = await cli(current!, "daemon", "pair"); + const badLink = link.replace(/[^.]+$/, "A".repeat(43)); + await expect( + verifyLocalPairing(badLink, instance, origin, (address) => browserSocket(socket(address))), + ).rejects.toBeInstanceOf(LocalAuthError); + expect(unpaired.readyState).toBe(WebSocket.OPEN); + expect((await readLocalState()).credentials).toHaveLength(0); + const report = JSON.parse(await cli(current!, "--json", "status")); + expect(report.browsers).toHaveLength(1); + + await verifyLocalPairing(link, instance, origin, (address) => browserSocket(socket(address))); + const paired = await opened(url); + await authenticate(browserSocket(paired), AbortSignal.timeout(5000)); + expect(status).toHaveBeenLastCalledWith(expect.objectContaining({ state: "verified" })); + expect((await handshake(paired)).result).toBeDefined(); + }, + 20_000, +); +it.skipIf(!current || !old)( + "paired profiles refuse a pre-pairing daemon after an independent CLI downgrade", + async () => { + await start(current!); + const link = await cli(current!, "daemon", "pair"); + await verifyLocalPairing(link, instance, origin, (address) => browserSocket(socket(address))); + const stopped = once(daemon!, "exit"); + daemon!.kill(); + await stopped; + const url = await start(old!); + const status = vi.fn(); + const authenticate = createLocalAuthenticator({ + instanceId: async () => instance, + origin, + status, + }); + for (let attempt = 0; attempt < 2; attempt++) { + const ws = await opened(url); + await expect( + authenticate(browserSocket(ws), AbortSignal.timeout(5000)), + ).rejects.toBeInstanceOf(LocalAuthError); + } + expect(status.mock.calls.some(([value]) => value.state === "unverified_local")).toBe(false); + expect((await readLocalState()).credentials[0].role).toBe("active"); + expect(JSON.parse(await cli(old!, "--json", "status")).browsers).toHaveLength(0); + }, + 20_000, +); diff --git a/apps/extension/src/transport/local-credentials.test.ts b/apps/extension/src/transport/local-credentials.test.ts index fa73812d..d08d4966 100644 --- a/apps/extension/src/transport/local-credentials.test.ts +++ b/apps/extension/src/transport/local-credentials.test.ts @@ -4,7 +4,6 @@ import v from "../../../../crates/bsk-protocol/tests/fixtures/local-auth-v1.json import { openCredentialDatabase } from "./credential-db"; import { discardStaged, - initializeLocalMigration, parseLocalPairing, promoteCandidate, readLocalState, @@ -46,7 +45,6 @@ it("L08c: key writes use strict durability, compare candidates, and promote atom const state = await readLocalState(); expect(state.credentials[0]).toMatchObject({ role: "active", gen: 1, key: v.candidate }); expect(state.credentials[0].pending).toBeUndefined(); - expect(state.policy).toMatchObject({ everPaired: true, legacyCompat: false }); const writes = transactions.mock.calls.filter((call) => call[1] === "readwrite"); expect(writes.length).toBeGreaterThan(2); for (const call of writes) expect(call[2]).toEqual({ durability: "strict" }); @@ -76,7 +74,6 @@ it("L08c/L14c: startup retains an expired replacement candidate until recovery c vi.spyOn(Date, "now").mockReturnValue(saved.createdAt + 24 * 60 * 60_000); expect((await readLocalState()).credentials).toEqual([active, saved]); - await initializeLocalMigration(); await setSkipLocalVerification(true); expect((await readLocalState()).credentials).toEqual([active, saved]); await expect( @@ -94,29 +91,17 @@ it("L08c/L14c: startup retains an expired replacement candidate until recovery c }); expect(recovered[0].pending).toBeUndefined(); }); -it("L18: only eligible updates get migration compatibility; pairing never resurrects it", async () => { - await initializeLocalMigration({ reason: "install" }, "0.4.2"); - expect((await readLocalState()).policy.legacyCompat).toBe(false); - await initializeLocalMigration({ reason: "update", previousVersion: "0.4.1" }, "0.4.2"); - expect((await readLocalState()).policy.legacyCompat).toBe(true); - let credential = parseLocalPairing(link); - await stageCredential(credential); - credential = await saveCandidate(credential, { txn: v.txn, gen: 1, key: v.candidate }); - await promoteCandidate(credential, { txn: v.txn, gen: 1 }); - await initializeLocalMigration({ reason: "update", previousVersion: "0.4.1" }, "0.4.2"); - expect((await readLocalState()).policy.legacyCompat).toBe(false); - await setSkipLocalVerification(true); - expect((await readLocalState()).credentials).toHaveLength(1); -}); -it("L18: the exit version clears compatibility and never clears explicit skipping", async () => { - await initializeLocalMigration({ reason: "update", previousVersion: "0.4.1" }, "0.4.2"); - await setSkipLocalVerification(true); - await initializeLocalMigration(undefined, "0.4.3"); - expect((await readLocalState()).policy).toEqual({ - skip: true, - everPaired: false, - legacyCompat: false, +it("ignores obsolete migration fields while retaining the explicit skip preference", async () => { + const db = await openCredentialDatabase(); + const tx = db.transaction("migration", "readwrite"); + tx.objectStore("migration").put({ skip: true, everPaired: true, legacyCompat: true }, "policy"); + await new Promise((resolve) => { + tx.oncomplete = () => resolve(); }); + db.close(); + expect((await readLocalState()).policy).toEqual({ skip: true }); + await setSkipLocalVerification(false); + expect((await readLocalState()).policy).toEqual({ skip: false }); }); it("upgrades the shared database while keeping the existing remote grant", async () => { await new Promise((resolve) => { diff --git a/apps/extension/src/transport/local-credentials.ts b/apps/extension/src/transport/local-credentials.ts index 8c154a46..e09810db 100644 --- a/apps/extension/src/transport/local-credentials.ts +++ b/apps/extension/src/transport/local-credentials.ts @@ -2,8 +2,6 @@ import { openCredentialDatabase } from "./credential-db"; import { decodeBytes } from "./local-auth-crypto"; import type { Rotation } from "./local-auth-protocol"; -export const PAIRING_VERSION = "0.4.2"; -export const MIGRATION_EXIT_VERSION = "0.4.3"; const STAGED_TTL_MS = 10 * 60_000; export interface LocalCredential { daemonId: string; @@ -17,17 +15,14 @@ export interface LocalCredential { } export interface LocalPolicy { skip: boolean; - everPaired: boolean; - legacyCompat: boolean; } export interface LocalState { credentials: LocalCredential[]; policy: LocalPolicy; } -const defaultPolicy = (): LocalPolicy => ({ skip: false, everPaired: false, legacyCompat: false }); /** No asynchronous work inside an IDB transaction. Resolve only on complete, - * including strict persistence of candidates, promotion, and migration state. */ + * including strict persistence of candidates, promotion, and explicit skip preferences. */ async function access(write: boolean, action: (state: LocalState) => T): Promise { const database = await openCredentialDatabase(); try { @@ -49,7 +44,7 @@ async function access(write: boolean, action: (state: LocalState) => T): Prom try { const state: LocalState = { credentials: records.result ?? [], - policy: policy.result ?? defaultPolicy(), + policy: { skip: policy.result?.skip ?? false }, }; // A saved candidate may already be committed by the daemon even if // its reply or our promotion was interrupted. Keep both keys until @@ -174,8 +169,6 @@ export function promoteCandidate( state.credentials = state.credentials.filter( (c) => c.daemonId !== record.daemonId || c === record, ); - state.policy.everPaired = true; - state.policy.legacyCompat = false; return record; }); } @@ -196,24 +189,3 @@ export function setSkipLocalVerification(skip: boolean): Promise { state.policy.skip = skip; }); } -function before(version: string, bound: string): boolean { - const a = version.split(".").map(Number); - const b = bound.split(".").map(Number); - if (a.length !== 3 || a.some((part) => !Number.isSafeInteger(part) || part < 0)) return false; - return a[0] < b[0] || (a[0] === b[0] && (a[1] < b[1] || (a[1] === b[1] && a[2] < b[2]))); -} -export function initializeLocalMigration( - details?: { reason: string; previousVersion?: string }, - version = __BSK_EXT_VERSION__, -): Promise { - return access(true, ({ policy }) => { - if (!before(version, MIGRATION_EXIT_VERSION) || policy.everPaired) policy.legacyCompat = false; - else if (details?.reason === "install") policy.legacyCompat = false; - else if ( - details?.reason === "update" && - details.previousVersion && - before(details.previousVersion, PAIRING_VERSION) - ) - policy.legacyCompat = true; - }); -} diff --git a/packages/i18n/src/locales/de-DE/extension.json b/packages/i18n/src/locales/de-DE/extension.json index 2bbc792d..67690b1e 100644 --- a/packages/i18n/src/locales/de-DE/extension.json +++ b/packages/i18n/src/locales/de-DE/extension.json @@ -203,8 +203,6 @@ "already_paired": "Dieser Browser ist bereits gekoppelt. Zum Ersetzen bsk daemon pair --replace {{browser}} ausführen und den neuen Link einfügen.", "replace_mismatch": "Dieser Browser ist {{instance}}; das Ziel ist {{browser}}. Keine Änderungen. Für ein neues Profil bsk daemon pair verwenden; ungenutzte Geräte mit bsk daemon revoke {{browser}} widerrufen.", "skip": "Lokale Verifizierung wird übersprungen. Lokale Programme könnten sich als bsk ausgeben und diesen Browser steuern.", - "migration_old": "Diese Verbindung ist nicht verifiziert; bsk ist für die Kopplung zu alt. Mit bsk update aktualisieren, dann koppeln.", - "migration_pair": "Diese Verbindung ist nicht verifiziert. bsk wird bald eine Kopplung voraussetzen. Bitte jetzt einmalig koppeln.", "server_unverified": "Verifizierung fehlgeschlagen. Ein anderes Programm könnte den Port belegen oder die Kopplung wurde zurückgesetzt. Mit bsk doctor prüfen.", "daemon_too_old": "bsk ist für eine sichere Verbindung zu alt. Führen Sie bsk update aus und versuchen Sie es erneut.", "busy": "Eine andere Verbindung verifiziert dieses Gerät. Bitte kurz warten." diff --git a/packages/i18n/src/locales/en-US/extension.json b/packages/i18n/src/locales/en-US/extension.json index 2a73b25b..f0720e4f 100644 --- a/packages/i18n/src/locales/en-US/extension.json +++ b/packages/i18n/src/locales/en-US/extension.json @@ -203,8 +203,6 @@ "already_paired": "This browser is already paired with this bsk. To replace it, run bsk daemon pair --replace {{browser}} and paste the new link.", "replace_mismatch": "This browser is {{instance}}; the replacement targets {{browser}}. No changes were made. Use bsk daemon pair for a new browser profile; revoke an unused device separately with bsk daemon revoke {{browser}}.", "skip": "Local verification is skipped. Any local program could impersonate bsk and control this browser.", - "migration_old": "This connection is unverified and the local bsk is too old to pair. Run bsk update, then pair this browser.", - "migration_pair": "This connection is unverified. bsk will soon require pairing; complete it once now.", "server_unverified": "The service failed verification. Another program may be using the port, or this bsk’s pairing may have been reset. Run bsk doctor to check.", "daemon_too_old": "This bsk is too old for a secure connection. Run bsk update, then retry.", "busy": "Another connection is verifying this device. Please retry shortly." diff --git a/packages/i18n/src/locales/es-ES/extension.json b/packages/i18n/src/locales/es-ES/extension.json index 6aae9704..1d9c7a11 100644 --- a/packages/i18n/src/locales/es-ES/extension.json +++ b/packages/i18n/src/locales/es-ES/extension.json @@ -203,8 +203,6 @@ "already_paired": "Este navegador ya está vinculado. Para reemplazarlo, ejecuta bsk daemon pair --replace {{browser}} y pega el nuevo enlace.", "replace_mismatch": "Este navegador es {{instance}}; el destino es {{browser}}. No se realizaron cambios. Usa bsk daemon pair para un perfil nuevo y bsk daemon revoke {{browser}} para revocar un dispositivo sin uso.", "skip": "Se ha omitido la verificación local. Cualquier programa local podría suplantar a bsk y controlar este navegador.", - "migration_old": "Esta conexión no está verificada y bsk es demasiado antiguo para vincularse. Ejecuta bsk update y luego vincula el navegador.", - "migration_pair": "Esta conexión no está verificada. Pronto bsk exigirá vinculación; complétala una vez ahora.", "server_unverified": "El servicio no superó la verificación. Otro programa podría estar usando el puerto o se restableció la vinculación. Compruébalo con bsk doctor.", "daemon_too_old": "bsk es demasiado antiguo para una conexión segura. Ejecuta bsk update y reintenta.", "busy": "Otra conexión está verificando este dispositivo. Reintenta en un momento." diff --git a/packages/i18n/src/locales/fr-FR/extension.json b/packages/i18n/src/locales/fr-FR/extension.json index 4078a2d7..08b121af 100644 --- a/packages/i18n/src/locales/fr-FR/extension.json +++ b/packages/i18n/src/locales/fr-FR/extension.json @@ -203,8 +203,6 @@ "already_paired": "Ce navigateur est déjà associé. Pour remplacer l’association, exécutez bsk daemon pair --replace {{browser}} et collez le nouveau lien.", "replace_mismatch": "Ce navigateur est {{instance}} ; la cible est {{browser}}. Aucune modification. Pour un nouveau profil, utilisez bsk daemon pair ; révoquez un appareil inutilisé avec bsk daemon revoke {{browser}}.", "skip": "La vérification locale est ignorée. Un programme local pourrait se faire passer pour bsk et contrôler ce navigateur.", - "migration_old": "Connexion non vérifiée : bsk est trop ancien pour l’association. Exécutez bsk update, puis associez le navigateur.", - "migration_pair": "Cette connexion n’est pas vérifiée. bsk exigera bientôt une association ; effectuez-la une fois maintenant.", "server_unverified": "Échec de la vérification. Un autre programme utilise peut-être le port ou l’association a été réinitialisée. Vérifiez avec bsk doctor.", "daemon_too_old": "bsk est trop ancien pour une connexion sécurisée. Exécutez bsk update et réessayez.", "busy": "Une autre connexion vérifie cet appareil. Réessayez dans un instant." diff --git a/packages/i18n/src/locales/it-IT/extension.json b/packages/i18n/src/locales/it-IT/extension.json index 7552b72e..a12f51d6 100644 --- a/packages/i18n/src/locales/it-IT/extension.json +++ b/packages/i18n/src/locales/it-IT/extension.json @@ -203,8 +203,6 @@ "already_paired": "Questo browser è già associato. Per sostituirlo, esegui bsk daemon pair --replace {{browser}} e incolla il nuovo link.", "replace_mismatch": "Questo browser è {{instance}}; la destinazione è {{browser}}. Nessuna modifica. Usa bsk daemon pair per un nuovo profilo e bsk daemon revoke {{browser}} per revocare un dispositivo inutilizzato.", "skip": "La verifica locale è saltata. Un programma locale potrebbe impersonare bsk e controllare questo browser.", - "migration_old": "Questa connessione non è verificata e bsk è troppo vecchio per l’associazione. Esegui bsk update, poi associa il browser.", - "migration_pair": "Questa connessione non è verificata. bsk richiederà presto l’associazione; completala una volta ora.", "server_unverified": "Verifica del servizio fallita. Un altro programma potrebbe usare la porta o l’associazione è stata reimpostata. Controlla con bsk doctor.", "daemon_too_old": "bsk è troppo vecchio per una connessione sicura. Esegui bsk update e riprova.", "busy": "Un’altra connessione sta verificando questo dispositivo. Riprova tra poco." diff --git a/packages/i18n/src/locales/ja-JP/extension.json b/packages/i18n/src/locales/ja-JP/extension.json index 6628a12f..106a2daa 100644 --- a/packages/i18n/src/locales/ja-JP/extension.json +++ b/packages/i18n/src/locales/ja-JP/extension.json @@ -203,8 +203,6 @@ "already_paired": "このブラウザーはすでにペアリング済みです。置き換えるには bsk daemon pair --replace {{browser}} を実行し、新しいリンクを貼り付けてください。", "replace_mismatch": "現在のブラウザーは {{instance}}、置き換え対象は {{browser}} です。変更はありません。新しいプロファイルには bsk daemon pair を使い、不要なデバイスは bsk daemon revoke {{browser}} で解除してください。", "skip": "ローカル検証をスキップ中です。ローカルプログラムが bsk を装ってブラウザーを操作する可能性があります。", - "migration_old": "この接続は未検証で、bsk が古くペアリングに対応していません。bsk update で更新してからペアリングしてください。", - "migration_pair": "この接続は未検証です。bsk はまもなくペアリングを必須にします。一度だけ設定してください。", "server_unverified": "サービスの検証に失敗しました。別のプログラムがポートを使用しているか、ペアリングがリセットされた可能性があります。bsk doctor で確認してください。", "daemon_too_old": "bsk が古いため安全に接続できません。bsk update の実行後に再試行してください。", "busy": "別の接続がこのデバイスを検証中です。しばらくして再試行してください。" diff --git a/packages/i18n/src/locales/ko-KR/extension.json b/packages/i18n/src/locales/ko-KR/extension.json index 5fb566d4..b0025166 100644 --- a/packages/i18n/src/locales/ko-KR/extension.json +++ b/packages/i18n/src/locales/ko-KR/extension.json @@ -203,8 +203,6 @@ "already_paired": "이 브라우저는 이미 페어링되어 있습니다. 교체하려면 bsk daemon pair --replace {{browser}}를 실행하고 새 링크를 붙여 넣으세요.", "replace_mismatch": "현재 브라우저는 {{instance}}이고 교체 대상은 {{browser}}입니다. 변경 사항이 없습니다. 새 프로필에는 bsk daemon pair를 사용하고, 사용하지 않는 기기는 bsk daemon revoke {{browser}}로 취소하세요.", "skip": "로컬 검증을 건너뛰고 있습니다. 로컬 프로그램이 bsk를 사칭하여 브라우저를 제어할 수 있습니다.", - "migration_old": "연결이 미검증 상태이며 bsk가 너무 오래되어 페어링을 지원하지 않습니다. bsk update로 업데이트한 뒤 페어링하세요.", - "migration_pair": "이 연결은 미검증 상태입니다. 곧 bsk에 페어링이 필수가 되니 지금 한 번 설정하세요.", "server_unverified": "서비스 검증에 실패했습니다. 다른 프로그램이 포트를 사용하거나 페어링이 초기화되었을 수 있습니다. bsk doctor로 확인하세요.", "daemon_too_old": "bsk 버전이 오래되어 안전하게 연결할 수 없습니다. bsk update 실행 후 다시 시도하세요.", "busy": "다른 연결이 이 기기를 검증 중입니다. 잠시 후 다시 시도하세요." diff --git a/packages/i18n/src/locales/pt-BR/extension.json b/packages/i18n/src/locales/pt-BR/extension.json index b6eda212..d4b37356 100644 --- a/packages/i18n/src/locales/pt-BR/extension.json +++ b/packages/i18n/src/locales/pt-BR/extension.json @@ -203,8 +203,6 @@ "already_paired": "Este navegador já está pareado. Para substituí-lo, execute bsk daemon pair --replace {{browser}} e cole o novo link.", "replace_mismatch": "Este navegador é {{instance}}; o destino é {{browser}}. Nada foi alterado. Use bsk daemon pair para um novo perfil e bsk daemon revoke {{browser}} para revogar um dispositivo sem uso.", "skip": "A verificação local foi ignorada. Qualquer programa local pode se passar pelo bsk e controlar este navegador.", - "migration_old": "Esta conexão não foi verificada e o bsk é antigo demais para parear. Execute bsk update e depois faça o pareamento.", - "migration_pair": "Esta conexão não foi verificada. Em breve o bsk exigirá pareamento; conclua-o uma vez agora.", "server_unverified": "Falha na verificação do serviço. Outro programa pode estar usando a porta ou o pareamento foi redefinido. Verifique com bsk doctor.", "daemon_too_old": "O bsk é antigo demais para uma conexão segura. Execute bsk update e tente novamente.", "busy": "Outra conexão está verificando este dispositivo. Tente novamente em instantes." diff --git a/packages/i18n/src/locales/zh-CN/extension.json b/packages/i18n/src/locales/zh-CN/extension.json index 65f8c96d..b3085b68 100644 --- a/packages/i18n/src/locales/zh-CN/extension.json +++ b/packages/i18n/src/locales/zh-CN/extension.json @@ -203,8 +203,6 @@ "already_paired": "这个浏览器已与这台 bsk 配对,无需重新配对。如需替换,运行 bsk daemon pair --replace {{browser}},再粘贴新链接。", "replace_mismatch": "当前浏览器是 {{instance}},替换目标是 {{browser}},未做任何改动。新浏览器配置请使用 bsk daemon pair;不用的设备可用 bsk daemon revoke {{browser}} 单独撤销。", "skip": "已跳过本机验证:本机任何程序都可能冒充 bsk 控制此浏览器。", - "migration_old": "当前连接未验证,本机 bsk 版本还不支持配对。请运行 bsk update 升级,再完成配对。", - "migration_pair": "当前连接未验证。bsk 即将要求配对,建议现在完成,只需一次。", "server_unverified": "服务未通过验证。可能是其它程序占用了端口,也可能是这台 bsk 的配对已被重置。请运行 bsk doctor 检查。", "daemon_too_old": "本机 bsk 版本过旧,不支持安全连接。请运行 bsk update 后重试。", "busy": "另一个连接正在验证此设备,请稍后重试。" diff --git a/packages/i18n/src/locales/zh-TW/extension.json b/packages/i18n/src/locales/zh-TW/extension.json index 5f36835b..571328d6 100644 --- a/packages/i18n/src/locales/zh-TW/extension.json +++ b/packages/i18n/src/locales/zh-TW/extension.json @@ -203,8 +203,6 @@ "already_paired": "此瀏覽器已與這台 bsk 配對。如需取代,執行 bsk daemon pair --replace {{browser}},再貼上新連結。", "replace_mismatch": "目前瀏覽器是 {{instance}},取代目標是 {{browser}},未做任何變更。新設定檔請用 bsk daemon pair;不用的裝置可用 bsk daemon revoke {{browser}} 撤銷。", "skip": "已略過本機驗證:本機任何程式都可能冒充 bsk 控制此瀏覽器。", - "migration_old": "此連線尚未驗證,本機 bsk 版本不支援配對。請執行 bsk update 升級後配對。", - "migration_pair": "此連線尚未驗證。bsk 即將要求配對,建議現在完成一次配對。", "server_unverified": "服務未通過驗證。可能是其他程式占用連接埠,或 bsk 配對已重設。請執行 bsk doctor 檢查。", "daemon_too_old": "本機 bsk 版本過舊,不支援安全連線。請執行 bsk update 後重試。", "busy": "另一條連線正在驗證此裝置,請稍後重試。"