Skip to content
Open
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
37 changes: 9 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ takosはActivityPubでweb自主するためのソフトウェアです。
takosは、ActivityPubに追加で、以下の機能を提供します。

このソフトウェアは、1人のユーザが、他のユーザとコミュニケーションを取るためのものです。
基本的に同一ドメインのユーザーは同一人物です。(サブアカウントなど)
基本的に同一ドメインのユーザーは同一人物です。(サブアカウントなど) ActivityPub
の投稿に加え、暗号化を行わないシンプルなダイレクトメッセージ機能を備え
ています。

## 🔧 技術スタック

Expand Down Expand Up @@ -165,29 +167,17 @@ ActivityPub 形式の一覧が必要な場合は、`/ap/users/:username/follower

- `GET /api/accounts` – アカウント一覧取得
- `POST /api/accounts` – アカウント作成
- `GET /api/accounts/:id` – アカウント取得(鍵情報を含む)
- `GET /api/accounts/:id` – アカウント取得
- `PUT /api/accounts/:id` – アカウント更新
- `DELETE /api/accounts/:id` – アカウント削除

## チャット API

エンドツーエンド暗号化に対応したチャット機能の API です。 `/api/users/*`
プレフィックスには公開ユーザー情報取得用のエンドポイントも含まれますが、
アカウント管理機能は `/api/accounts/*` で提供されます。 MLS
に関する暗号化・復号・状態管理はすべてクライアント側で行い、サーバーは
暗号化済みデータの保存と配送だけを担います。

- `GET /api/users/:user/keyPackages` – KeyPackage 一覧取得(`?summary=true`
で残数のみ取得)
- `POST /api/users/:user/keyPackages` – KeyPackage 登録(GroupInfo
や有効期限を付与可能)
- `POST /api/keyPackages/bulk` – 複数ユーザーの KeyPackage を一括登録
- `GET /api/users/:user/keyPackages/:keyId` – KeyPackage 取得
- `DELETE /api/users/:user/keyPackages/:keyId` – KeyPackage 削除
- `GET /api/users/:user/encryptedKeyPair` – 暗号化鍵ペア取得
- `POST /api/users/:user/encryptedKeyPair` – 暗号化鍵ペア保存
- `DELETE /api/users/:user/encryptedKeyPair` – 暗号化鍵ペア削除
- `POST /api/users/:user/resetKeys` – 鍵情報リセット
ActivityPub を利用したシンプルなダイレクトメッセージ機能の API
です。暗号化は行わ れません。 `/api/users/*`
プレフィックスには公開ユーザー情報取得用のエンドポイン
トも含まれますが、アカウント管理機能は `/api/accounts/*` で提供されます。

- `GET /api/users/:user/messages` – メッセージ一覧取得
- `POST /api/users/:user/messages` – メッセージ送信
- `GET /api/users/:user/keep` – TAKO Keep に保存したメモ一覧を取得
Expand All @@ -214,15 +204,6 @@ ActivityPub 形式の一覧が必要な場合は、`/ap/users/:username/follower

.env の例は `app/api/.env.example` を参照してください。

## クライアントでのデータ保存

チャット機能で利用する MLS 関連データはブラウザの IndexedDB に保存されます。
暗号化やグループ状態の更新もクライアント内で完結し、サーバーは暗号化済みデータを
そのまま中継します。データベースはアカウントごとに分割され、別アカウントの情報が混在しないようになっています。

鍵共有の仕組みについては [docs/key-sharing.md](docs/key-sharing.md)
を参照してください。

## OpenAPI仕様

APIの詳細仕様は [docs/openapi.yaml](docs/openapi.yaml) に記載されています。
Expand Down
36 changes: 3 additions & 33 deletions app/client/src/components/Application.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { createEffect, createSignal, onCleanup, onMount, Show } from "solid-js";
import { createEffect, createSignal, onMount, Show } from "solid-js";
import { useAtom } from "solid-jotai";
import { selectedAppState } from "../states/app.ts";
import { selectedRoomState } from "../states/chat.ts";
import { activeAccount, accounts as accountsAtom } from "../states/account.ts";
import { activeAccount } from "../states/account.ts";
import { Home } from "./Home.tsx";
import Profile from "./Profile.tsx";
import { Microblog } from "./Microblog.tsx";
Expand All @@ -12,15 +12,12 @@ import UnifiedToolsContent from "./home/UnifiedToolsContent.tsx";
import Header from "./header/header.tsx";
import { connectWebSocket, registerUser } from "../utils/ws.ts";
import { getDomain } from "../utils/config.ts";
import { topUpKeyPackagesBulk } from "./e2ee/api.ts";

export function Application() {
const [selectedApp] = useAtom(selectedAppState);
const [selectedRoom] = useAtom(selectedRoomState);
const [account] = useAtom(activeAccount);
const [allAccounts] = useAtom(accountsAtom);
const [isMobile, setIsMobile] = createSignal(false);
let topUpTimer: number | undefined;

// モバイルかどうかを判定
onMount(() => {
Expand All @@ -42,34 +39,7 @@ export function Application() {
registerUser(`${user.userName}@${getDomain()}`);
}

// Top up KeyPackages for all configured accounts (bulk) instead of only the active one.
const accs = allAccounts();
if (accs && accs.length > 0) {
const payload = accs.map((a) => ({ userName: a.userName, accountId: a.id }));
// Run immediately and stop periodic top-up if uploads were performed.
void (async () => {
try {
const uploaded = await topUpKeyPackagesBulk(payload);
if (uploaded && topUpTimer) {
clearInterval(topUpTimer);
topUpTimer = undefined;
}
} catch (e) {
console.warn("topUpKeyPackagesBulk failed:", e);
}
})();
if (topUpTimer) clearInterval(topUpTimer);
topUpTimer = setInterval(() => {
void topUpKeyPackagesBulk(payload);
}, 300_000);
} else if (topUpTimer) {
clearInterval(topUpTimer);
topUpTimer = undefined;
}
});

onCleanup(() => {
if (topUpTimer) clearInterval(topUpTimer);
// KeyPackages 関連の定期処理は削除
});

// チャットページかつスマホ版かつチャンネルが選択されている場合にヘッダーが非表示の場合のクラス名を生成
Expand Down
Loading