most-box 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -14
- package/electron/main.js +1 -1
- package/out/admin/index.html +0 -0
- package/out/app/index.html +0 -0
- package/out/assets/AccountMenu-D36x3rKH.js +1 -0
- package/out/assets/AppTop-qtp-3wqv.js +1 -0
- package/out/assets/CopyButton-C00LHzxo.js +1 -0
- package/out/assets/FilePreviewOverlay-BvOCftIV.js +1 -0
- package/out/assets/{MarketingHeader-7B-OT2XX.js → MarketingHeader-D7AjEmWU.js} +1 -1
- package/out/assets/MarketingLayout-BVw4vr-u.js +1 -0
- package/out/assets/{MilkdownEditor-WedhCoFH.js → MilkdownEditor-DXVbZsH_.js} +92 -92
- package/out/assets/OpenSidebarButton-DI6Ld8um.js +1 -0
- package/out/assets/arrow-right-CXzRt0Fp.js +1 -0
- package/out/assets/arrow-up-down-B-677ip8.js +1 -0
- package/out/assets/chatJoinInvite-aCHhLrlm.js +1 -0
- package/out/assets/chatNoteDraft-CYbvcEvC.js +1 -0
- package/out/assets/check-iBCQl0yr.js +1 -0
- package/out/assets/chevron-right-D75NRNNs.js +1 -0
- package/out/assets/circle-alert-dfN4T6Nq.js +1 -0
- package/out/assets/cobol-DHLQUbN7.js +1 -0
- package/out/assets/copy-B7pPZ2MP.js +1 -0
- package/out/assets/{dist-DCX0ws1K.js → dist-1jNICPWO.js} +1 -1
- package/out/assets/{dist-BAJKKN4w.js → dist-B3unnv5t.js} +1 -1
- package/out/assets/{dist-DJdv-Ma3.js → dist-B5MBMmGa.js} +1 -1
- package/out/assets/{dist-CMmmtl3f.js → dist-BAqJdUtV.js} +1 -1
- package/out/assets/{dist-C3lbe8SW.js → dist-BBJOmVU3.js} +1 -1
- package/out/assets/{dist-IN8WN7NI.js → dist-BV5CqsJD.js} +1 -1
- package/out/assets/{dist-DBnWo8ZP.js → dist-Ba7fxbV-.js} +1 -1
- package/out/assets/{dist-BzqqCPi2.js → dist-BxxtNKuo.js} +1 -1
- package/out/assets/{dist-DvWZsW-D.js → dist-C8Ue2rSs.js} +1 -1
- package/out/assets/{dist-C-Tg23jc.js → dist-CIn7Xx5U.js} +1 -1
- package/out/assets/{dist-CbTzBiwL.js → dist-CSyRxrry.js} +3 -3
- package/out/assets/{dist-DTL5jL08.js → dist-CZIuQqmV.js} +1 -1
- package/out/assets/{dist-8QDHqrPN.js → dist-CaaBTHCc.js} +1 -1
- package/out/assets/{dist-yZ96GF-e.js → dist-CgReC0ZE.js} +1 -1
- package/out/assets/{dist-D94V9Zlh.js → dist-Ct90qYA2.js} +1 -1
- package/out/assets/{dist-IGpXmkFm.js → dist-DIFFjNuO.js} +1 -1
- package/out/assets/{dist-CqQavSZV.js → dist-DUB2IhWu.js} +1 -1
- package/out/assets/{dist-B0JrbG7f.js → dist-DheA_Tyz.js} +1 -1
- package/out/assets/{dist-Br_5lLVO.js → dist-DyZh1ncm.js} +1 -1
- package/out/assets/{dist-BPs0Xns9.js → dist-E74uGTy3.js} +1 -1
- package/out/assets/{dist-BFSyuOuw.js → dist-K2s-Uj08.js} +1 -1
- package/out/assets/{dist-zyJb88Zz.js → dist-RU_cpjXQ.js} +1 -1
- package/out/assets/{dist-chOCTzB2.js → dist-eIeCvp_6.js} +1 -1
- package/out/assets/{dist-CfU9fwWz.js → dist-hEE2Ub__.js} +1 -1
- package/out/assets/download-COQOcPqI.js +1 -0
- package/out/assets/downloadValidation-UPgpJbKz.js +1 -0
- package/out/assets/external-link-D6tHlYgS.js +1 -0
- package/out/assets/file-text-DiyIGL1I.js +1 -0
- package/out/assets/folder-BS_GbpPQ.js +1 -0
- package/out/assets/hard-drive-Cqa7Rstj.js +1 -0
- package/out/assets/index-CUzbruyP.js +31 -0
- package/out/assets/index-FV6RZlVI.css +1 -0
- package/out/assets/index.lazy-08bEbzIk.js +1 -0
- package/out/assets/index.lazy-6b-8jxXI.js +1 -0
- package/out/assets/index.lazy-B4pxVFWK.js +2 -0
- package/out/assets/index.lazy-Bi5KZylP.js +5 -0
- package/out/assets/index.lazy-CJnFeoy4.js +1 -0
- package/out/assets/index.lazy-CRV2-Y6z.js +3 -0
- package/out/assets/index.lazy-CzCHV559.js +1 -0
- package/out/assets/index.lazy-DrfZ9XTR.js +1 -0
- package/out/assets/index.lazy-DuvCRtpm.js +1 -0
- package/out/assets/index.lazy-DxOIgf3c.js +1 -0
- package/out/assets/index.lazy-FNVWBYth.js +1 -0
- package/out/assets/index.lazy-Itk05ouU.js +1 -0
- package/out/assets/index.lazy-_CazgyO7.js +1 -0
- package/out/assets/index.lazy-odd8ydDw.js +3 -0
- package/out/assets/key-round-JR8M3aHl.js +1 -0
- package/out/assets/loader-CwyHYZdX.js +1 -0
- package/out/assets/lock-CuwwlXlx.js +1 -0
- package/out/assets/message-square-BgsNXPft.js +1 -0
- package/out/assets/mp-Dv12gDTx.js +1 -0
- package/out/assets/music-Dn9nm9Qb.js +1 -0
- package/out/assets/notebook-pen-BzrCXQJE.js +1 -0
- package/out/assets/play-CvWKSMwY.js +1 -0
- package/out/assets/refresh-cw-D4BsHvhi.js +1 -0
- package/out/assets/save-B02sbO9Y.js +1 -0
- package/out/assets/scheme-tChLYBuY.js +1 -0
- package/out/assets/search-HW4oPOBP.js +1 -0
- package/out/assets/send-4dhnJGuS.js +1 -0
- package/out/assets/shield-check-Boae7Nc6.js +1 -0
- package/out/assets/smartphone-JXH-zQXB.js +1 -0
- package/out/assets/textile-CyzeGT9J.js +1 -0
- package/out/assets/trash-2-BLwoM0ME.js +1 -0
- package/out/assets/triangle-alert-B9sMiA9l.js +1 -0
- package/out/assets/upload-DVuXJt_o.js +1 -0
- package/out/assets/useAppStore-DOnk608w.js +4 -0
- package/out/assets/{useChannelMessages-Bs_RWgO4.js → useChannelMessages-CDvw-f_x.js} +1 -1
- package/out/assets/useGameRoom-CATo4XWU.js +1 -0
- package/out/assets/userProfile-BZvkCuet.js +1 -0
- package/out/assets/wallet-D9Iw4YWE.js +1 -0
- package/out/assets/wifi-ljEI_ySA.js +1 -0
- package/out/chat/index.html +0 -0
- package/out/chat/join/demo/index.html +0 -0
- package/out/chat/join/index.html +0 -0
- package/out/download/index.html +2 -2
- package/out/game/gandengyan/index.html +0 -0
- package/out/game/index.html +0 -0
- package/out/game/zhajinhua/index.html +0 -0
- package/out/index.html +2 -2
- package/out/note/index.html +0 -0
- package/out/ping/index.html +2 -2
- package/out/profile/index.html +0 -0
- package/out/web3/index.html +0 -0
- package/package.json +30 -26
- package/server/index.js +3 -0
- package/server/src/config.js +0 -1
- package/server/src/core/channelAttachment.js +2 -2
- package/server/src/core/gameRoom.js +12 -19
- package/server/src/http/routes/noteVaultRoutes.js +70 -0
- package/server/src/index.js +17 -8
- package/server/src/utils/accountBackup.js +8 -0
- package/server/src/utils/api.js +0 -14
- package/server/src/utils/auth.js +0 -7
- package/server/src/utils/avatar.js +6 -6
- package/server/src/utils/noteVault.js +197 -2
- package/out/assets/AccountMenu-NjOgag0d.js +0 -1
- package/out/assets/FilePreviewOverlay-CZp6F1s_.js +0 -1
- package/out/assets/MarketingLayout-CyiSCygk.js +0 -1
- package/out/assets/OpenSidebarButton-BoSmO8CY.js +0 -1
- package/out/assets/SidebarHomeLink-CkhGDvZ8.js +0 -1
- package/out/assets/arrow-right-DUxAoZqb.js +0 -1
- package/out/assets/avatar-BZwHW4ll.js +0 -4
- package/out/assets/circle-alert-DSZ0bG_3.js +0 -1
- package/out/assets/cobol-B_OZ4V-R.js +0 -1
- package/out/assets/copy-CK7HMulu.js +0 -1
- package/out/assets/download-Q1uCiwif.js +0 -1
- package/out/assets/downloadValidation-Ch966YTl.js +0 -1
- package/out/assets/external-link-DGzNJOqQ.js +0 -1
- package/out/assets/file-text-C3v0L_lQ.js +0 -1
- package/out/assets/folder-CwtLO09O.js +0 -1
- package/out/assets/hard-drive-B2V5USzR.js +0 -1
- package/out/assets/i18n-DZaOYCSO.js +0 -1
- package/out/assets/index-CBkHUp3F.css +0 -1
- package/out/assets/index-DluhgSHX.js +0 -31
- package/out/assets/index.lazy-B5TYRvFJ.js +0 -1
- package/out/assets/index.lazy-BeDctVci.js +0 -1
- package/out/assets/index.lazy-BjmAkVtV.js +0 -1
- package/out/assets/index.lazy-CHJbzlK6.js +0 -1
- package/out/assets/index.lazy-CITrkWMQ.js +0 -1
- package/out/assets/index.lazy-CTGE5fUt.js +0 -2
- package/out/assets/index.lazy-CUxcXUMy.js +0 -2
- package/out/assets/index.lazy-D84xQtPb.js +0 -3
- package/out/assets/index.lazy-DRqAgqpV.js +0 -1
- package/out/assets/index.lazy-DSAmY1q_.js +0 -1
- package/out/assets/index.lazy-DvbVQRSL.js +0 -1
- package/out/assets/index.lazy-gAJi-rJV.js +0 -1
- package/out/assets/index.lazy-rzyMd-Gz.js +0 -1
- package/out/assets/key-round-Dn5tud-4.js +0 -1
- package/out/assets/loader-CLoDCtNy.js +0 -1
- package/out/assets/lock-BEWKuIqK.js +0 -1
- package/out/assets/message-square-C8ZiYztG.js +0 -1
- package/out/assets/mp-CGBtY36n.js +0 -1
- package/out/assets/music-BsTA8b_M.js +0 -1
- package/out/assets/notebook-pen-DgWzxf2y.js +0 -1
- package/out/assets/play-CVkbAJJU.js +0 -1
- package/out/assets/plus-D1kCYb8G.js +0 -1
- package/out/assets/save-X5c7jlCg.js +0 -1
- package/out/assets/scheme-CyDdOh7e.js +0 -1
- package/out/assets/search-DAV9vDOq.js +0 -1
- package/out/assets/send-C5JjYo-A.js +0 -1
- package/out/assets/shield-check-DuD6OLde.js +0 -1
- package/out/assets/smartphone-gVFruyjO.js +0 -1
- package/out/assets/textile-DWBqthVk.js +0 -1
- package/out/assets/trash-2-CE-3Dc63.js +0 -1
- package/out/assets/triangle-alert-DnOxsFpB.js +0 -1
- package/out/assets/upload-CsnBv3pd.js +0 -1
- package/out/assets/useGameRoom-BxDxm3rp.js +0 -1
- package/out/assets/userProfile-UphvP_bG.js +0 -1
- package/out/assets/wallet-VDaoXwjI.js +0 -1
- package/out/assets/wifi-DfWbmlGE.js +0 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "most-box",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "MostBox - P2P
|
|
3
|
+
"version": "0.3.3",
|
|
4
|
+
"description": "MostBox - chat-first P2P toolbox for files, notes, and game rooms",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "electron/main.js",
|
|
7
7
|
"bin": {
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"typecheck": "tsc -p tsconfig.typecheck.json",
|
|
31
31
|
"typecheck:strict-router": "tsc -p tsconfig.strict-router.json",
|
|
32
32
|
"check:static-output": "node scripts/check-static-output.mjs",
|
|
33
|
-
"format": "
|
|
34
|
-
"lint": "
|
|
33
|
+
"format": "prettier --write .",
|
|
34
|
+
"lint": "eslint .",
|
|
35
35
|
"r2:cors": "node scripts/configure-r2-cors.mjs",
|
|
36
36
|
"electron:dev": "concurrently \"npm run build\" \"wait-on out/index.html && electron .\"",
|
|
37
37
|
"electron:rebuild": "electron-rebuild -f -w sodium-native",
|
|
@@ -44,29 +44,33 @@
|
|
|
44
44
|
},
|
|
45
45
|
"keywords": [
|
|
46
46
|
"p2p",
|
|
47
|
+
"chat",
|
|
47
48
|
"file-sharing",
|
|
49
|
+
"file-transfer",
|
|
48
50
|
"hyperswarm",
|
|
51
|
+
"hypercore",
|
|
49
52
|
"hyperdrive"
|
|
50
53
|
],
|
|
51
54
|
"license": "MIT",
|
|
52
55
|
"dependencies": {
|
|
53
|
-
"@dicebear/
|
|
54
|
-
"@dicebear/
|
|
55
|
-
"@hono/node-server": "^2.0.
|
|
56
|
-
"@tanstack/react-router": "^1.170.
|
|
57
|
-
"@tanstack/react-start": "^1.168.
|
|
56
|
+
"@dicebear/core": "^10.3.0",
|
|
57
|
+
"@dicebear/styles": "^10.2.0",
|
|
58
|
+
"@hono/node-server": "^2.0.6",
|
|
59
|
+
"@tanstack/react-router": "^1.170.16",
|
|
60
|
+
"@tanstack/react-start": "^1.168.26",
|
|
61
|
+
"@tanstack/react-table": "^8.21.3",
|
|
58
62
|
"b4a": "^1.8.1",
|
|
59
63
|
"busboy": "^1.6.0",
|
|
60
|
-
"corestore": "^7.
|
|
64
|
+
"corestore": "^7.11.0",
|
|
61
65
|
"dayjs": "^1.11.21",
|
|
62
|
-
"ethers": "^6.
|
|
66
|
+
"ethers": "^6.17.0",
|
|
63
67
|
"eventemitter3": "^5.0.4",
|
|
64
|
-
"hono": "^4.12.
|
|
65
|
-
"hypercore": "^11.33.
|
|
68
|
+
"hono": "^4.12.27",
|
|
69
|
+
"hypercore": "^11.33.2",
|
|
66
70
|
"hyperdrive": "^13.3.2",
|
|
67
71
|
"hyperswarm": "^4.17.0",
|
|
68
72
|
"ipfs-unixfs-importer": "^17.0.1",
|
|
69
|
-
"multiformats": "^14.0.
|
|
73
|
+
"multiformats": "^14.0.2",
|
|
70
74
|
"tweetnacl": "^1.0.3",
|
|
71
75
|
"ws": "^8.21.0"
|
|
72
76
|
},
|
|
@@ -74,26 +78,26 @@
|
|
|
74
78
|
"@electron/rebuild": "^4.0.4",
|
|
75
79
|
"@eslint/js": "^10.0.1",
|
|
76
80
|
"@iconify/react": "^6.0.2",
|
|
77
|
-
"@mantine/hooks": "^9.
|
|
81
|
+
"@mantine/hooks": "^9.4.0",
|
|
78
82
|
"@milkdown/crepe": "^7.21.2",
|
|
79
83
|
"@milkdown/utils": "^7.21.2",
|
|
80
|
-
"@types/react": "^19.2.
|
|
81
|
-
"@vitejs/plugin-react": "^6.0.
|
|
84
|
+
"@types/react": "^19.2.17",
|
|
85
|
+
"@vitejs/plugin-react": "^6.0.3",
|
|
82
86
|
"concurrently": "^10.0.3",
|
|
83
|
-
"electron": "^42.
|
|
84
|
-
"electron-builder": "^26.
|
|
85
|
-
"esbuild": "^0.28.
|
|
86
|
-
"eslint": "^10.
|
|
87
|
-
"globals": "^17.
|
|
87
|
+
"electron": "^42.5.0",
|
|
88
|
+
"electron-builder": "^26.15.3",
|
|
89
|
+
"esbuild": "^0.28.1",
|
|
90
|
+
"eslint": "^10.5.0",
|
|
91
|
+
"globals": "^17.7.0",
|
|
88
92
|
"ky": "^2.0.2",
|
|
89
|
-
"lucide-react": "^1.
|
|
90
|
-
"prettier": "^3.8.
|
|
93
|
+
"lucide-react": "^1.21.0",
|
|
94
|
+
"prettier": "^3.8.4",
|
|
91
95
|
"qrcode.react": "^4.2.0",
|
|
92
96
|
"react": "^19.2.7",
|
|
93
97
|
"react-dom": "^19.2.7",
|
|
94
98
|
"typescript": "6.0.3",
|
|
95
|
-
"typescript-eslint": "^8.
|
|
96
|
-
"vite": "^8.0
|
|
99
|
+
"typescript-eslint": "^8.62.0",
|
|
100
|
+
"vite": "^8.1.0",
|
|
97
101
|
"wait-on": "^9.0.10",
|
|
98
102
|
"zustand": "^5.0.14"
|
|
99
103
|
},
|
package/server/index.js
CHANGED
|
@@ -137,6 +137,9 @@ function bindEngineEvents({
|
|
|
137
137
|
engine.on('channel:peer:offline', data =>
|
|
138
138
|
wsBroadcast('channel:peer:offline', data)
|
|
139
139
|
)
|
|
140
|
+
engine.on('channel:sync:available', data =>
|
|
141
|
+
wsBroadcast('channel:sync:available', data)
|
|
142
|
+
)
|
|
140
143
|
engine.on('channel:presence', data =>
|
|
141
144
|
wsSendToChannel(data.channelKey, 'channel:presence', data)
|
|
142
145
|
)
|
package/server/src/config.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parseMostLink, validateCidString } from './cid.js'
|
|
1
|
+
import { buildMostLink, parseMostLink, validateCidString } from './cid.js'
|
|
2
2
|
import { sanitizeFilename } from '../utils/security.js'
|
|
3
3
|
import { ValidationError } from '../utils/errors.js'
|
|
4
4
|
|
|
@@ -53,7 +53,7 @@ export function normalizeChannelAttachment(input) {
|
|
|
53
53
|
kind,
|
|
54
54
|
cid,
|
|
55
55
|
fileName,
|
|
56
|
-
link:
|
|
56
|
+
link: buildMostLink(cid, fileName),
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
if (typeof input.mimeType === 'string' && input.mimeType.length <= 100) {
|
|
@@ -19,7 +19,9 @@ export const GAME_IDS = ['gandengyan', 'zhajinhua']
|
|
|
19
19
|
const ROOM_CODE_ALPHABET = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'
|
|
20
20
|
|
|
21
21
|
export function normalizeGameId(input) {
|
|
22
|
-
const value = String(input || '')
|
|
22
|
+
const value = String(input || '')
|
|
23
|
+
.trim()
|
|
24
|
+
.toLowerCase()
|
|
23
25
|
return GAME_IDS.includes(value) ? value : ''
|
|
24
26
|
}
|
|
25
27
|
|
|
@@ -47,7 +49,9 @@ export function gameRoomCodeToChannelName(gameId, roomCode) {
|
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
export function channelNameToGameRoom(input) {
|
|
50
|
-
const value = String(input || '')
|
|
52
|
+
const value = String(input || '')
|
|
53
|
+
.trim()
|
|
54
|
+
.toLowerCase()
|
|
51
55
|
const match = /^game\.([a-z0-9]+)\.([a-z0-9]+)$/.exec(value)
|
|
52
56
|
if (!match) return null
|
|
53
57
|
const gameId = normalizeGameId(match[1])
|
|
@@ -86,7 +90,8 @@ export function parseGameEvent(content, options = {}) {
|
|
|
86
90
|
const gameId = normalizeGameId(event.gameId)
|
|
87
91
|
const roomCode = normalizeGameRoomCode(event.roomCode)
|
|
88
92
|
if (!gameId || !isValidGameRoomCode(roomCode)) return null
|
|
89
|
-
if (options.gameId && gameId !== normalizeGameId(options.gameId))
|
|
93
|
+
if (options.gameId && gameId !== normalizeGameId(options.gameId))
|
|
94
|
+
return null
|
|
90
95
|
if (
|
|
91
96
|
options.roomCode &&
|
|
92
97
|
roomCode !== normalizeGameRoomCode(options.roomCode)
|
|
@@ -99,9 +104,7 @@ export function parseGameEvent(content, options = {}) {
|
|
|
99
104
|
gameId,
|
|
100
105
|
roomCode,
|
|
101
106
|
payload:
|
|
102
|
-
event.payload && typeof event.payload === 'object'
|
|
103
|
-
? event.payload
|
|
104
|
-
: {},
|
|
107
|
+
event.payload && typeof event.payload === 'object' ? event.payload : {},
|
|
105
108
|
}
|
|
106
109
|
} catch {
|
|
107
110
|
return null
|
|
@@ -132,7 +135,9 @@ export function deriveGameRoomLobby(messages = [], options = {}) {
|
|
|
132
135
|
}
|
|
133
136
|
|
|
134
137
|
if (event.event === 'player:leave') {
|
|
135
|
-
const address = normalizeAddress(
|
|
138
|
+
const address = normalizeAddress(
|
|
139
|
+
event.payload?.player?.address || message.author
|
|
140
|
+
)
|
|
136
141
|
if (address) {
|
|
137
142
|
const index = players.findIndex(p => p.address === address)
|
|
138
143
|
if (index !== -1) {
|
|
@@ -190,18 +195,6 @@ export function createPlayerFromPayload(input, messageOrAuthor) {
|
|
|
190
195
|
return player
|
|
191
196
|
}
|
|
192
197
|
|
|
193
|
-
export function normalizeGamePlayer(input) {
|
|
194
|
-
if (!input || typeof input !== 'object') return null
|
|
195
|
-
const address = normalizeAddress(input.address)
|
|
196
|
-
if (!address) return null
|
|
197
|
-
return {
|
|
198
|
-
...input,
|
|
199
|
-
address,
|
|
200
|
-
name: String(input.name || shortAddress(address)).slice(0, 50),
|
|
201
|
-
publicKey: String(input.publicKey || ''),
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
198
|
function upsertPlayer(players, playerMap, player) {
|
|
206
199
|
const existing = playerMap.get(player.address)
|
|
207
200
|
if (existing) {
|
|
@@ -2,10 +2,15 @@ import { errorJson } from '../errors.js'
|
|
|
2
2
|
import { PermissionError } from '../../utils/errors.js'
|
|
3
3
|
import {
|
|
4
4
|
configureNoteVault,
|
|
5
|
+
createMarkdownFile,
|
|
6
|
+
createNoteVaultSnapshot,
|
|
7
|
+
deleteMarkdownFile,
|
|
5
8
|
getConfiguredNoteVaultPath,
|
|
6
9
|
getNoteVaultStatus,
|
|
7
10
|
listMarkdownFiles,
|
|
11
|
+
moveMarkdownFile,
|
|
8
12
|
readMarkdownFile,
|
|
13
|
+
restoreNoteVaultSnapshot,
|
|
9
14
|
writeMarkdownFile,
|
|
10
15
|
} from '../../utils/noteVault.js'
|
|
11
16
|
|
|
@@ -67,6 +72,22 @@ export function registerNoteVaultRoutes(app, { configStore, isRemoteRequest }) {
|
|
|
67
72
|
}
|
|
68
73
|
})
|
|
69
74
|
|
|
75
|
+
app.post('/api/note-vault/file', async c => {
|
|
76
|
+
try {
|
|
77
|
+
assertNoteVaultAccess(c, isRemoteRequest)
|
|
78
|
+
const body = await c.req.json()
|
|
79
|
+
const vaultPath = await getConfiguredNoteVaultPath(configStore.configDir)
|
|
80
|
+
const file = await createMarkdownFile(
|
|
81
|
+
vaultPath,
|
|
82
|
+
String(body.path || ''),
|
|
83
|
+
String(body.content || '')
|
|
84
|
+
)
|
|
85
|
+
return c.json({ success: true, file })
|
|
86
|
+
} catch (err) {
|
|
87
|
+
return errorJson(c, err)
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
|
|
70
91
|
app.put('/api/note-vault/file', async c => {
|
|
71
92
|
try {
|
|
72
93
|
assertNoteVaultAccess(c, isRemoteRequest)
|
|
@@ -82,4 +103,53 @@ export function registerNoteVaultRoutes(app, { configStore, isRemoteRequest }) {
|
|
|
82
103
|
return errorJson(c, err)
|
|
83
104
|
}
|
|
84
105
|
})
|
|
106
|
+
|
|
107
|
+
app.patch('/api/note-vault/file', async c => {
|
|
108
|
+
try {
|
|
109
|
+
assertNoteVaultAccess(c, isRemoteRequest)
|
|
110
|
+
const body = await c.req.json()
|
|
111
|
+
const vaultPath = await getConfiguredNoteVaultPath(configStore.configDir)
|
|
112
|
+
const file = await moveMarkdownFile(
|
|
113
|
+
vaultPath,
|
|
114
|
+
String(body.path || body.fromPath || ''),
|
|
115
|
+
String(body.newPath || body.toPath || '')
|
|
116
|
+
)
|
|
117
|
+
return c.json({ success: true, file })
|
|
118
|
+
} catch (err) {
|
|
119
|
+
return errorJson(c, err)
|
|
120
|
+
}
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
app.delete('/api/note-vault/file', async c => {
|
|
124
|
+
try {
|
|
125
|
+
assertNoteVaultAccess(c, isRemoteRequest)
|
|
126
|
+
const vaultPath = await getConfiguredNoteVaultPath(configStore.configDir)
|
|
127
|
+
const result = await deleteMarkdownFile(vaultPath, c.req.query('path'))
|
|
128
|
+
return c.json({ success: true, ...result })
|
|
129
|
+
} catch (err) {
|
|
130
|
+
return errorJson(c, err)
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
app.get('/api/note-vault/snapshot', async c => {
|
|
135
|
+
try {
|
|
136
|
+
assertNoteVaultAccess(c, isRemoteRequest)
|
|
137
|
+
const vaultPath = await getConfiguredNoteVaultPath(configStore.configDir)
|
|
138
|
+
return c.json(await createNoteVaultSnapshot(vaultPath))
|
|
139
|
+
} catch (err) {
|
|
140
|
+
return errorJson(c, err)
|
|
141
|
+
}
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
app.post('/api/note-vault/restore', async c => {
|
|
145
|
+
try {
|
|
146
|
+
assertNoteVaultAccess(c, isRemoteRequest)
|
|
147
|
+
const body = await c.req.json()
|
|
148
|
+
const vaultPath = await getConfiguredNoteVaultPath(configStore.configDir)
|
|
149
|
+
const result = await restoreNoteVaultSnapshot(vaultPath, body)
|
|
150
|
+
return c.json({ success: true, result })
|
|
151
|
+
} catch (err) {
|
|
152
|
+
return errorJson(c, err)
|
|
153
|
+
}
|
|
154
|
+
})
|
|
85
155
|
}
|
package/server/src/index.js
CHANGED
|
@@ -625,7 +625,7 @@ export class MostBoxEngine extends EventEmitter {
|
|
|
625
625
|
})
|
|
626
626
|
return {
|
|
627
627
|
cid: cidString,
|
|
628
|
-
link:
|
|
628
|
+
link: buildMostLink(cidString, existing.fileName),
|
|
629
629
|
fileName: existing.fileName,
|
|
630
630
|
alreadyExists: true,
|
|
631
631
|
}
|
|
@@ -713,7 +713,7 @@ export class MostBoxEngine extends EventEmitter {
|
|
|
713
713
|
|
|
714
714
|
const result = {
|
|
715
715
|
cid: cidString,
|
|
716
|
-
link:
|
|
716
|
+
link: buildMostLink(cidString, safeFileName),
|
|
717
717
|
fileName: safeFileName,
|
|
718
718
|
}
|
|
719
719
|
|
|
@@ -1226,7 +1226,7 @@ export class MostBoxEngine extends EventEmitter {
|
|
|
1226
1226
|
return files.map(f => ({
|
|
1227
1227
|
fileName: f.fileName,
|
|
1228
1228
|
cid: f.cid,
|
|
1229
|
-
link:
|
|
1229
|
+
link: buildMostLink(f.cid, f.fileName),
|
|
1230
1230
|
publishedAt: f.publishedAt,
|
|
1231
1231
|
size: Number(f.size) || 0,
|
|
1232
1232
|
starred: f.starred || false,
|
|
@@ -1318,7 +1318,7 @@ export class MostBoxEngine extends EventEmitter {
|
|
|
1318
1318
|
return files.map(f => ({
|
|
1319
1319
|
fileName: f.fileName,
|
|
1320
1320
|
cid: f.cid,
|
|
1321
|
-
link:
|
|
1321
|
+
link: buildMostLink(f.cid, f.fileName),
|
|
1322
1322
|
publishedAt: f.publishedAt,
|
|
1323
1323
|
size: Number(f.size) || 0,
|
|
1324
1324
|
starred: f.starred || false,
|
|
@@ -1560,7 +1560,7 @@ export class MostBoxEngine extends EventEmitter {
|
|
|
1560
1560
|
return {
|
|
1561
1561
|
cid,
|
|
1562
1562
|
fileName: safeFileName,
|
|
1563
|
-
link:
|
|
1563
|
+
link: buildMostLink(cid, safeFileName),
|
|
1564
1564
|
}
|
|
1565
1565
|
}
|
|
1566
1566
|
|
|
@@ -1602,7 +1602,7 @@ export class MostBoxEngine extends EventEmitter {
|
|
|
1602
1602
|
return {
|
|
1603
1603
|
cid: file.cid,
|
|
1604
1604
|
fileName: file.fileName,
|
|
1605
|
-
link:
|
|
1605
|
+
link: buildMostLink(file.cid, file.fileName),
|
|
1606
1606
|
}
|
|
1607
1607
|
})
|
|
1608
1608
|
|
|
@@ -1725,7 +1725,7 @@ export class MostBoxEngine extends EventEmitter {
|
|
|
1725
1725
|
seedError: seedState?.error,
|
|
1726
1726
|
seedStatusUpdatedAt: seedState?.updatedAt,
|
|
1727
1727
|
...this.#getFileRuntimeStats(holding.cid),
|
|
1728
|
-
link:
|
|
1728
|
+
link: buildMostLink(holding.cid, holding.fileName || holding.cid),
|
|
1729
1729
|
}
|
|
1730
1730
|
})
|
|
1731
1731
|
}
|
|
@@ -1782,7 +1782,7 @@ export class MostBoxEngine extends EventEmitter {
|
|
|
1782
1782
|
|
|
1783
1783
|
this.#getCidInfo(cid)
|
|
1784
1784
|
const fileName = sanitizeFilename(input.fileName || `${cid}.bin`)
|
|
1785
|
-
const link =
|
|
1785
|
+
const link = buildMostLink(cid, fileName)
|
|
1786
1786
|
const result = await this.downloadFile(link, input.taskId || null, {
|
|
1787
1787
|
timeout: input.timeout,
|
|
1788
1788
|
ownerAddress: input.ownerAddress,
|
|
@@ -4818,6 +4818,15 @@ export class MostBoxEngine extends EventEmitter {
|
|
|
4818
4818
|
])
|
|
4819
4819
|
this.#saveChannelsMetadata()
|
|
4820
4820
|
}
|
|
4821
|
+
if (channel) {
|
|
4822
|
+
this.emit('channel:sync:available', {
|
|
4823
|
+
channel: channelKey,
|
|
4824
|
+
channelKey,
|
|
4825
|
+
channelId: channel.channelId || '',
|
|
4826
|
+
writerCoreKey: normalizedCoreKey,
|
|
4827
|
+
writerCoreKeys: uniqueStrings(channel.writerCoreKeys),
|
|
4828
|
+
})
|
|
4829
|
+
}
|
|
4821
4830
|
console.log(
|
|
4822
4831
|
`[MostBox] Opened remote channel core ${normalizedCoreKey.slice(0, 8)}... for ${channelKey}`
|
|
4823
4832
|
)
|
|
@@ -29,6 +29,14 @@ export function validateAccountBackupPayload(input) {
|
|
|
29
29
|
if (!Array.isArray(input.notes)) {
|
|
30
30
|
throw new Error('账号备份缺少 notes')
|
|
31
31
|
}
|
|
32
|
+
if (
|
|
33
|
+
input.noteVault !== undefined &&
|
|
34
|
+
(!input.noteVault ||
|
|
35
|
+
typeof input.noteVault !== 'object' ||
|
|
36
|
+
!Array.isArray(input.noteVault.files))
|
|
37
|
+
) {
|
|
38
|
+
throw new Error('账号备份 noteVault 格式无效')
|
|
39
|
+
}
|
|
32
40
|
return input
|
|
33
41
|
}
|
|
34
42
|
|
package/server/src/utils/api.js
CHANGED
|
@@ -413,10 +413,6 @@ export function getBackendUrlExport() {
|
|
|
413
413
|
return getBackendUrl()
|
|
414
414
|
}
|
|
415
415
|
|
|
416
|
-
export function getConfiguredBackendUrlExport() {
|
|
417
|
-
return getConfiguredBackendUrl()
|
|
418
|
-
}
|
|
419
|
-
|
|
420
416
|
export function getSameOriginBackendUrlExport() {
|
|
421
417
|
return getSameOriginBackendUrl()
|
|
422
418
|
}
|
|
@@ -437,10 +433,6 @@ export function getNodeHistoryExport() {
|
|
|
437
433
|
return getNodeHistory()
|
|
438
434
|
}
|
|
439
435
|
|
|
440
|
-
export function getBackendInviteExport() {
|
|
441
|
-
return getBackendInvite()
|
|
442
|
-
}
|
|
443
|
-
|
|
444
436
|
export function getApiUrl(path) {
|
|
445
437
|
const url = getBackendUrl()
|
|
446
438
|
return `${url}${normalizePath(path)}`
|
|
@@ -510,12 +502,6 @@ export async function getAuthenticatedWebSocketUrl(path = '/ws') {
|
|
|
510
502
|
return url.toString()
|
|
511
503
|
}
|
|
512
504
|
|
|
513
|
-
export async function checkBackendConnection() {
|
|
514
|
-
const url = getBackendUrl() || getSameOriginBackendUrl()
|
|
515
|
-
const invite = shouldAttachBackendInvite(url) ? getBackendInvite() : ''
|
|
516
|
-
return checkBackendConnectionTarget({ url, invite })
|
|
517
|
-
}
|
|
518
|
-
|
|
519
505
|
async function probeHttp(cleanedUrl, invite, identity) {
|
|
520
506
|
try {
|
|
521
507
|
const headers = {}
|
package/server/src/utils/auth.js
CHANGED
|
@@ -51,10 +51,3 @@ export function verifyAuthHeader(header, method, path, options = {}) {
|
|
|
51
51
|
return { ok: false, error: 'Invalid authorization signature' }
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
|
-
|
|
55
|
-
export function parseInviteList(value = '') {
|
|
56
|
-
return String(value || '')
|
|
57
|
-
.split(',')
|
|
58
|
-
.map(item => item.trim())
|
|
59
|
-
.filter(Boolean)
|
|
60
|
-
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { Avatar, Style } from '@dicebear/core'
|
|
2
|
+
import botttsNeutralDefinition from '@dicebear/styles/bottts-neutral.json' with { type: 'json' }
|
|
3
3
|
|
|
4
4
|
export const defaultAvatarIds = [
|
|
5
5
|
'panda',
|
|
@@ -50,11 +50,11 @@ export function normalizeDefaultAvatarValue(avatar) {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
function createAddressAvatar(address) {
|
|
53
|
-
|
|
53
|
+
const avatar = new Avatar(new Style(botttsNeutralDefinition), {
|
|
54
54
|
seed: 'most.box@' + address,
|
|
55
|
-
flip:
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
flip: 'horizontal',
|
|
56
|
+
})
|
|
57
|
+
return avatar.toDataUri()
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
export function generateAvatar(address, avatar) {
|