尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證在您的網頁瀏覽器中進行安全的點對點聊天。
AI 翻譯
A secure peer-to-peer chat in your web browser
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
We believe that everyone has the right to communicate privately.
That's why we provide otr.to, a tool that allows you to chat P2P.
In the project directory, you can run:
The page will reload if you make edits.\
You will also see any lint errors in the console.
Launches the test runner in the interactive watch mode.\
See the section about running tests for more information.
Runs the Jest test suite once.\
Use npm run test:watch while editing, or npm run test:coverage for a coverage report.檢視完整 README ↗Peer-to-peer chat in your web browser. Open otr.to, send the link it gives you to one person or several, and you talk over direct connections between your browsers, end-to-end encrypted. There is no account, nothing you have to install, and no history: the conversation is gone when the tab is closed.
https://otr.to/#<peer-id>.<secret>.#. If nobody answers within 15 seconds, the page says the chat
is no longer open and offers to start a new one. A link without a valid
secret, for example one that was cut off when it was shared, is refused
straight away.# to a server, so neither the signalling server
nor a TURN relay learns the key, and neither could read or forge messages
even if it got between two peers. A connection only counts as part of the
chat once its first packet decrypts.public/sw.js) keeps a copy of the page,
the script and the stylesheet, so the app opens without a connection and
browsers offer to install it. It always asks the network first, so an
online visit gets the current version, and it files every chat link under
the plain address, so the key after the # never ends up on disk.The chat itself never touches a server, but a few are needed to set it up:
0.peerjs.com) brokers the
connections. It sees the peer IDs and IP addresses and who connects to whom,
but never the secret, so it cannot read the messages.stun.cloudflare.com, stun.l.google.com) tell each browser its address
on the internet, so that devices on different networks can find a direct
route to each other. They see the IP address of whoever asks, not the chat.turn.otr.to (turn/). It sees the
IP addresses and how much is sent, but only ever relays encrypted packets,
and keeps no log of who used it.Whoever has the link can join the chat and read it. That includes the service it was shared through, such as Telegram, WhatsApp or an email provider, so share it somewhere you trust.
src/bulma.scss listsYou need Node.js 22 or newer.
git clone https://github.com/jermainee/otr.to.git
cd otr.to
npm install
npm run dev
npm run dev writes the script and the stylesheet to public/dist and
rebuilds them on every change. Serve the public folder with any static file
server to open the app, for example the one the end-to-end tests use:
node e2e/static-server.js
It listens on http://127.0.0.1:4173 (set PORT to change that). To try a
conversation, open the app in one tab and the chat link it shows in another.
| Command | What it does |
|---|---|
npm run dev | Builds in development mode and rebuilds on every change. |
npm run icons | Draws the app icons in public from the logo. |
npm run build | Builds the minified script and stylesheet in public/dist. |
npm test | Runs the Jest suite once. |
npm run test:watch | Runs Jest in watch mode. |
npm run test:coverage | Runs Jest with a coverage report in coverage/. |
npm run test:e2e | Builds the site and runs the Playwright suite against it. |
Unit tests live in src/__tests__ and run in jsdom. PeerJS is replaced by
a mock (src/__mocks__/peerjs.ts), so they never open a network connection.
End-to-end tests live in e2e and drive browser tabs through real chats
over WebRTC: the share link and its buttons, messages in both directions, a
stale link, file transfers down to the downloaded bytes, group chats of three
and four, and checks that nothing readable crosses a data channel and that the
signalling server never sees the secret. Another test holds the script back to
check that the page is styled without it, and the last ones check that Chrome
would install the app, that it opens offline, and that the secret stays out of
its cache. Only the PeerJS signalling server is stubbed
(e2e/support/signalling.ts), so the suite needs no internet connection.
Install the browser once before the first run:
npx playwright install chromium
GitHub Actions runs on every push to main and
on every pull request, in two jobs:
Deploy TURN relay runs the same checks
after every merge to main that changes turn/, then installs the relay on
the VPS.
Dependabot checks the npm packages and the GitHub Actions weekly.
index.tsx Entry point: mounts the app and the router
src/Chat.tsx Connection states, notices, file transfer and share link
src/Messages.tsx The conversation: messages, names, notices and files
src/InstallButton.tsx The navbar's install button, while the browser offers to install
src/Icons.tsx Inline SVG icons that take the text colour
src/bulma.scss The Bulma modules the app uses
src/theme.css Colour tokens and Bulma overrides for light and dark mode
src/chat.css Layout of the start page and the conversation
src/Service/Group.ts The peers of a chat and how they find and greet each other
src/Service/RoomKey.ts The chat's key: the link's secret, encryption, decryption
src/Service/ChatHelper.ts Peer IDs, chat links, nicknames, file sizes
src/Struct/ Message, packet and file transfer models
src/__tests__/ Jest tests
e2e/ Playwright tests and the static server they use
public/ Static site: index.html, manifest, service worker, icons and the bundle
scripts/icons.js Draws the app icons from the logo
turn/ The TURN relay: coturn configuration and its deploy
npm run build produces a fully static site in public. Upload that folder
to any static host. The app only uses the root path, so no rewrite rules are
needed.
The TURN relay deploys itself to its VPS from GitHub Actions; the one-time
setup is in turn/README.md.