Compare commits

..

3 Commits

Author SHA1 Message Date
CrescentLeaf
05d2779922 服务端不必检查密码
因为被哈希的空字符不空
2026-02-02 22:46:11 +08:00
CrescentLeaf
a9dbb9655b 消息和用户头像右键菜单查看原始数据 2026-01-25 16:04:48 +08:00
CrescentLeaf
2aa9425334 docs: readme 2026-01-25 00:59:22 +08:00
3 changed files with 75 additions and 27 deletions

View File

@@ -1,6 +1,7 @@
import { Message } from 'lingchair-client-protocol' import { Message } from 'lingchair-client-protocol'
import * as React from 'react' import * as React from 'react'
import ChatMessage from './ChatMessage.tsx' import ChatMessage from './ChatMessage.tsx'
import { dialog } from 'mdui'
export default function ChatMessageContainer({ messages }: { messages: Message[] }) { export default function ChatMessageContainer({ messages }: { messages: Message[] }) {
return ( return (
@@ -53,7 +54,51 @@ export default function ChatMessageContainer({ messages }: { messages: Message[]
</div> </div>
</mdui-tooltip> </mdui-tooltip>
} }
<ChatMessage message={msg} noUserDisplay={lastUser == user && !shouldShowTime} /> <ChatMessage
message={msg}
noUserDisplay={lastUser == user && !shouldShowTime}
avatarMenuItems={[
<mdui-menu-item icon="info" onClick={async () => {
const user = await msg.getUser().then((re) => re?.bean) || {}
dialog({
headline: "Info",
body: `<span style="word-break: break-word;">${Object.keys(user)
// @ts-ignore 懒
.map((k) => `${k} = ${user[k]}`)
.join('<br><br>')}<span>`,
closeOnEsc: true,
closeOnOverlayClick: true,
actions: [
{
text: "关闭",
onClick: () => {
return true
},
}
]
}).addEventListener('click', (e) => e.stopPropagation())
}}>JSON</mdui-menu-item>
]}
messageMenuItems={[
<mdui-menu-item icon="info" onClick={() => dialog({
headline: "Info",
body: `<span style="word-break: break-word;">${Object.keys(msg.bean)
// @ts-ignore 懒
.map((k) => `${k} = ${msg.bean[k]}`)
.join('<br><br>')}<span>`,
closeOnEsc: true,
closeOnOverlayClick: true,
actions: [
{
text: "关闭",
onClick: () => {
return true
},
}
]
}).addEventListener('click', (e) => e.stopPropagation())}>Info</mdui-menu-item>
]}
/>
</> </>
}) })
})() })()

View File

@@ -6,31 +6,27 @@
铃之椅, 一个普通的即时通讯项目——简单, 轻量, 纯粹, 时而天真 铃之椅, 一个普通的即时通讯项目——简单, 轻量, 纯粹, 时而天真
*目前还没有发布正式版本, 仍在积极开发中* ***仍在开发阶段, 随时都可能有破坏性变更!***
项目代号: TheWhiteSilk ### 目前的功能
### 基本功能
<details> <details>
<summary>客户端</summary> <summary>客户端</summary>
*: 重构中
- 消息 - 消息
- [x] 收发消息 - [ ] *收发消息
- [x] 富文本 (based on Marked) - [x] 富文本
- [x] 图片
- [x] 视频
- [x] 文件
- [ ] 测试其他 Markdown 语法的可用性
- [ ] 撤回消息 - [ ] 撤回消息
- [ ] 修改消息 - [ ] 修改消息
- 对话 - 对话
- [x] 最近对话 - [x] 最近对话
- [x] 添加对话 - [x] 添加收藏对话
- [x] 添加用户 - [x] 添加用户
- [x] 添加群组 - [x] 添加群组
- [ ] 群组管理 - [ ] *群组管理
- 帐号 - 帐号
- [x] 登录注册 - [x] 登录注册
@@ -64,46 +60,48 @@
- [x] 登录注册 - [x] 登录注册
- [x] 资料编辑 - [x] 资料编辑
- [ ] 帐号管理 - [ ] 帐号管理
- [ ] 重设密码 - [x] 重设密码 (不够好!)
- [ ] 绑定邮箱 - [ ] 绑定邮箱
</details> </details>
### 快速上手 ### 部署
```bash ```bash
git clone https://codeberg.org/CrescentLeaf/LingChair git clone https://codeberg.org/CrescentLeaf/LingChair
cd LingChair cd LingChair
# 编译前端 npm run install-dependencies
deno task build npm run build-client
# 运行服务 npm run server
deno task server
``` ```
#### 配置 #### 配置
[thewhitesilk_config.json 是什么?](./server/config.ts) thewhitesilk_config.json [请见此处](./server/config.ts)
### 使用的项目 / 技术栈 ### 使用的项目 /
本项目由 Deno 强力驱动 Deno 存在的严重问题, 已重新迁移到 Node.js
*当然, 由于没有使用 Deno Api, 只有 Node Api, 因此理论上 Node.js 也能运行, 但需要另外安装依赖* - 客户端协议
- crypto-browserify
- 前端 - 前端
- 编译 - 编译
- vite - vite
- vite-plugin-babel
- react - react
- socket.io-client - socket.io-client
- mdui - mdui
- split.js - split.js
- react-json-view - ua-parser-js
- pinch-zoom
- use-context-selector
- dompurify - dompurify
- marked - marked
- 后端 - 后端
- express - express
- express-fileupload
- socket.io - socket.io
- chalk - chalk
- file-type - file-type

View File

@@ -140,7 +140,12 @@ export default class UserApi extends BaseApi {
}) })
// 注冊 // 注冊
this.registerEvent("User.register", (args, { deviceId }) => { this.registerEvent("User.register", (args, { deviceId }) => {
if (this.checkArgsMissing(args, ['nickname', 'password'])) return { // 判断密码是否为空已经没有意义
// 因为空字符的哈希值不为空
// 后续会修缮关于注册的机制
// 比如限制 IP, 需要邮箱
// 虽然我知道这没有什么意义
if (this.checkArgsEmpty(args, ['nickname'])) return {
msg: "参数缺失", msg: "参数缺失",
code: 400, code: 400,
} }