Skip to content

refactor: ストレージ層を expo-sqlite (SQLCipher) に移行しスニペット機能の基盤を整備 #78

Description

@dashi296

背景

現在、接続プロファイルは AsyncStorage に平文で保存されている。将来 Sentry 等のクラッシュレポーターを導入した場合、ナビゲーション URL に含まれる ip/token が外部サービスに送信されるリスクがある。

また、ターミナル画面で使えるコマンドスニペットの保存機能を将来追加する予定があるため、この機会に SQLite ベースの永続化基盤を整備する。

やること

1. パッケージ追加

```bash
npx expo install expo-sqlite expo-secure-store
```

2. DB クライアントの実装 (src/db/client.ts)

  • expo-secure-store でランダムな暗号化キーを生成・保管
  • expo-sqliteuseSQLCipher: true で DB を開く
  • アプリ起動時に一度だけ初期化・マイグレーション実行

3. スキーマ

```sql
CREATE TABLE profiles (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
ip TEXT NOT NULL,
token TEXT NOT NULL,
last_connected_at TEXT
);

CREATE TABLE snippets (
id TEXT PRIMARY KEY,
title TEXT NOT NULL,
command TEXT NOT NULL,
created_at TEXT NOT NULL
);
```

  • snippets は全接続先共通(profile_id なし)

4. AsyncStorage からのデータ移行

  • 初回起動時に connectionProfiles キーのデータを SQLite に移行
  • 移行完了後に AsyncStorage のエントリを削除
  • 移行済みフラグを SecureStore に保存(二重移行防止)

5. ナビゲーション修正

  • ip/token を URL パラメータから除去
  • profileId のみ URL で渡し、各画面は DB から ip/token を取得

```
変更前: /session-picker?ip=100.x.x.x&token=uuid
変更後: /session-picker?profileId=abc123
```

6. ファイル構成

```
src/
└── db/
├── client.ts # DB 初期化・暗号化キー管理
├── profiles.ts # profiles テーブルの CRUD
└── snippets.ts # snippets テーブルの CRUD(スニペット実装時に追加)
```

注意点

  • expo-secure-store は iOS で 1 エントリあたり 2KB の上限があるが、暗号化キー(UUID)のみ保存するため問題なし
  • SQLCipher のキーは SecureStore に保存するため、アンインストール時にキーも消える(データ復元不可)。これは意図した動作
  • スニペット機能の UI 実装はこの Issue のスコープ外

関連

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions