ocean-brain 0.4.1 → 0.4.2
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/package.json +3 -1
- package/server/client/dist/assets/{Calendar-D4KkvcU8.js → Calendar-DI0PhQTq.js} +1 -1
- package/server/client/dist/assets/{Callout-CaSzc-1y.js → Callout-BAqbXI0L.js} +1 -1
- package/server/client/dist/assets/{Graph-C8pBdJzV.js → Graph-Dhuog4tc.js} +1 -1
- package/server/client/dist/assets/{Image.es-C8g5NwNt.js → Image.es-COwqkQuh.js} +1 -1
- package/server/client/dist/assets/Note-ChUWU3Su.js +21 -0
- package/server/client/dist/assets/{Plus.es-Bkl1ZXE0.js → Plus.es-KeV96R_e.js} +1 -1
- package/server/client/dist/assets/{Reminders-FrTR9ny8.js → Reminders-D7MCTNxb.js} +1 -1
- package/server/client/dist/assets/{Search-BPf2LO1Y.js → Search-B-fwTr5y.js} +1 -1
- package/server/client/dist/assets/{SurfaceCard-WSk7zWeM.js → SurfaceCard-CHjcCuqZ.js} +1 -1
- package/server/client/dist/assets/{Tag-uArdLjo1.js → Tag-BbV2z-Db.js} +1 -1
- package/server/client/dist/assets/{TagNotes-DDvXHB9I.js → TagNotes-2HKF09Jm.js} +1 -1
- package/server/client/dist/assets/{Trash.es-DumPfiUz.js → Trash.es-BqRTZPrI.js} +1 -1
- package/server/client/dist/assets/{ViewNotes-BVu9lEs-.js → ViewNotes-TfM3Uzbp.js} +1 -1
- package/server/client/dist/assets/{Views-D4LGh30P.js → Views-CUwtnfa8.js} +1 -1
- package/server/client/dist/assets/{image.api-D3Ei3fbf.js → image.api-CMdQbCyN.js} +1 -1
- package/server/client/dist/assets/index-B4l2UvuC.js +232 -0
- package/server/client/dist/assets/{index-C7YGbIuA.js → index-zhxZjg7V.js} +1 -1
- package/server/client/dist/assets/{manage-image-DiuREdeE.js → manage-image-DdXb5Bkj.js} +1 -1
- package/server/client/dist/assets/{manage-image-detail-D8Eorq3u.js → manage-image-detail-CrrXCQIX.js} +1 -1
- package/server/client/dist/assets/{mcp-CvCGaYSz.js → mcp-DqGLZv90.js} +1 -1
- package/server/client/dist/assets/{placeholder-znZDfNAE.js → placeholder-BXLtvdtN.js} +1 -1
- package/server/client/dist/assets/{trash-R0sww0ur.js → trash-3eUAjFRh.js} +1 -1
- package/server/client/dist/assets/{useReminderMutate-Bkj-oIm4.js → useReminderMutate-v1EXqM90.js} +1 -1
- package/server/client/dist/assets/{view-dashboard-ClpF_qLM.js → view-dashboard-T6gmohr-.js} +1 -1
- package/server/client/dist/index.html +1 -1
- package/server/dist/app.js +2 -2
- package/server/dist/app.js.map +1 -1
- package/server/dist/features/auth/http/login-page.js +11 -4
- package/server/dist/features/auth/http/login-page.js.map +1 -1
- package/server/dist/features/auth/http/pages.js +3 -2
- package/server/dist/features/auth/http/pages.js.map +1 -1
- package/server/dist/modules/auth-guard.js +18 -0
- package/server/dist/modules/auth-guard.js.map +1 -1
- package/server/dist/modules/error-handler.js +7 -0
- package/server/dist/modules/error-handler.js.map +1 -1
- package/server/dist/modules/rate-limit.js +18 -0
- package/server/dist/modules/rate-limit.js.map +1 -0
- package/server/dist/routes/api.js +2 -1
- package/server/dist/routes/api.js.map +1 -1
- package/server/dist/routes/auth-pages.js +2 -1
- package/server/dist/routes/auth-pages.js.map +1 -1
- package/server/client/dist/assets/Note-ODOESft3.js +0 -21
- package/server/client/dist/assets/index-46ZUXbW5.js +0 -232
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./note-vendor-B0t5F04o.js";import{p as h,a4 as p,P as M,T as t,L as i,aw as f,g as o,ar as u,ax as j,ay as v,az as E}from"./index-46ZUXbW5.js";import{a}from"./graph-vendor-CUxe67Lr.js";import{c as N,n as w}from"./Trash.es-DumPfiUz.js";import{I as y}from"./Image.es-C8g5NwNt.js";import"./note-core-GgFcksAF.js";const H=new Map([["bold",a.createElement(a.Fragment,null,a.createElement("path",{d:"M236.37,139.4a12,12,0,0,0-12-3A84.07,84.07,0,0,1,119.6,31.59a12,12,0,0,0-15-15A108.86,108.86,0,0,0,49.69,55.07,108,108,0,0,0,136,228a107.09,107.09,0,0,0,64.93-21.69,108.86,108.86,0,0,0,38.44-54.94A12,12,0,0,0,236.37,139.4Zm-49.88,47.74A84,84,0,0,1,68.86,69.51,84.93,84.93,0,0,1,92.27,48.29Q92,52.13,92,56A108.12,108.12,0,0,0,200,164q3.87,0,7.71-.27A84.79,84.79,0,0,1,186.49,187.14Z"}))],["duotone",a.createElement(a.Fragment,null,a.createElement("path",{d:"M227.89,147.89A96,96,0,1,1,108.11,28.11,96.09,96.09,0,0,0,227.89,147.89Z",opacity:"0.2"}),a.createElement("path",{d:"M233.54,142.23a8,8,0,0,0-8-2,88.08,88.08,0,0,1-109.8-109.8,8,8,0,0,0-10-10,104.84,104.84,0,0,0-52.91,37A104,104,0,0,0,136,224a103.09,103.09,0,0,0,62.52-20.88,104.84,104.84,0,0,0,37-52.91A8,8,0,0,0,233.54,142.23ZM188.9,190.34A88,88,0,0,1,65.66,67.11a89,89,0,0,1,31.4-26A106,106,0,0,0,96,56,104.11,104.11,0,0,0,200,160a106,106,0,0,0,14.92-1.06A89,89,0,0,1,188.9,190.34Z"}))],["fill",a.createElement(a.Fragment,null,a.createElement("path",{d:"M235.54,150.21a104.84,104.84,0,0,1-37,52.91A104,104,0,0,1,32,120,103.09,103.09,0,0,1,52.88,57.48a104.84,104.84,0,0,1,52.91-37,8,8,0,0,1,10,10,88.08,88.08,0,0,0,109.8,109.8,8,8,0,0,1,10,10Z"}))],["light",a.createElement(a.Fragment,null,a.createElement("path",{d:"M232.13,143.64a6,6,0,0,0-6-1.49A90.07,90.07,0,0,1,113.86,29.85a6,6,0,0,0-7.49-7.48A102.88,102.88,0,0,0,54.48,58.68,102,102,0,0,0,197.32,201.52a102.88,102.88,0,0,0,36.31-51.89A6,6,0,0,0,232.13,143.64Zm-42,48.29a90,90,0,0,1-126-126A90.9,90.9,0,0,1,99.65,37.66,102.06,102.06,0,0,0,218.34,156.35,90.9,90.9,0,0,1,190.1,191.93Z"}))],["regular",a.createElement(a.Fragment,null,a.createElement("path",{d:"M233.54,142.23a8,8,0,0,0-8-2,88.08,88.08,0,0,1-109.8-109.8,8,8,0,0,0-10-10,104.84,104.84,0,0,0-52.91,37A104,104,0,0,0,136,224a103.09,103.09,0,0,0,62.52-20.88,104.84,104.84,0,0,0,37-52.91A8,8,0,0,0,233.54,142.23ZM188.9,190.34A88,88,0,0,1,65.66,67.11a89,89,0,0,1,31.4-26A106,106,0,0,0,96,56,104.11,104.11,0,0,0,200,160a106,106,0,0,0,14.92-1.06A89,89,0,0,1,188.9,190.34Z"}))],["thin",a.createElement(a.Fragment,null,a.createElement("path",{d:"M230.72,145.06a4,4,0,0,0-4-1A92.08,92.08,0,0,1,111.94,29.27a4,4,0,0,0-5-5A100.78,100.78,0,0,0,56.08,59.88a100,100,0,0,0,140,140,100.78,100.78,0,0,0,35.59-50.87A4,4,0,0,0,230.72,145.06ZM191.3,193.53A92,92,0,0,1,62.47,64.7a93,93,0,0,1,39.88-30.35,100.09,100.09,0,0,0,119.3,119.3A93,93,0,0,1,191.3,193.53Z"}))]]),b=new Map([["bold",a.createElement(a.Fragment,null,a.createElement("path",{d:"M203.57,51A107.9,107.9,0,0,0,20,128c0,44.72,27.6,82.25,72,97.94A36,36,0,0,0,140,192a12,12,0,0,1,12-12h46.21a35.79,35.79,0,0,0,35.1-28A108.6,108.6,0,0,0,236,127.09,107.23,107.23,0,0,0,203.57,51Zm6.34,95.67a11.91,11.91,0,0,1-11.7,9.3H152a36,36,0,0,0-36,36,12,12,0,0,1-16,11.3c-16.65-5.88-30.65-15.76-40.48-28.56A76,76,0,0,1,44,128a84,84,0,0,1,83.13-84H128a84.35,84.35,0,0,1,84,83.29A84.72,84.72,0,0,1,209.91,146.71ZM144,76a16,16,0,1,1-16-16A16,16,0,0,1,144,76Zm-44,24A16,16,0,1,1,84,84,16,16,0,0,1,100,100Zm0,56a16,16,0,1,1-16-16A16,16,0,0,1,100,156Zm88-56a16,16,0,1,1-16-16A16,16,0,0,1,188,100Z"}))],["duotone",a.createElement(a.Fragment,null,a.createElement("path",{d:"M224,127.17a96.48,96.48,0,0,1-2.39,22.18A24,24,0,0,1,198.21,168H152a24,24,0,0,0-24,24,24,24,0,0,1-32,22.61C58.73,201.44,32,169.81,32,128a96,96,0,0,1,95-96C179.84,31.47,223.55,74.35,224,127.17Z",opacity:"0.2"}),a.createElement("path",{d:"M200.77,53.89A103.27,103.27,0,0,0,128,24h-1.07A104,104,0,0,0,24,128c0,43,26.58,79.06,69.36,94.17A32,32,0,0,0,136,192a16,16,0,0,1,16-16h46.21a31.81,31.81,0,0,0,31.2-24.88,104.43,104.43,0,0,0,2.59-24A103.28,103.28,0,0,0,200.77,53.89Zm13,93.71A15.89,15.89,0,0,1,198.21,160H152a32,32,0,0,0-32,32,16,16,0,0,1-21.31,15.07C62.49,194.3,40,164,40,128a88,88,0,0,1,87.09-88h.9a88.35,88.35,0,0,1,88,87.25A88.86,88.86,0,0,1,213.81,147.6ZM140,76a12,12,0,1,1-12-12A12,12,0,0,1,140,76ZM96,100A12,12,0,1,1,84,88,12,12,0,0,1,96,100Zm0,56a12,12,0,1,1-12-12A12,12,0,0,1,96,156Zm88-56a12,12,0,1,1-12-12A12,12,0,0,1,184,100Z"}))],["fill",a.createElement(a.Fragment,null,a.createElement("path",{d:"M200.77,53.89A103.27,103.27,0,0,0,128,24h-1.07A104,104,0,0,0,24,128c0,43,26.58,79.06,69.36,94.17A32,32,0,0,0,136,192a16,16,0,0,1,16-16h46.21a31.81,31.81,0,0,0,31.2-24.88,104.43,104.43,0,0,0,2.59-24A103.28,103.28,0,0,0,200.77,53.89ZM84,168a12,12,0,1,1,12-12A12,12,0,0,1,84,168Zm0-56a12,12,0,1,1,12-12A12,12,0,0,1,84,112Zm44-24a12,12,0,1,1,12-12A12,12,0,0,1,128,88Zm44,24a12,12,0,1,1,12-12A12,12,0,0,1,172,112Z"}))],["light",a.createElement(a.Fragment,null,a.createElement("path",{d:"M199.37,55.31A101.32,101.32,0,0,0,128,26h-1A102,102,0,0,0,26,128c0,42.09,26.07,77.44,68,92.26A30.21,30.21,0,0,0,104.11,222,30.06,30.06,0,0,0,134,192a18,18,0,0,1,18-18h46.21a29.82,29.82,0,0,0,29.25-23.31A102.71,102.71,0,0,0,230,127.11,101.25,101.25,0,0,0,199.37,55.31ZM215.76,148a17.89,17.89,0,0,1-17.55,14H152a30,30,0,0,0-30,30,18,18,0,0,1-24,17C61,195.86,38,164.85,38,128a90,90,0,0,1,89.07-90H128a90.34,90.34,0,0,1,90,89.22A90.46,90.46,0,0,1,215.76,148ZM138,76a10,10,0,1,1-10-10A10,10,0,0,1,138,76ZM94,100A10,10,0,1,1,84,90,10,10,0,0,1,94,100Zm0,56a10,10,0,1,1-10-10A10,10,0,0,1,94,156Zm88-56a10,10,0,1,1-10-10A10,10,0,0,1,182,100Z"}))],["regular",a.createElement(a.Fragment,null,a.createElement("path",{d:"M200.77,53.89A103.27,103.27,0,0,0,128,24h-1.07A104,104,0,0,0,24,128c0,43,26.58,79.06,69.36,94.17A32,32,0,0,0,136,192a16,16,0,0,1,16-16h46.21a31.81,31.81,0,0,0,31.2-24.88,104.43,104.43,0,0,0,2.59-24A103.28,103.28,0,0,0,200.77,53.89Zm13,93.71A15.89,15.89,0,0,1,198.21,160H152a32,32,0,0,0-32,32,16,16,0,0,1-21.31,15.07C62.49,194.3,40,164,40,128a88,88,0,0,1,87.09-88h.9a88.35,88.35,0,0,1,88,87.25A88.86,88.86,0,0,1,213.81,147.6ZM140,76a12,12,0,1,1-12-12A12,12,0,0,1,140,76ZM96,100A12,12,0,1,1,84,88,12,12,0,0,1,96,100Zm0,56a12,12,0,1,1-12-12A12,12,0,0,1,96,156Zm88-56a12,12,0,1,1-12-12A12,12,0,0,1,184,100Z"}))],["thin",a.createElement(a.Fragment,null,a.createElement("path",{d:"M198,56.74A99.31,99.31,0,0,0,128,28h-1A100,100,0,0,0,28,128c0,41.22,25.55,75.85,66.69,90.38a28.34,28.34,0,0,0,9.42,1.63A28,28,0,0,0,132,192a20,20,0,0,1,20-20h46.21a27.84,27.84,0,0,0,27.3-21.76,100.37,100.37,0,0,0,2.49-23.1A99.26,99.26,0,0,0,198,56.74Zm19.74,91.72A19.89,19.89,0,0,1,198.21,164H152a28,28,0,0,0-28,28,20,20,0,0,1-26.64,18.83C59.51,197.46,36,165.72,36,128a92,92,0,0,1,91.05-92H128a92,92,0,0,1,89.72,112.46ZM136,76a8,8,0,1,1-8-8A8,8,0,0,1,136,76ZM92,100a8,8,0,1,1-8-8A8,8,0,0,1,92,100Zm0,56a8,8,0,1,1-8-8A8,8,0,0,1,92,156Zm88-56a8,8,0,1,1-8-8A8,8,0,0,1,180,100Z"}))]]),T=new Map([["bold",a.createElement(a.Fragment,null,a.createElement("path",{d:"M116,36V20a12,12,0,0,1,24,0V36a12,12,0,0,1-24,0Zm80,92a68,68,0,1,1-68-68A68.07,68.07,0,0,1,196,128Zm-24,0a44,44,0,1,0-44,44A44.05,44.05,0,0,0,172,128ZM51.51,68.49a12,12,0,1,0,17-17l-12-12a12,12,0,0,0-17,17Zm0,119-12,12a12,12,0,0,0,17,17l12-12a12,12,0,1,0-17-17ZM196,72a12,12,0,0,0,8.49-3.51l12-12a12,12,0,0,0-17-17l-12,12A12,12,0,0,0,196,72Zm8.49,115.51a12,12,0,0,0-17,17l12,12a12,12,0,0,0,17-17ZM48,128a12,12,0,0,0-12-12H20a12,12,0,0,0,0,24H36A12,12,0,0,0,48,128Zm80,80a12,12,0,0,0-12,12v16a12,12,0,0,0,24,0V220A12,12,0,0,0,128,208Zm108-92H220a12,12,0,0,0,0,24h16a12,12,0,0,0,0-24Z"}))],["duotone",a.createElement(a.Fragment,null,a.createElement("path",{d:"M184,128a56,56,0,1,1-56-56A56,56,0,0,1,184,128Z",opacity:"0.2"}),a.createElement("path",{d:"M120,40V16a8,8,0,0,1,16,0V40a8,8,0,0,1-16,0Zm72,88a64,64,0,1,1-64-64A64.07,64.07,0,0,1,192,128Zm-16,0a48,48,0,1,0-48,48A48.05,48.05,0,0,0,176,128ZM58.34,69.66A8,8,0,0,0,69.66,58.34l-16-16A8,8,0,0,0,42.34,53.66Zm0,116.68-16,16a8,8,0,0,0,11.32,11.32l16-16a8,8,0,0,0-11.32-11.32ZM192,72a8,8,0,0,0,5.66-2.34l16-16a8,8,0,0,0-11.32-11.32l-16,16A8,8,0,0,0,192,72Zm5.66,114.34a8,8,0,0,0-11.32,11.32l16,16a8,8,0,0,0,11.32-11.32ZM48,128a8,8,0,0,0-8-8H16a8,8,0,0,0,0,16H40A8,8,0,0,0,48,128Zm80,80a8,8,0,0,0-8,8v24a8,8,0,0,0,16,0V216A8,8,0,0,0,128,208Zm112-88H216a8,8,0,0,0,0,16h24a8,8,0,0,0,0-16Z"}))],["fill",a.createElement(a.Fragment,null,a.createElement("path",{d:"M120,40V16a8,8,0,0,1,16,0V40a8,8,0,0,1-16,0Zm8,24a64,64,0,1,0,64,64A64.07,64.07,0,0,0,128,64ZM58.34,69.66A8,8,0,0,0,69.66,58.34l-16-16A8,8,0,0,0,42.34,53.66Zm0,116.68-16,16a8,8,0,0,0,11.32,11.32l16-16a8,8,0,0,0-11.32-11.32ZM192,72a8,8,0,0,0,5.66-2.34l16-16a8,8,0,0,0-11.32-11.32l-16,16A8,8,0,0,0,192,72Zm5.66,114.34a8,8,0,0,0-11.32,11.32l16,16a8,8,0,0,0,11.32-11.32ZM48,128a8,8,0,0,0-8-8H16a8,8,0,0,0,0,16H40A8,8,0,0,0,48,128Zm80,80a8,8,0,0,0-8,8v24a8,8,0,0,0,16,0V216A8,8,0,0,0,128,208Zm112-88H216a8,8,0,0,0,0,16h24a8,8,0,0,0,0-16Z"}))],["light",a.createElement(a.Fragment,null,a.createElement("path",{d:"M122,40V16a6,6,0,0,1,12,0V40a6,6,0,0,1-12,0Zm68,88a62,62,0,1,1-62-62A62.07,62.07,0,0,1,190,128Zm-12,0a50,50,0,1,0-50,50A50.06,50.06,0,0,0,178,128ZM59.76,68.24a6,6,0,1,0,8.48-8.48l-16-16a6,6,0,0,0-8.48,8.48Zm0,119.52-16,16a6,6,0,1,0,8.48,8.48l16-16a6,6,0,1,0-8.48-8.48ZM192,70a6,6,0,0,0,4.24-1.76l16-16a6,6,0,0,0-8.48-8.48l-16,16A6,6,0,0,0,192,70Zm4.24,117.76a6,6,0,0,0-8.48,8.48l16,16a6,6,0,0,0,8.48-8.48ZM46,128a6,6,0,0,0-6-6H16a6,6,0,0,0,0,12H40A6,6,0,0,0,46,128Zm82,82a6,6,0,0,0-6,6v24a6,6,0,0,0,12,0V216A6,6,0,0,0,128,210Zm112-88H216a6,6,0,0,0,0,12h24a6,6,0,0,0,0-12Z"}))],["regular",a.createElement(a.Fragment,null,a.createElement("path",{d:"M120,40V16a8,8,0,0,1,16,0V40a8,8,0,0,1-16,0Zm72,88a64,64,0,1,1-64-64A64.07,64.07,0,0,1,192,128Zm-16,0a48,48,0,1,0-48,48A48.05,48.05,0,0,0,176,128ZM58.34,69.66A8,8,0,0,0,69.66,58.34l-16-16A8,8,0,0,0,42.34,53.66Zm0,116.68-16,16a8,8,0,0,0,11.32,11.32l16-16a8,8,0,0,0-11.32-11.32ZM192,72a8,8,0,0,0,5.66-2.34l16-16a8,8,0,0,0-11.32-11.32l-16,16A8,8,0,0,0,192,72Zm5.66,114.34a8,8,0,0,0-11.32,11.32l16,16a8,8,0,0,0,11.32-11.32ZM48,128a8,8,0,0,0-8-8H16a8,8,0,0,0,0,16H40A8,8,0,0,0,48,128Zm80,80a8,8,0,0,0-8,8v24a8,8,0,0,0,16,0V216A8,8,0,0,0,128,208Zm112-88H216a8,8,0,0,0,0,16h24a8,8,0,0,0,0-16Z"}))],["thin",a.createElement(a.Fragment,null,a.createElement("path",{d:"M124,40V16a4,4,0,0,1,8,0V40a4,4,0,0,1-8,0Zm64,88a60,60,0,1,1-60-60A60.07,60.07,0,0,1,188,128Zm-8,0a52,52,0,1,0-52,52A52.06,52.06,0,0,0,180,128ZM61.17,66.83a4,4,0,0,0,5.66-5.66l-16-16a4,4,0,0,0-5.66,5.66Zm0,122.34-16,16a4,4,0,0,0,5.66,5.66l16-16a4,4,0,0,0-5.66-5.66ZM192,68a4,4,0,0,0,2.83-1.17l16-16a4,4,0,1,0-5.66-5.66l-16,16A4,4,0,0,0,192,68Zm2.83,121.17a4,4,0,0,0-5.66,5.66l16,16a4,4,0,0,0,5.66-5.66ZM40,124H16a4,4,0,0,0,0,8H40a4,4,0,0,0,0-8Zm88,88a4,4,0,0,0-4,4v24a4,4,0,0,0,8,0V216A4,4,0,0,0,128,212Zm112-88H216a4,4,0,0,0,0,8h24a4,4,0,0,0,0-8Z"}))]]),A=a.forwardRef((s,l)=>a.createElement(h,{ref:l,...s,weights:H}));A.displayName="MoonIcon";const F=A,Z=a.forwardRef((s,l)=>a.createElement(h,{ref:l,...s,weights:b}));Z.displayName="PaletteIcon";const V=Z,g=a.forwardRef((s,l)=>a.createElement(h,{ref:l,...s,weights:T}));g.displayName="SunIcon";const C=g,P=()=>{const{theme:s,toggleTheme:l}=p(x=>x),n="focus-ring-soft surface-base group flex items-start justify-between gap-3.5 px-4 py-3.5 text-left text-fg-default outline-none transition-colors hover:bg-hover-subtle",r="inline-flex h-12 w-12 shrink-0 items-center justify-center rounded-[15px] border border-border-subtle bg-muted text-fg-secondary transition-colors group-hover:border-border-secondary/70 group-hover:text-fg-default",m="h-6 w-6",d="text-fg-tertiary",c="min-w-0 flex flex-col gap-0.5 pt-0.5";return e.jsx(M,{title:"Settings",description:"Manage appearance, integrations, and workspace tools",children:e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsxs("section",{className:"flex flex-col gap-3",children:[e.jsx(t,{as:"p",variant:"label",weight:"medium",className:d,children:"Appearance"}),e.jsxs("button",{type:"button",className:n,onClick:l,children:[e.jsxs("div",{className:"flex min-w-0 items-start gap-3",children:[e.jsx("span",{className:r,children:e.jsx(V,{className:m})}),e.jsxs("div",{className:c,children:[e.jsx(t,{as:"div",variant:"body",weight:"medium",children:"Theme"}),e.jsx(t,{as:"div",variant:"meta",tone:"secondary",children:"Switch between light and dark mode."})]})]}),e.jsxs("div",{className:"mt-0.5 flex shrink-0 items-center gap-2 text-fg-tertiary",children:[e.jsx(t,{as:"span",variant:"meta",weight:"medium",tone:"secondary",children:s==="dark"?"Dark":"Light"}),s==="dark"?e.jsx(F,{className:"h-4 w-4",weight:"fill"}):e.jsx(C,{className:"h-4 w-4",weight:"fill"})]})]})]}),e.jsxs("section",{className:"flex flex-col gap-3",children:[e.jsx(t,{as:"p",variant:"label",weight:"medium",className:d,children:"Integrations"}),e.jsxs(i,{to:f,className:n,children:[e.jsxs("div",{className:"flex min-w-0 items-start gap-3",children:[e.jsx("span",{className:r,children:e.jsx(N,{className:m})}),e.jsxs("div",{className:c,children:[e.jsx(t,{as:"div",variant:"body",weight:"medium",children:"MCP"}),e.jsx(t,{as:"div",variant:"meta",tone:"secondary",children:"Manage AI integration access."})]})]}),e.jsx(o,{className:"mt-0.5 h-4 w-4 shrink-0 text-fg-tertiary transition-transform group-hover:translate-x-0.5 group-hover:text-fg-secondary"})]})]}),e.jsxs("section",{className:"flex flex-col gap-3",children:[e.jsx(t,{as:"p",variant:"label",weight:"medium",className:d,children:"Workspace"}),e.jsxs("div",{className:"grid grid-cols-1 gap-3 md:grid-cols-2",children:[e.jsxs(i,{to:u,search:{page:1},className:n,children:[e.jsxs("div",{className:"flex min-w-0 items-start gap-3",children:[e.jsx("span",{className:r,children:e.jsx(w,{className:m})}),e.jsxs("div",{className:c,children:[e.jsx(t,{as:"div",variant:"body",weight:"medium",children:"Trash"}),e.jsx(t,{as:"div",variant:"meta",tone:"secondary",children:"Restore deleted notes."})]})]}),e.jsx(o,{className:"mt-0.5 h-4 w-4 shrink-0 text-fg-tertiary transition-transform group-hover:translate-x-0.5 group-hover:text-fg-secondary"})]}),e.jsxs(i,{to:j,search:{page:1},className:n,children:[e.jsxs("div",{className:"flex min-w-0 items-start gap-3",children:[e.jsx("span",{className:r,children:e.jsx(y,{className:m})}),e.jsxs("div",{className:c,children:[e.jsx(t,{as:"div",variant:"body",weight:"medium",children:"Images"}),e.jsx(t,{as:"div",variant:"meta",tone:"secondary",children:"Upload and organize images."})]})]}),e.jsx(o,{className:"mt-0.5 h-4 w-4 shrink-0 text-fg-tertiary transition-transform group-hover:translate-x-0.5 group-hover:text-fg-secondary"})]}),e.jsxs(i,{to:v,search:{page:1},className:n,children:[e.jsxs("div",{className:"flex min-w-0 items-start gap-3",children:[e.jsx("span",{className:r,children:e.jsx(E,{className:m})}),e.jsxs("div",{className:c,children:[e.jsx(t,{as:"div",variant:"body",weight:"medium",children:"Placeholders"}),e.jsx(t,{as:"div",variant:"meta",tone:"secondary",children:"Manage template variables."})]})]}),e.jsx(o,{className:"mt-0.5 h-4 w-4 shrink-0 text-fg-tertiary transition-transform group-hover:translate-x-0.5 group-hover:text-fg-secondary"})]})]})]})]})})};export{P as default};
|
|
1
|
+
import{j as e}from"./note-vendor-B0t5F04o.js";import{p as h,a4 as p,P as M,T as t,L as i,aw as f,g as o,ar as u,ax as j,ay as v,az as E}from"./index-B4l2UvuC.js";import{a}from"./graph-vendor-CUxe67Lr.js";import{c as N,n as w}from"./Trash.es-BqRTZPrI.js";import{I as y}from"./Image.es-COwqkQuh.js";import"./note-core-GgFcksAF.js";const H=new Map([["bold",a.createElement(a.Fragment,null,a.createElement("path",{d:"M236.37,139.4a12,12,0,0,0-12-3A84.07,84.07,0,0,1,119.6,31.59a12,12,0,0,0-15-15A108.86,108.86,0,0,0,49.69,55.07,108,108,0,0,0,136,228a107.09,107.09,0,0,0,64.93-21.69,108.86,108.86,0,0,0,38.44-54.94A12,12,0,0,0,236.37,139.4Zm-49.88,47.74A84,84,0,0,1,68.86,69.51,84.93,84.93,0,0,1,92.27,48.29Q92,52.13,92,56A108.12,108.12,0,0,0,200,164q3.87,0,7.71-.27A84.79,84.79,0,0,1,186.49,187.14Z"}))],["duotone",a.createElement(a.Fragment,null,a.createElement("path",{d:"M227.89,147.89A96,96,0,1,1,108.11,28.11,96.09,96.09,0,0,0,227.89,147.89Z",opacity:"0.2"}),a.createElement("path",{d:"M233.54,142.23a8,8,0,0,0-8-2,88.08,88.08,0,0,1-109.8-109.8,8,8,0,0,0-10-10,104.84,104.84,0,0,0-52.91,37A104,104,0,0,0,136,224a103.09,103.09,0,0,0,62.52-20.88,104.84,104.84,0,0,0,37-52.91A8,8,0,0,0,233.54,142.23ZM188.9,190.34A88,88,0,0,1,65.66,67.11a89,89,0,0,1,31.4-26A106,106,0,0,0,96,56,104.11,104.11,0,0,0,200,160a106,106,0,0,0,14.92-1.06A89,89,0,0,1,188.9,190.34Z"}))],["fill",a.createElement(a.Fragment,null,a.createElement("path",{d:"M235.54,150.21a104.84,104.84,0,0,1-37,52.91A104,104,0,0,1,32,120,103.09,103.09,0,0,1,52.88,57.48a104.84,104.84,0,0,1,52.91-37,8,8,0,0,1,10,10,88.08,88.08,0,0,0,109.8,109.8,8,8,0,0,1,10,10Z"}))],["light",a.createElement(a.Fragment,null,a.createElement("path",{d:"M232.13,143.64a6,6,0,0,0-6-1.49A90.07,90.07,0,0,1,113.86,29.85a6,6,0,0,0-7.49-7.48A102.88,102.88,0,0,0,54.48,58.68,102,102,0,0,0,197.32,201.52a102.88,102.88,0,0,0,36.31-51.89A6,6,0,0,0,232.13,143.64Zm-42,48.29a90,90,0,0,1-126-126A90.9,90.9,0,0,1,99.65,37.66,102.06,102.06,0,0,0,218.34,156.35,90.9,90.9,0,0,1,190.1,191.93Z"}))],["regular",a.createElement(a.Fragment,null,a.createElement("path",{d:"M233.54,142.23a8,8,0,0,0-8-2,88.08,88.08,0,0,1-109.8-109.8,8,8,0,0,0-10-10,104.84,104.84,0,0,0-52.91,37A104,104,0,0,0,136,224a103.09,103.09,0,0,0,62.52-20.88,104.84,104.84,0,0,0,37-52.91A8,8,0,0,0,233.54,142.23ZM188.9,190.34A88,88,0,0,1,65.66,67.11a89,89,0,0,1,31.4-26A106,106,0,0,0,96,56,104.11,104.11,0,0,0,200,160a106,106,0,0,0,14.92-1.06A89,89,0,0,1,188.9,190.34Z"}))],["thin",a.createElement(a.Fragment,null,a.createElement("path",{d:"M230.72,145.06a4,4,0,0,0-4-1A92.08,92.08,0,0,1,111.94,29.27a4,4,0,0,0-5-5A100.78,100.78,0,0,0,56.08,59.88a100,100,0,0,0,140,140,100.78,100.78,0,0,0,35.59-50.87A4,4,0,0,0,230.72,145.06ZM191.3,193.53A92,92,0,0,1,62.47,64.7a93,93,0,0,1,39.88-30.35,100.09,100.09,0,0,0,119.3,119.3A93,93,0,0,1,191.3,193.53Z"}))]]),b=new Map([["bold",a.createElement(a.Fragment,null,a.createElement("path",{d:"M203.57,51A107.9,107.9,0,0,0,20,128c0,44.72,27.6,82.25,72,97.94A36,36,0,0,0,140,192a12,12,0,0,1,12-12h46.21a35.79,35.79,0,0,0,35.1-28A108.6,108.6,0,0,0,236,127.09,107.23,107.23,0,0,0,203.57,51Zm6.34,95.67a11.91,11.91,0,0,1-11.7,9.3H152a36,36,0,0,0-36,36,12,12,0,0,1-16,11.3c-16.65-5.88-30.65-15.76-40.48-28.56A76,76,0,0,1,44,128a84,84,0,0,1,83.13-84H128a84.35,84.35,0,0,1,84,83.29A84.72,84.72,0,0,1,209.91,146.71ZM144,76a16,16,0,1,1-16-16A16,16,0,0,1,144,76Zm-44,24A16,16,0,1,1,84,84,16,16,0,0,1,100,100Zm0,56a16,16,0,1,1-16-16A16,16,0,0,1,100,156Zm88-56a16,16,0,1,1-16-16A16,16,0,0,1,188,100Z"}))],["duotone",a.createElement(a.Fragment,null,a.createElement("path",{d:"M224,127.17a96.48,96.48,0,0,1-2.39,22.18A24,24,0,0,1,198.21,168H152a24,24,0,0,0-24,24,24,24,0,0,1-32,22.61C58.73,201.44,32,169.81,32,128a96,96,0,0,1,95-96C179.84,31.47,223.55,74.35,224,127.17Z",opacity:"0.2"}),a.createElement("path",{d:"M200.77,53.89A103.27,103.27,0,0,0,128,24h-1.07A104,104,0,0,0,24,128c0,43,26.58,79.06,69.36,94.17A32,32,0,0,0,136,192a16,16,0,0,1,16-16h46.21a31.81,31.81,0,0,0,31.2-24.88,104.43,104.43,0,0,0,2.59-24A103.28,103.28,0,0,0,200.77,53.89Zm13,93.71A15.89,15.89,0,0,1,198.21,160H152a32,32,0,0,0-32,32,16,16,0,0,1-21.31,15.07C62.49,194.3,40,164,40,128a88,88,0,0,1,87.09-88h.9a88.35,88.35,0,0,1,88,87.25A88.86,88.86,0,0,1,213.81,147.6ZM140,76a12,12,0,1,1-12-12A12,12,0,0,1,140,76ZM96,100A12,12,0,1,1,84,88,12,12,0,0,1,96,100Zm0,56a12,12,0,1,1-12-12A12,12,0,0,1,96,156Zm88-56a12,12,0,1,1-12-12A12,12,0,0,1,184,100Z"}))],["fill",a.createElement(a.Fragment,null,a.createElement("path",{d:"M200.77,53.89A103.27,103.27,0,0,0,128,24h-1.07A104,104,0,0,0,24,128c0,43,26.58,79.06,69.36,94.17A32,32,0,0,0,136,192a16,16,0,0,1,16-16h46.21a31.81,31.81,0,0,0,31.2-24.88,104.43,104.43,0,0,0,2.59-24A103.28,103.28,0,0,0,200.77,53.89ZM84,168a12,12,0,1,1,12-12A12,12,0,0,1,84,168Zm0-56a12,12,0,1,1,12-12A12,12,0,0,1,84,112Zm44-24a12,12,0,1,1,12-12A12,12,0,0,1,128,88Zm44,24a12,12,0,1,1,12-12A12,12,0,0,1,172,112Z"}))],["light",a.createElement(a.Fragment,null,a.createElement("path",{d:"M199.37,55.31A101.32,101.32,0,0,0,128,26h-1A102,102,0,0,0,26,128c0,42.09,26.07,77.44,68,92.26A30.21,30.21,0,0,0,104.11,222,30.06,30.06,0,0,0,134,192a18,18,0,0,1,18-18h46.21a29.82,29.82,0,0,0,29.25-23.31A102.71,102.71,0,0,0,230,127.11,101.25,101.25,0,0,0,199.37,55.31ZM215.76,148a17.89,17.89,0,0,1-17.55,14H152a30,30,0,0,0-30,30,18,18,0,0,1-24,17C61,195.86,38,164.85,38,128a90,90,0,0,1,89.07-90H128a90.34,90.34,0,0,1,90,89.22A90.46,90.46,0,0,1,215.76,148ZM138,76a10,10,0,1,1-10-10A10,10,0,0,1,138,76ZM94,100A10,10,0,1,1,84,90,10,10,0,0,1,94,100Zm0,56a10,10,0,1,1-10-10A10,10,0,0,1,94,156Zm88-56a10,10,0,1,1-10-10A10,10,0,0,1,182,100Z"}))],["regular",a.createElement(a.Fragment,null,a.createElement("path",{d:"M200.77,53.89A103.27,103.27,0,0,0,128,24h-1.07A104,104,0,0,0,24,128c0,43,26.58,79.06,69.36,94.17A32,32,0,0,0,136,192a16,16,0,0,1,16-16h46.21a31.81,31.81,0,0,0,31.2-24.88,104.43,104.43,0,0,0,2.59-24A103.28,103.28,0,0,0,200.77,53.89Zm13,93.71A15.89,15.89,0,0,1,198.21,160H152a32,32,0,0,0-32,32,16,16,0,0,1-21.31,15.07C62.49,194.3,40,164,40,128a88,88,0,0,1,87.09-88h.9a88.35,88.35,0,0,1,88,87.25A88.86,88.86,0,0,1,213.81,147.6ZM140,76a12,12,0,1,1-12-12A12,12,0,0,1,140,76ZM96,100A12,12,0,1,1,84,88,12,12,0,0,1,96,100Zm0,56a12,12,0,1,1-12-12A12,12,0,0,1,96,156Zm88-56a12,12,0,1,1-12-12A12,12,0,0,1,184,100Z"}))],["thin",a.createElement(a.Fragment,null,a.createElement("path",{d:"M198,56.74A99.31,99.31,0,0,0,128,28h-1A100,100,0,0,0,28,128c0,41.22,25.55,75.85,66.69,90.38a28.34,28.34,0,0,0,9.42,1.63A28,28,0,0,0,132,192a20,20,0,0,1,20-20h46.21a27.84,27.84,0,0,0,27.3-21.76,100.37,100.37,0,0,0,2.49-23.1A99.26,99.26,0,0,0,198,56.74Zm19.74,91.72A19.89,19.89,0,0,1,198.21,164H152a28,28,0,0,0-28,28,20,20,0,0,1-26.64,18.83C59.51,197.46,36,165.72,36,128a92,92,0,0,1,91.05-92H128a92,92,0,0,1,89.72,112.46ZM136,76a8,8,0,1,1-8-8A8,8,0,0,1,136,76ZM92,100a8,8,0,1,1-8-8A8,8,0,0,1,92,100Zm0,56a8,8,0,1,1-8-8A8,8,0,0,1,92,156Zm88-56a8,8,0,1,1-8-8A8,8,0,0,1,180,100Z"}))]]),T=new Map([["bold",a.createElement(a.Fragment,null,a.createElement("path",{d:"M116,36V20a12,12,0,0,1,24,0V36a12,12,0,0,1-24,0Zm80,92a68,68,0,1,1-68-68A68.07,68.07,0,0,1,196,128Zm-24,0a44,44,0,1,0-44,44A44.05,44.05,0,0,0,172,128ZM51.51,68.49a12,12,0,1,0,17-17l-12-12a12,12,0,0,0-17,17Zm0,119-12,12a12,12,0,0,0,17,17l12-12a12,12,0,1,0-17-17ZM196,72a12,12,0,0,0,8.49-3.51l12-12a12,12,0,0,0-17-17l-12,12A12,12,0,0,0,196,72Zm8.49,115.51a12,12,0,0,0-17,17l12,12a12,12,0,0,0,17-17ZM48,128a12,12,0,0,0-12-12H20a12,12,0,0,0,0,24H36A12,12,0,0,0,48,128Zm80,80a12,12,0,0,0-12,12v16a12,12,0,0,0,24,0V220A12,12,0,0,0,128,208Zm108-92H220a12,12,0,0,0,0,24h16a12,12,0,0,0,0-24Z"}))],["duotone",a.createElement(a.Fragment,null,a.createElement("path",{d:"M184,128a56,56,0,1,1-56-56A56,56,0,0,1,184,128Z",opacity:"0.2"}),a.createElement("path",{d:"M120,40V16a8,8,0,0,1,16,0V40a8,8,0,0,1-16,0Zm72,88a64,64,0,1,1-64-64A64.07,64.07,0,0,1,192,128Zm-16,0a48,48,0,1,0-48,48A48.05,48.05,0,0,0,176,128ZM58.34,69.66A8,8,0,0,0,69.66,58.34l-16-16A8,8,0,0,0,42.34,53.66Zm0,116.68-16,16a8,8,0,0,0,11.32,11.32l16-16a8,8,0,0,0-11.32-11.32ZM192,72a8,8,0,0,0,5.66-2.34l16-16a8,8,0,0,0-11.32-11.32l-16,16A8,8,0,0,0,192,72Zm5.66,114.34a8,8,0,0,0-11.32,11.32l16,16a8,8,0,0,0,11.32-11.32ZM48,128a8,8,0,0,0-8-8H16a8,8,0,0,0,0,16H40A8,8,0,0,0,48,128Zm80,80a8,8,0,0,0-8,8v24a8,8,0,0,0,16,0V216A8,8,0,0,0,128,208Zm112-88H216a8,8,0,0,0,0,16h24a8,8,0,0,0,0-16Z"}))],["fill",a.createElement(a.Fragment,null,a.createElement("path",{d:"M120,40V16a8,8,0,0,1,16,0V40a8,8,0,0,1-16,0Zm8,24a64,64,0,1,0,64,64A64.07,64.07,0,0,0,128,64ZM58.34,69.66A8,8,0,0,0,69.66,58.34l-16-16A8,8,0,0,0,42.34,53.66Zm0,116.68-16,16a8,8,0,0,0,11.32,11.32l16-16a8,8,0,0,0-11.32-11.32ZM192,72a8,8,0,0,0,5.66-2.34l16-16a8,8,0,0,0-11.32-11.32l-16,16A8,8,0,0,0,192,72Zm5.66,114.34a8,8,0,0,0-11.32,11.32l16,16a8,8,0,0,0,11.32-11.32ZM48,128a8,8,0,0,0-8-8H16a8,8,0,0,0,0,16H40A8,8,0,0,0,48,128Zm80,80a8,8,0,0,0-8,8v24a8,8,0,0,0,16,0V216A8,8,0,0,0,128,208Zm112-88H216a8,8,0,0,0,0,16h24a8,8,0,0,0,0-16Z"}))],["light",a.createElement(a.Fragment,null,a.createElement("path",{d:"M122,40V16a6,6,0,0,1,12,0V40a6,6,0,0,1-12,0Zm68,88a62,62,0,1,1-62-62A62.07,62.07,0,0,1,190,128Zm-12,0a50,50,0,1,0-50,50A50.06,50.06,0,0,0,178,128ZM59.76,68.24a6,6,0,1,0,8.48-8.48l-16-16a6,6,0,0,0-8.48,8.48Zm0,119.52-16,16a6,6,0,1,0,8.48,8.48l16-16a6,6,0,1,0-8.48-8.48ZM192,70a6,6,0,0,0,4.24-1.76l16-16a6,6,0,0,0-8.48-8.48l-16,16A6,6,0,0,0,192,70Zm4.24,117.76a6,6,0,0,0-8.48,8.48l16,16a6,6,0,0,0,8.48-8.48ZM46,128a6,6,0,0,0-6-6H16a6,6,0,0,0,0,12H40A6,6,0,0,0,46,128Zm82,82a6,6,0,0,0-6,6v24a6,6,0,0,0,12,0V216A6,6,0,0,0,128,210Zm112-88H216a6,6,0,0,0,0,12h24a6,6,0,0,0,0-12Z"}))],["regular",a.createElement(a.Fragment,null,a.createElement("path",{d:"M120,40V16a8,8,0,0,1,16,0V40a8,8,0,0,1-16,0Zm72,88a64,64,0,1,1-64-64A64.07,64.07,0,0,1,192,128Zm-16,0a48,48,0,1,0-48,48A48.05,48.05,0,0,0,176,128ZM58.34,69.66A8,8,0,0,0,69.66,58.34l-16-16A8,8,0,0,0,42.34,53.66Zm0,116.68-16,16a8,8,0,0,0,11.32,11.32l16-16a8,8,0,0,0-11.32-11.32ZM192,72a8,8,0,0,0,5.66-2.34l16-16a8,8,0,0,0-11.32-11.32l-16,16A8,8,0,0,0,192,72Zm5.66,114.34a8,8,0,0,0-11.32,11.32l16,16a8,8,0,0,0,11.32-11.32ZM48,128a8,8,0,0,0-8-8H16a8,8,0,0,0,0,16H40A8,8,0,0,0,48,128Zm80,80a8,8,0,0,0-8,8v24a8,8,0,0,0,16,0V216A8,8,0,0,0,128,208Zm112-88H216a8,8,0,0,0,0,16h24a8,8,0,0,0,0-16Z"}))],["thin",a.createElement(a.Fragment,null,a.createElement("path",{d:"M124,40V16a4,4,0,0,1,8,0V40a4,4,0,0,1-8,0Zm64,88a60,60,0,1,1-60-60A60.07,60.07,0,0,1,188,128Zm-8,0a52,52,0,1,0-52,52A52.06,52.06,0,0,0,180,128ZM61.17,66.83a4,4,0,0,0,5.66-5.66l-16-16a4,4,0,0,0-5.66,5.66Zm0,122.34-16,16a4,4,0,0,0,5.66,5.66l16-16a4,4,0,0,0-5.66-5.66ZM192,68a4,4,0,0,0,2.83-1.17l16-16a4,4,0,1,0-5.66-5.66l-16,16A4,4,0,0,0,192,68Zm2.83,121.17a4,4,0,0,0-5.66,5.66l16,16a4,4,0,0,0,5.66-5.66ZM40,124H16a4,4,0,0,0,0,8H40a4,4,0,0,0,0-8Zm88,88a4,4,0,0,0-4,4v24a4,4,0,0,0,8,0V216A4,4,0,0,0,128,212Zm112-88H216a4,4,0,0,0,0,8h24a4,4,0,0,0,0-8Z"}))]]),A=a.forwardRef((s,l)=>a.createElement(h,{ref:l,...s,weights:H}));A.displayName="MoonIcon";const F=A,Z=a.forwardRef((s,l)=>a.createElement(h,{ref:l,...s,weights:b}));Z.displayName="PaletteIcon";const V=Z,g=a.forwardRef((s,l)=>a.createElement(h,{ref:l,...s,weights:T}));g.displayName="SunIcon";const C=g,P=()=>{const{theme:s,toggleTheme:l}=p(x=>x),n="focus-ring-soft surface-base group flex items-start justify-between gap-3.5 px-4 py-3.5 text-left text-fg-default outline-none transition-colors hover:bg-hover-subtle",r="inline-flex h-12 w-12 shrink-0 items-center justify-center rounded-[15px] border border-border-subtle bg-muted text-fg-secondary transition-colors group-hover:border-border-secondary/70 group-hover:text-fg-default",m="h-6 w-6",d="text-fg-tertiary",c="min-w-0 flex flex-col gap-0.5 pt-0.5";return e.jsx(M,{title:"Settings",description:"Manage appearance, integrations, and workspace tools",children:e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsxs("section",{className:"flex flex-col gap-3",children:[e.jsx(t,{as:"p",variant:"label",weight:"medium",className:d,children:"Appearance"}),e.jsxs("button",{type:"button",className:n,onClick:l,children:[e.jsxs("div",{className:"flex min-w-0 items-start gap-3",children:[e.jsx("span",{className:r,children:e.jsx(V,{className:m})}),e.jsxs("div",{className:c,children:[e.jsx(t,{as:"div",variant:"body",weight:"medium",children:"Theme"}),e.jsx(t,{as:"div",variant:"meta",tone:"secondary",children:"Switch between light and dark mode."})]})]}),e.jsxs("div",{className:"mt-0.5 flex shrink-0 items-center gap-2 text-fg-tertiary",children:[e.jsx(t,{as:"span",variant:"meta",weight:"medium",tone:"secondary",children:s==="dark"?"Dark":"Light"}),s==="dark"?e.jsx(F,{className:"h-4 w-4",weight:"fill"}):e.jsx(C,{className:"h-4 w-4",weight:"fill"})]})]})]}),e.jsxs("section",{className:"flex flex-col gap-3",children:[e.jsx(t,{as:"p",variant:"label",weight:"medium",className:d,children:"Integrations"}),e.jsxs(i,{to:f,className:n,children:[e.jsxs("div",{className:"flex min-w-0 items-start gap-3",children:[e.jsx("span",{className:r,children:e.jsx(N,{className:m})}),e.jsxs("div",{className:c,children:[e.jsx(t,{as:"div",variant:"body",weight:"medium",children:"MCP"}),e.jsx(t,{as:"div",variant:"meta",tone:"secondary",children:"Manage AI integration access."})]})]}),e.jsx(o,{className:"mt-0.5 h-4 w-4 shrink-0 text-fg-tertiary transition-transform group-hover:translate-x-0.5 group-hover:text-fg-secondary"})]})]}),e.jsxs("section",{className:"flex flex-col gap-3",children:[e.jsx(t,{as:"p",variant:"label",weight:"medium",className:d,children:"Workspace"}),e.jsxs("div",{className:"grid grid-cols-1 gap-3 md:grid-cols-2",children:[e.jsxs(i,{to:u,search:{page:1},className:n,children:[e.jsxs("div",{className:"flex min-w-0 items-start gap-3",children:[e.jsx("span",{className:r,children:e.jsx(w,{className:m})}),e.jsxs("div",{className:c,children:[e.jsx(t,{as:"div",variant:"body",weight:"medium",children:"Trash"}),e.jsx(t,{as:"div",variant:"meta",tone:"secondary",children:"Restore deleted notes."})]})]}),e.jsx(o,{className:"mt-0.5 h-4 w-4 shrink-0 text-fg-tertiary transition-transform group-hover:translate-x-0.5 group-hover:text-fg-secondary"})]}),e.jsxs(i,{to:j,search:{page:1},className:n,children:[e.jsxs("div",{className:"flex min-w-0 items-start gap-3",children:[e.jsx("span",{className:r,children:e.jsx(y,{className:m})}),e.jsxs("div",{className:c,children:[e.jsx(t,{as:"div",variant:"body",weight:"medium",children:"Images"}),e.jsx(t,{as:"div",variant:"meta",tone:"secondary",children:"Upload and organize images."})]})]}),e.jsx(o,{className:"mt-0.5 h-4 w-4 shrink-0 text-fg-tertiary transition-transform group-hover:translate-x-0.5 group-hover:text-fg-secondary"})]}),e.jsxs(i,{to:v,search:{page:1},className:n,children:[e.jsxs("div",{className:"flex min-w-0 items-start gap-3",children:[e.jsx("span",{className:r,children:e.jsx(E,{className:m})}),e.jsxs("div",{className:c,children:[e.jsx(t,{as:"div",variant:"body",weight:"medium",children:"Placeholders"}),e.jsx(t,{as:"div",variant:"meta",tone:"secondary",children:"Manage template variables."})]})]}),e.jsx(o,{className:"mt-0.5 h-4 w-4 shrink-0 text-fg-tertiary transition-transform group-hover:translate-x-0.5 group-hover:text-fg-secondary"})]})]})]})]})})};export{P as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./note-vendor-B0t5F04o.js";import{a5 as v,q as x,v as w,w as E,aa as b,af as A,$ as T,P as o,F as _,L as G,aH as M,T as R,B as S,a0 as P,i as l,j as k,ax as q}from"./index-
|
|
1
|
+
import{j as e}from"./note-vendor-B0t5F04o.js";import{a5 as v,q as x,v as w,w as E,aa as b,af as A,$ as T,P as o,F as _,L as G,aH as M,T as R,B as S,a0 as P,i as l,j as k,ax as q}from"./index-B4l2UvuC.js";import{f as D,d as L}from"./image.api-CMdQbCyN.js";import"./graph-vendor-CUxe67Lr.js";import{I as C}from"./Image-DlJ4MDo3.js";import{S as f}from"./SurfaceCard-CHjcCuqZ.js";import{c as F,n as H}from"./Trash.es-BqRTZPrI.js";import"./note-core-GgFcksAF.js";const K=r=>{const{data:d}=v({queryKey:x.images.list(r.searchParams),async queryFn(){const i=await D({offset:r.searchParams.offset,limit:r.searchParams.limit});if(i.type==="error")throw i;return i.allImages}});return r.render(d)},Q=240,W=20,B=4,m=192,g=k(q),Z=()=>{const r=w(),d=E(),i=g.useNavigate(),{page:c}=g.useSearch(),{containerRef:p,limit:n}=b({minItemWidth:Q,gap:W,rows:B}),j=A({mutationFn:L,onSuccess:s=>{if(s.type==="error")throw s;d.invalidateQueries({queryKey:x.images.listAll(),exact:!1})}}),y=async s=>{await r("Delete this image? It is not referenced by any notes.")&&j.mutate(s)},I=s=>s===1?"1 reference":`${s} references`;return e.jsx("div",{ref:p,children:e.jsx(T,{fallback:e.jsx(o,{title:"Images",variant:"default",heading:e.jsx(l,{width:136,height:24,className:"rounded-full"}),description:e.jsx(l,{width:232,height:16,className:"rounded-full"}),children:e.jsx("div",{className:"flex flex-col gap-4",children:e.jsx("div",{className:"grid-auto-cards grid gap-4",children:Array.from({length:3},(s,t)=>e.jsxs(f,{flush:!0,children:[e.jsx("div",{className:"flex items-center justify-center bg-muted/25 p-3",style:{height:m},children:e.jsx(l,{width:"100%",height:m-24,className:"rounded-[12px]"})}),e.jsxs("div",{className:"flex items-center justify-between gap-3 border-t border-border-subtle px-3 py-2.5",children:[e.jsx(l,{width:92,height:14,className:"rounded-full"}),e.jsx(l,{width:32,height:32,className:"rounded-[12px]"})]})]},t))})})}),errorTitle:"Failed to load images",errorDescription:"Retry loading uploaded image metadata",resetKeys:[c,n],children:e.jsx(K,{searchParams:{offset:(c-1)*n,limit:n},render:({images:s,totalCount:t})=>{const u=t>0?`Images (${t})`:void 0,h="Review and manage the images you uploaded inside notes";return s.length===0?e.jsx(o,{title:"Images",variant:"default",heading:u,description:h,children:e.jsx(_,{title:"There are no images",description:"Upload an image in any note and it will appear here"})}):e.jsx(o,{title:"Images",variant:"default",heading:u,description:h,children:e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx("div",{className:"grid-auto-cards grid gap-4",children:s.map(a=>e.jsxs(f,{flush:!0,children:[e.jsx(G,{to:M,params:{id:a.id},className:"focus-ring-soft block overflow-hidden rounded-t-[18px] outline-none",children:e.jsx("div",{className:"flex items-center justify-center bg-muted/25 p-3",style:{height:m},children:e.jsx(C,{className:"h-full w-full rounded-[12px] object-contain transition-transform duration-200 hover:scale-[1.02]",src:a.url,alt:a.id})})}),e.jsxs("div",{className:"flex items-center justify-between gap-3 border-t border-border-subtle px-3 py-2.5",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-2 text-fg-secondary",children:[e.jsx(F,{className:"h-3.5 w-3.5 shrink-0 text-fg-tertiary"}),e.jsx(R,{as:"span",variant:"meta",weight:"medium",tone:"secondary",className:"truncate",children:I(a.referenceCount)})]}),e.jsx(S,{variant:"ghost",size:"icon-sm",disabled:a.referenceCount>0,onClick:()=>y(a.id),children:e.jsx(H,{className:"h-4 w-4"})})]})]},a.id))}),t&&n<t&&e.jsx(P,{page:c,last:Math.ceil(t/n),onChange:a=>{i({search:N=>({...N,page:a})})}})]})})}})})})};export{Z as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./note-vendor-B0t5F04o.js";import{p as F,T as r,t as k,L as p,N as R,ac as _,aI as Z,ax as E,f as q,$ as B,j as L,aH as G,v as H,w as z,a5 as b,q as x,aJ as K,af as v,aK as O,aL as P,B as w,i as l,W as Q}from"./index-46ZUXbW5.js";import{a as U,d as $}from"./image.api-D3Ei3fbf.js";import{a as t}from"./graph-vendor-CUxe67Lr.js";import{I as W}from"./Image-DlJ4MDo3.js";import{S as g}from"./SurfaceCard-WSk7zWeM.js";import{c as J,n as V}from"./Trash.es-DumPfiUz.js";import{I as X}from"./Image.es-C8g5NwNt.js";import"./note-core-GgFcksAF.js";const Y=new Map([["bold",t.createElement(t.Fragment,null,t.createElement("path",{d:"M178,36c-20.09,0-37.92,7.93-50,21.56C115.92,43.93,98.09,36,78,36a66.08,66.08,0,0,0-66,66c0,72.34,105.81,130.14,110.31,132.57a12,12,0,0,0,11.38,0C138.19,232.14,244,174.34,244,102A66.08,66.08,0,0,0,178,36Zm-5.49,142.36A328.69,328.69,0,0,1,128,210.16a328.69,328.69,0,0,1-44.51-31.8C61.82,159.77,36,131.42,36,102A42,42,0,0,1,78,60c17.8,0,32.7,9.4,38.89,24.54a12,12,0,0,0,22.22,0C145.3,69.4,160.2,60,178,60a42,42,0,0,1,42,42C220,131.42,194.18,159.77,172.51,178.36Z"}))],["duotone",t.createElement(t.Fragment,null,t.createElement("path",{d:"M232,102c0,66-104,122-104,122S24,168,24,102A54,54,0,0,1,78,48c22.59,0,41.94,12.31,50,32,8.06-19.69,27.41-32,50-32A54,54,0,0,1,232,102Z",opacity:"0.2"}),t.createElement("path",{d:"M178,40c-20.65,0-38.73,8.88-50,23.89C116.73,48.88,98.65,40,78,40a62.07,62.07,0,0,0-62,62c0,70,103.79,126.66,108.21,129a8,8,0,0,0,7.58,0C136.21,228.66,240,172,240,102A62.07,62.07,0,0,0,178,40ZM128,214.8C109.74,204.16,32,155.69,32,102A46.06,46.06,0,0,1,78,56c19.45,0,35.78,10.36,42.6,27a8,8,0,0,0,14.8,0c6.82-16.67,23.15-27,42.6-27a46.06,46.06,0,0,1,46,46C224,155.61,146.24,204.15,128,214.8Z"}))],["fill",t.createElement(t.Fragment,null,t.createElement("path",{d:"M240,102c0,70-103.79,126.66-108.21,129a8,8,0,0,1-7.58,0C119.79,228.66,16,172,16,102A62.07,62.07,0,0,1,78,40c20.65,0,38.73,8.88,50,23.89C139.27,48.88,157.35,40,178,40A62.07,62.07,0,0,1,240,102Z"}))],["light",t.createElement(t.Fragment,null,t.createElement("path",{d:"M178,42c-21,0-39.26,9.47-50,25.34C117.26,51.47,99,42,78,42a60.07,60.07,0,0,0-60,60c0,29.2,18.2,59.59,54.1,90.31a334.68,334.68,0,0,0,53.06,37,6,6,0,0,0,5.68,0,334.68,334.68,0,0,0,53.06-37C219.8,161.59,238,131.2,238,102A60.07,60.07,0,0,0,178,42ZM128,217.11C111.59,207.64,30,157.72,30,102A48.05,48.05,0,0,1,78,54c20.28,0,37.31,10.83,44.45,28.27a6,6,0,0,0,11.1,0C140.69,64.83,157.72,54,178,54a48.05,48.05,0,0,1,48,48C226,157.72,144.41,207.64,128,217.11Z"}))],["regular",t.createElement(t.Fragment,null,t.createElement("path",{d:"M178,40c-20.65,0-38.73,8.88-50,23.89C116.73,48.88,98.65,40,78,40a62.07,62.07,0,0,0-62,62c0,70,103.79,126.66,108.21,129a8,8,0,0,0,7.58,0C136.21,228.66,240,172,240,102A62.07,62.07,0,0,0,178,40ZM128,214.8C109.74,204.16,32,155.69,32,102A46.06,46.06,0,0,1,78,56c19.45,0,35.78,10.36,42.6,27a8,8,0,0,0,14.8,0c6.82-16.67,23.15-27,42.6-27a46.06,46.06,0,0,1,46,46C224,155.61,146.24,204.15,128,214.8Z"}))],["thin",t.createElement(t.Fragment,null,t.createElement("path",{d:"M178,44c-21.44,0-39.92,10.19-50,27.07C117.92,54.19,99.44,44,78,44a58.07,58.07,0,0,0-58,58c0,28.59,18,58.47,53.4,88.79a333.81,333.81,0,0,0,52.7,36.73,4,4,0,0,0,3.8,0,333.81,333.81,0,0,0,52.7-36.73C218,160.47,236,130.59,236,102A58.07,58.07,0,0,0,178,44ZM128,219.42c-14-8-100-59.35-100-117.42A50.06,50.06,0,0,1,78,52c21.11,0,38.85,11.31,46.3,29.51a4,4,0,0,0,7.4,0C139.15,63.31,156.89,52,178,52a50.06,50.06,0,0,1,50,50C228,160,142,211.46,128,219.42Z"}))]]),A=t.forwardRef((a,n)=>t.createElement(F,{ref:n,...a,weights:Y}));A.displayName="HeartIcon";const ee=A;function ae({name:a}){return e.jsx(r,{as:"div",variant:"label",weight:"medium",tone:"secondary",className:"inline-flex items-center rounded-full border border-border-subtle bg-hover-subtle px-2.5 py-1",children:a})}function se({id:a,title:n,tags:i,createdAt:u,updatedAt:d}){const o=new Date(Number(u)),m=k(Number(d));return e.jsx("div",{className:"border-b-2 border-dashed border-border-subtle last:border-b-0",children:e.jsxs("div",{className:"py-4 flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(r,{variant:"label",weight:"medium",tone:"tertiary",children:m}),e.jsxs(r,{variant:"label",tone:"placeholder",children:["(",o.toDateString(),")"]})]}),e.jsx(r,{as:"div",variant:"body",weight:"bold",tracking:"tight",children:e.jsx(p,{className:"transition-colors hover:text-accent-primary",to:R,params:{id:a},children:n||"Untitled"})}),i&&i.length>0&&e.jsx("div",{className:"flex flex-wrap gap-1.5",children:i.map(c=>e.jsx(p,{to:_,params:{id:c.id},search:{page:1},children:e.jsx(ae,{name:c.name})},c.id))})]})})}const I=L(G),j=352,te="mb-4 inline-flex items-center gap-1 text-fg-secondary transition-colors hover:text-fg-default",T="flex items-center justify-center bg-muted/25 p-3",re="h-full w-full rounded-[12px] object-contain",M="mb-3 flex flex-wrap items-start justify-between gap-3 border-b border-border-subtle pb-3",S="space-y-1",ne=a=>a===1?"1 reference":`${a} references`,C=(a,n)=>typeof a=="object"&&a!==null&&"errors"in a&&Array.isArray(a.errors)&&typeof a.errors[0]?.message=="string"?a.errors[0].message:a instanceof Error&&a.message?a.message:n,ie=()=>e.jsxs("div",{className:"flex flex-col gap-6 lg:flex-row",children:[e.jsx("div",{className:"w-full lg:w-[400px] lg:flex-shrink-0",children:e.jsxs(g,{flush:!0,children:[e.jsx("div",{className:T,style:{height:j},children:e.jsx(l,{width:"100%",height:j-24,className:"rounded-[12px]"})}),e.jsxs("div",{className:"flex flex-col gap-4 border-t border-border-subtle p-4",children:[e.jsx(l,{width:96,height:14,className:"rounded-full"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(l,{height:32,className:"flex-1 rounded-[12px]"}),e.jsx(l,{height:32,className:"flex-1 rounded-[12px]"})]})]})]})}),e.jsx("div",{className:"flex-1 min-w-0",children:e.jsxs(g,{children:[e.jsxs("div",{className:M,children:[e.jsxs("div",{className:S,children:[e.jsx(l,{width:140,height:18}),e.jsx(l,{width:220,height:14,className:"rounded-full"})]}),e.jsx(l,{width:84,height:14,className:"rounded-full"})]}),e.jsx("div",{className:"flex flex-col gap-3",children:Array.from({length:3},(a,n)=>e.jsx(l,{height:72,className:"rounded-[16px]"},n))})]})})]}),le=({id:a})=>{const n=H(),i=Q(),u=I.useNavigate(),d=z(),{data:o}=b({queryKey:x.images.detail(a),queryFn:async()=>{const s=await U(a);if(s.type==="error")throw s;return s.image}}),{data:m}=b({queryKey:x.images.notes(a),queryFn:async()=>{const s=await K(o.url);if(s.type==="error")throw s;return s.imageNotes}}),c=m.length,y=ne(c),h=c===0,f=v({mutationFn:async()=>{const s=await $(a);if(s.type==="error")throw s;if(!s.deleteImage)throw new Error("Failed to delete image");return s.deleteImage},onSuccess:async()=>{await d.invalidateQueries({queryKey:x.images.listAll(),exact:!1}),i("Image deleted"),u({to:E,search:{page:1}})},onError:s=>{i(C(s,"Failed to delete image"))}}),N=v({mutationFn:async()=>{const s=await O("heroBanner",o.url);if(s.type==="error")throw s},onSuccess:async()=>{await d.invalidateQueries({queryKey:x.ui.heroBanner(),exact:!0}),i("Hero banner updated")},onError:s=>{i(C(s,"Failed to update hero banner"))}}),D=async()=>{!h||f.isPending||await n("Delete this image? It is not referenced by any notes.")&&f.mutate()};return e.jsxs("div",{className:"flex flex-col gap-6 lg:flex-row",children:[e.jsx("div",{className:"w-full lg:w-[400px] lg:flex-shrink-0",children:e.jsxs(g,{flush:!0,children:[e.jsx("div",{className:T,style:{height:j},children:e.jsx(W,{className:re,src:o.url,alt:`Image ${o.id}`})}),e.jsxs("div",{className:"flex flex-col gap-4 border-t border-border-subtle p-4",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(J,{size:14,className:"text-fg-tertiary"}),e.jsx(r,{as:"span",variant:"meta",weight:"medium",tone:"secondary",children:y})]}),e.jsx(r,{as:"p",variant:"meta",tone:"tertiary",children:h?"Delete is available because no notes reference this image":"Remove this image from notes before deleting it"})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(P,{content:h?"Delete this image":"Cannot delete while referenced by notes",side:"bottom",children:e.jsxs(w,{variant:"soft-danger",size:"sm",className:"flex-1",disabled:!h,isLoading:f.isPending,onClick:D,children:[e.jsx(V,{size:16}),"Delete"]})}),e.jsxs(w,{variant:"primary",size:"sm",className:"flex-1",isLoading:N.isPending,onClick:()=>N.mutate(),children:[e.jsx(ee,{size:16}),"Set hero banner"]})]})]})]})}),e.jsx("div",{className:"flex-1 min-w-0",children:e.jsxs(g,{children:[e.jsxs("div",{className:M,children:[e.jsxs("div",{className:S,children:[e.jsx(r,{as:"h2",variant:"subheading",weight:"medium",tracking:"tight",children:"Referenced Notes"}),e.jsx(r,{as:"p",variant:"meta",tone:"secondary",children:"Notes currently using this image"})]}),e.jsx(r,{as:"span",variant:"meta",weight:"medium",tone:"secondary",children:y})]}),c>0?e.jsx("ul",{className:"flex flex-col",children:m.map(s=>e.jsx("li",{children:e.jsx(se,{...s})},s.id))}):e.jsxs("div",{className:"flex items-start gap-3 py-1",children:[e.jsx("div",{className:"mt-0.5 flex h-8 w-8 shrink-0 items-center justify-center rounded-[10px] bg-muted/25 text-fg-disabled",children:e.jsx(X,{size:18})}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(r,{as:"p",variant:"body",weight:"medium",tone:"secondary",children:"No notes reference this image"}),e.jsx(r,{as:"p",variant:"meta",tone:"secondary",children:"This image can be deleted or reused in another note"})]})]})]})})]})},pe=()=>{const{id:a}=I.useParams();return e.jsxs(e.Fragment,{children:[e.jsx(Z,{children:e.jsx("title",{children:"Image Detail | Ocean Brain"})}),e.jsxs(p,{to:E,search:{page:1},className:te,children:[e.jsx(q,{size:16}),e.jsx(r,{as:"span",variant:"meta",weight:"medium",className:"text-current",children:"Back to Images"})]}),e.jsx(r,{as:"h1",variant:"heading",weight:"bold",tracking:"tighter",className:"sr-only",children:"Image Detail"}),e.jsx(B,{fallback:e.jsx(ie,{}),errorTitle:"Failed to load image detail",errorDescription:"Retry loading the image preview and its referenced notes",resetKeys:[a],children:e.jsx(le,{id:a})})]})};export{pe as default};
|
|
1
|
+
import{j as e}from"./note-vendor-B0t5F04o.js";import{p as F,T as r,t as k,L as p,N as R,ac as _,aI as Z,ax as E,f as q,$ as B,j as L,aH as G,v as H,w as z,a5 as b,q as x,aJ as K,af as v,aK as O,aL as P,B as w,i as l,W as Q}from"./index-B4l2UvuC.js";import{a as U,d as $}from"./image.api-CMdQbCyN.js";import{a as t}from"./graph-vendor-CUxe67Lr.js";import{I as W}from"./Image-DlJ4MDo3.js";import{S as g}from"./SurfaceCard-CHjcCuqZ.js";import{c as J,n as V}from"./Trash.es-BqRTZPrI.js";import{I as X}from"./Image.es-COwqkQuh.js";import"./note-core-GgFcksAF.js";const Y=new Map([["bold",t.createElement(t.Fragment,null,t.createElement("path",{d:"M178,36c-20.09,0-37.92,7.93-50,21.56C115.92,43.93,98.09,36,78,36a66.08,66.08,0,0,0-66,66c0,72.34,105.81,130.14,110.31,132.57a12,12,0,0,0,11.38,0C138.19,232.14,244,174.34,244,102A66.08,66.08,0,0,0,178,36Zm-5.49,142.36A328.69,328.69,0,0,1,128,210.16a328.69,328.69,0,0,1-44.51-31.8C61.82,159.77,36,131.42,36,102A42,42,0,0,1,78,60c17.8,0,32.7,9.4,38.89,24.54a12,12,0,0,0,22.22,0C145.3,69.4,160.2,60,178,60a42,42,0,0,1,42,42C220,131.42,194.18,159.77,172.51,178.36Z"}))],["duotone",t.createElement(t.Fragment,null,t.createElement("path",{d:"M232,102c0,66-104,122-104,122S24,168,24,102A54,54,0,0,1,78,48c22.59,0,41.94,12.31,50,32,8.06-19.69,27.41-32,50-32A54,54,0,0,1,232,102Z",opacity:"0.2"}),t.createElement("path",{d:"M178,40c-20.65,0-38.73,8.88-50,23.89C116.73,48.88,98.65,40,78,40a62.07,62.07,0,0,0-62,62c0,70,103.79,126.66,108.21,129a8,8,0,0,0,7.58,0C136.21,228.66,240,172,240,102A62.07,62.07,0,0,0,178,40ZM128,214.8C109.74,204.16,32,155.69,32,102A46.06,46.06,0,0,1,78,56c19.45,0,35.78,10.36,42.6,27a8,8,0,0,0,14.8,0c6.82-16.67,23.15-27,42.6-27a46.06,46.06,0,0,1,46,46C224,155.61,146.24,204.15,128,214.8Z"}))],["fill",t.createElement(t.Fragment,null,t.createElement("path",{d:"M240,102c0,70-103.79,126.66-108.21,129a8,8,0,0,1-7.58,0C119.79,228.66,16,172,16,102A62.07,62.07,0,0,1,78,40c20.65,0,38.73,8.88,50,23.89C139.27,48.88,157.35,40,178,40A62.07,62.07,0,0,1,240,102Z"}))],["light",t.createElement(t.Fragment,null,t.createElement("path",{d:"M178,42c-21,0-39.26,9.47-50,25.34C117.26,51.47,99,42,78,42a60.07,60.07,0,0,0-60,60c0,29.2,18.2,59.59,54.1,90.31a334.68,334.68,0,0,0,53.06,37,6,6,0,0,0,5.68,0,334.68,334.68,0,0,0,53.06-37C219.8,161.59,238,131.2,238,102A60.07,60.07,0,0,0,178,42ZM128,217.11C111.59,207.64,30,157.72,30,102A48.05,48.05,0,0,1,78,54c20.28,0,37.31,10.83,44.45,28.27a6,6,0,0,0,11.1,0C140.69,64.83,157.72,54,178,54a48.05,48.05,0,0,1,48,48C226,157.72,144.41,207.64,128,217.11Z"}))],["regular",t.createElement(t.Fragment,null,t.createElement("path",{d:"M178,40c-20.65,0-38.73,8.88-50,23.89C116.73,48.88,98.65,40,78,40a62.07,62.07,0,0,0-62,62c0,70,103.79,126.66,108.21,129a8,8,0,0,0,7.58,0C136.21,228.66,240,172,240,102A62.07,62.07,0,0,0,178,40ZM128,214.8C109.74,204.16,32,155.69,32,102A46.06,46.06,0,0,1,78,56c19.45,0,35.78,10.36,42.6,27a8,8,0,0,0,14.8,0c6.82-16.67,23.15-27,42.6-27a46.06,46.06,0,0,1,46,46C224,155.61,146.24,204.15,128,214.8Z"}))],["thin",t.createElement(t.Fragment,null,t.createElement("path",{d:"M178,44c-21.44,0-39.92,10.19-50,27.07C117.92,54.19,99.44,44,78,44a58.07,58.07,0,0,0-58,58c0,28.59,18,58.47,53.4,88.79a333.81,333.81,0,0,0,52.7,36.73,4,4,0,0,0,3.8,0,333.81,333.81,0,0,0,52.7-36.73C218,160.47,236,130.59,236,102A58.07,58.07,0,0,0,178,44ZM128,219.42c-14-8-100-59.35-100-117.42A50.06,50.06,0,0,1,78,52c21.11,0,38.85,11.31,46.3,29.51a4,4,0,0,0,7.4,0C139.15,63.31,156.89,52,178,52a50.06,50.06,0,0,1,50,50C228,160,142,211.46,128,219.42Z"}))]]),A=t.forwardRef((a,n)=>t.createElement(F,{ref:n,...a,weights:Y}));A.displayName="HeartIcon";const ee=A;function ae({name:a}){return e.jsx(r,{as:"div",variant:"label",weight:"medium",tone:"secondary",className:"inline-flex items-center rounded-full border border-border-subtle bg-hover-subtle px-2.5 py-1",children:a})}function se({id:a,title:n,tags:i,createdAt:u,updatedAt:d}){const o=new Date(Number(u)),m=k(Number(d));return e.jsx("div",{className:"border-b-2 border-dashed border-border-subtle last:border-b-0",children:e.jsxs("div",{className:"py-4 flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(r,{variant:"label",weight:"medium",tone:"tertiary",children:m}),e.jsxs(r,{variant:"label",tone:"placeholder",children:["(",o.toDateString(),")"]})]}),e.jsx(r,{as:"div",variant:"body",weight:"bold",tracking:"tight",children:e.jsx(p,{className:"transition-colors hover:text-accent-primary",to:R,params:{id:a},children:n||"Untitled"})}),i&&i.length>0&&e.jsx("div",{className:"flex flex-wrap gap-1.5",children:i.map(c=>e.jsx(p,{to:_,params:{id:c.id},search:{page:1},children:e.jsx(ae,{name:c.name})},c.id))})]})})}const I=L(G),j=352,te="mb-4 inline-flex items-center gap-1 text-fg-secondary transition-colors hover:text-fg-default",T="flex items-center justify-center bg-muted/25 p-3",re="h-full w-full rounded-[12px] object-contain",M="mb-3 flex flex-wrap items-start justify-between gap-3 border-b border-border-subtle pb-3",S="space-y-1",ne=a=>a===1?"1 reference":`${a} references`,C=(a,n)=>typeof a=="object"&&a!==null&&"errors"in a&&Array.isArray(a.errors)&&typeof a.errors[0]?.message=="string"?a.errors[0].message:a instanceof Error&&a.message?a.message:n,ie=()=>e.jsxs("div",{className:"flex flex-col gap-6 lg:flex-row",children:[e.jsx("div",{className:"w-full lg:w-[400px] lg:flex-shrink-0",children:e.jsxs(g,{flush:!0,children:[e.jsx("div",{className:T,style:{height:j},children:e.jsx(l,{width:"100%",height:j-24,className:"rounded-[12px]"})}),e.jsxs("div",{className:"flex flex-col gap-4 border-t border-border-subtle p-4",children:[e.jsx(l,{width:96,height:14,className:"rounded-full"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(l,{height:32,className:"flex-1 rounded-[12px]"}),e.jsx(l,{height:32,className:"flex-1 rounded-[12px]"})]})]})]})}),e.jsx("div",{className:"flex-1 min-w-0",children:e.jsxs(g,{children:[e.jsxs("div",{className:M,children:[e.jsxs("div",{className:S,children:[e.jsx(l,{width:140,height:18}),e.jsx(l,{width:220,height:14,className:"rounded-full"})]}),e.jsx(l,{width:84,height:14,className:"rounded-full"})]}),e.jsx("div",{className:"flex flex-col gap-3",children:Array.from({length:3},(a,n)=>e.jsx(l,{height:72,className:"rounded-[16px]"},n))})]})})]}),le=({id:a})=>{const n=H(),i=Q(),u=I.useNavigate(),d=z(),{data:o}=b({queryKey:x.images.detail(a),queryFn:async()=>{const s=await U(a);if(s.type==="error")throw s;return s.image}}),{data:m}=b({queryKey:x.images.notes(a),queryFn:async()=>{const s=await K(o.url);if(s.type==="error")throw s;return s.imageNotes}}),c=m.length,y=ne(c),h=c===0,f=v({mutationFn:async()=>{const s=await $(a);if(s.type==="error")throw s;if(!s.deleteImage)throw new Error("Failed to delete image");return s.deleteImage},onSuccess:async()=>{await d.invalidateQueries({queryKey:x.images.listAll(),exact:!1}),i("Image deleted"),u({to:E,search:{page:1}})},onError:s=>{i(C(s,"Failed to delete image"))}}),N=v({mutationFn:async()=>{const s=await O("heroBanner",o.url);if(s.type==="error")throw s},onSuccess:async()=>{await d.invalidateQueries({queryKey:x.ui.heroBanner(),exact:!0}),i("Hero banner updated")},onError:s=>{i(C(s,"Failed to update hero banner"))}}),D=async()=>{!h||f.isPending||await n("Delete this image? It is not referenced by any notes.")&&f.mutate()};return e.jsxs("div",{className:"flex flex-col gap-6 lg:flex-row",children:[e.jsx("div",{className:"w-full lg:w-[400px] lg:flex-shrink-0",children:e.jsxs(g,{flush:!0,children:[e.jsx("div",{className:T,style:{height:j},children:e.jsx(W,{className:re,src:o.url,alt:`Image ${o.id}`})}),e.jsxs("div",{className:"flex flex-col gap-4 border-t border-border-subtle p-4",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(J,{size:14,className:"text-fg-tertiary"}),e.jsx(r,{as:"span",variant:"meta",weight:"medium",tone:"secondary",children:y})]}),e.jsx(r,{as:"p",variant:"meta",tone:"tertiary",children:h?"Delete is available because no notes reference this image":"Remove this image from notes before deleting it"})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(P,{content:h?"Delete this image":"Cannot delete while referenced by notes",side:"bottom",children:e.jsxs(w,{variant:"soft-danger",size:"sm",className:"flex-1",disabled:!h,isLoading:f.isPending,onClick:D,children:[e.jsx(V,{size:16}),"Delete"]})}),e.jsxs(w,{variant:"primary",size:"sm",className:"flex-1",isLoading:N.isPending,onClick:()=>N.mutate(),children:[e.jsx(ee,{size:16}),"Set hero banner"]})]})]})]})}),e.jsx("div",{className:"flex-1 min-w-0",children:e.jsxs(g,{children:[e.jsxs("div",{className:M,children:[e.jsxs("div",{className:S,children:[e.jsx(r,{as:"h2",variant:"subheading",weight:"medium",tracking:"tight",children:"Referenced Notes"}),e.jsx(r,{as:"p",variant:"meta",tone:"secondary",children:"Notes currently using this image"})]}),e.jsx(r,{as:"span",variant:"meta",weight:"medium",tone:"secondary",children:y})]}),c>0?e.jsx("ul",{className:"flex flex-col",children:m.map(s=>e.jsx("li",{children:e.jsx(se,{...s})},s.id))}):e.jsxs("div",{className:"flex items-start gap-3 py-1",children:[e.jsx("div",{className:"mt-0.5 flex h-8 w-8 shrink-0 items-center justify-center rounded-[10px] bg-muted/25 text-fg-disabled",children:e.jsx(X,{size:18})}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(r,{as:"p",variant:"body",weight:"medium",tone:"secondary",children:"No notes reference this image"}),e.jsx(r,{as:"p",variant:"meta",tone:"secondary",children:"This image can be deleted or reused in another note"})]})]})]})})]})},pe=()=>{const{id:a}=I.useParams();return e.jsxs(e.Fragment,{children:[e.jsx(Z,{children:e.jsx("title",{children:"Image Detail | Ocean Brain"})}),e.jsxs(p,{to:E,search:{page:1},className:te,children:[e.jsx(q,{size:16}),e.jsx(r,{as:"span",variant:"meta",weight:"medium",className:"text-current",children:"Back to Images"})]}),e.jsx(r,{as:"h1",variant:"heading",weight:"bold",tracking:"tighter",className:"sr-only",children:"Image Detail"}),e.jsx(B,{fallback:e.jsx(ie,{}),errorTitle:"Failed to load image detail",errorDescription:"Retry loading the image preview and its referenced notes",resetKeys:[a],children:e.jsx(le,{id:a})})]})};export{pe as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./note-vendor-B0t5F04o.js";import{aA as r,w as Q,u as R,af as p,P as E,T as t,aB as G,B as M,l as w,m as J,I as K,n as O,o as T,W as U}from"./index-
|
|
1
|
+
import{j as e}from"./note-vendor-B0t5F04o.js";import{aA as r,w as Q,u as R,af as p,P as E,T as t,aB as G,B as M,l as w,m as J,I as K,n as O,o as T,W as U}from"./index-B4l2UvuC.js";import{a as h}from"./graph-vendor-CUxe67Lr.js";import{S as x}from"./SurfaceCard-CHjcCuqZ.js";import"./note-core-GgFcksAF.js";const D=async()=>{const{data:s}=await r.get("/api/mcp-admin/status");return s},z=async s=>{const{data:n}=await r.post("/api/mcp-admin/enabled",{enabled:s});return n},V=async()=>{const{data:s}=await r.post("/api/mcp-admin/token/rotate");return s},W=async()=>{const{data:s}=await r.post("/api/mcp-admin/token/revoke");return s},o=["mcp-admin","status"],H=s=>JSON.stringify({mcpServers:{"ocean-brain":{command:"npx",args:["-y","ocean-brain","mcp","--server",s,"--token-file","/path/to/token.txt"]}}},null,2),X=s=>JSON.stringify({mcpServers:{"ocean-brain":{command:"npx",args:["-y","ocean-brain","mcp","--server",s,"--token","your-token-here"]}}},null,2),se=()=>{const s=U(),n=Q(),[c,S]=h.useState(()=>window.location.origin),[v,g]=h.useState(""),[k,P]=h.useState("token-file"),{data:y,isLoading:A}=R({queryKey:o,queryFn:D}),b=p({mutationFn:z,onSuccess:a=>{n.setQueryData(o,a),s(a.enabled?"MCP access enabled.":"MCP access disabled.")}}),f=p({mutationFn:V,onSuccess:async({token:a})=>{g(a),s("A new MCP token has been issued."),await n.invalidateQueries({queryKey:o})}}),j=p({mutationFn:W,onSuccess:a=>{g(""),n.setQueryData(o,a),s("The active MCP token has been revoked.")}}),l=y?.enabled??!1,d=y?.hasActiveToken??!1,I=!A&&!b.isPending,i="space-y-1",N="space-y-4.5",F="inline-flex items-center gap-3 rounded-[14px] border border-border-subtle bg-muted px-3 py-2",L="rounded-full border border-border-subtle bg-hover-subtle px-2.5 py-1",q="space-y-3 rounded-[16px] border border-border-subtle bg-surface px-4 py-3",B="overflow-x-auto rounded-[14px] border border-border-subtle bg-surface px-4 py-3 text-xs text-fg-secondary",u={variant:"subheading",weight:"medium",tracking:"tight"},C="font-medium text-fg-tertiary",m=k==="token-file"?{title:"Token file",description:"Recommended. Keeps the token out of config.",snippet:H(c)}:{title:"Inline token",description:"Useful for quick local testing.",snippet:X(c)};return e.jsx(E,{title:"MCP",variant:"default",description:"Manage MCP access, tokens, and connection details",children:e.jsxs("div",{className:"grid grid-cols-1 gap-4",children:[e.jsx(x,{tone:"elevated",children:e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-4",children:[e.jsxs("div",{className:i,children:[e.jsx(t,{as:"h2",...u,children:"MCP Access"}),e.jsx(t,{as:"p",variant:"meta",tone:"secondary",children:"Allow or block MCP requests at the server level."})]}),e.jsxs("div",{className:F,children:[e.jsx(t,{as:"span",variant:"meta",weight:"medium",tone:"secondary",children:l?"Enabled":"Disabled"}),e.jsx(G,{"aria-label":"Allow MCP access",checked:l,disabled:!I,onCheckedChange:()=>{b.mutate(!l)}})]})]})}),e.jsx(x,{tone:"elevated",children:e.jsxs("div",{className:N,children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:i,children:[e.jsx(t,{as:"h2",...u,children:"Token Management"}),e.jsx(t,{as:"p",variant:"meta",tone:"secondary",className:"max-w-[64ch]",children:"Ocean Brain supports one active MCP token at a time. Rotating immediately invalidates the previous one."})]}),e.jsx(t,{as:"span",variant:"meta",weight:"medium",tone:d?"secondary":"tertiary",className:L,children:d?"1 active token":"No active token"})]}),e.jsxs("div",{className:"flex flex-wrap gap-2.5",children:[e.jsx(M,{onClick:()=>f.mutate(void 0),isLoading:f.isPending,children:"Rotate token"}),e.jsx(M,{variant:"soft-danger",onClick:()=>j.mutate(),isLoading:j.isPending,disabled:!d,children:"Revoke token"})]}),v&&e.jsxs("div",{className:"space-y-2.5",children:[e.jsx(w,{htmlFor:"issued-mcp-token",className:C,children:"Issued token"}),e.jsx(J,{id:"issued-mcp-token",rows:3,readOnly:!0,value:v})]})]})}),e.jsx(x,{tone:"elevated",children:e.jsxs("div",{className:N,children:[e.jsxs("div",{className:i,children:[e.jsx(t,{as:"h2",...u,children:"Connection Guide"}),e.jsx(t,{as:"p",variant:"meta",tone:"secondary",children:"Connect your MCP client with either a token file or an inline token."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(w,{htmlFor:"mcp-server-url",className:C,children:"Server URL"}),e.jsx(K,{id:"mcp-server-url",value:c,onChange:a=>S(a.target.value)})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs(O,{type:"single",variant:"pills",size:"sm",value:k,onValueChange:a=>{(a==="token-file"||a==="inline-token")&&P(a)},children:[e.jsx(T,{value:"token-file",children:"Token file"}),e.jsx(T,{value:"inline-token",children:"Inline token"})]}),e.jsxs("div",{className:q,children:[e.jsxs("div",{className:i,children:[e.jsx(t,{as:"p",variant:"meta",weight:"semibold",children:m.title}),e.jsx(t,{as:"p",variant:"meta",tone:"secondary",children:m.description})]}),e.jsx("pre",{className:B,children:m.snippet})]})]})]})})]})})};export{se as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{j as e}from"./note-vendor-B0t5F04o.js";import{p as Y,h as E,w as J,q as v,aM as V,u as ee,af as M,P as ae,T as s,ai as te,aN as j,aO as N,B as C,a7 as se,M as m,l as w,I as b,r as le,ab as ne,a0 as re,i as $,j as ce,ay as ie,W as oe}from"./index-
|
|
1
|
+
import{j as e}from"./note-vendor-B0t5F04o.js";import{p as Y,h as E,w as J,q as v,aM as V,u as ee,af as M,P as ae,T as s,ai as te,aN as j,aO as N,B as C,a7 as se,M as m,l as w,I as b,r as le,ab as ne,a0 as re,i as $,j as ce,ay as ie,W as oe}from"./index-B4l2UvuC.js";import{a}from"./graph-vendor-CUxe67Lr.js";import{S as D}from"./SurfaceCard-CHjcCuqZ.js";import{n as de}from"./Plus.es-KeV96R_e.js";import"./note-core-GgFcksAF.js";const me=new Map([["bold",a.createElement(a.Fragment,null,a.createElement("path",{d:"M216.49,168.49a12,12,0,0,1-17,0L128,97,56.49,168.49a12,12,0,0,1-17-17l80-80a12,12,0,0,1,17,0l80,80A12,12,0,0,1,216.49,168.49Z"}))],["duotone",a.createElement(a.Fragment,null,a.createElement("path",{d:"M208,160H48l80-80Z",opacity:"0.2"}),a.createElement("path",{d:"M213.66,154.34l-80-80a8,8,0,0,0-11.32,0l-80,80A8,8,0,0,0,48,168H208a8,8,0,0,0,5.66-13.66ZM67.31,152,128,91.31,188.69,152Z"}))],["fill",a.createElement(a.Fragment,null,a.createElement("path",{d:"M215.39,163.06A8,8,0,0,1,208,168H48a8,8,0,0,1-5.66-13.66l80-80a8,8,0,0,1,11.32,0l80,80A8,8,0,0,1,215.39,163.06Z"}))],["light",a.createElement(a.Fragment,null,a.createElement("path",{d:"M212.24,164.24a6,6,0,0,1-8.48,0L128,88.49,52.24,164.24a6,6,0,0,1-8.48-8.48l80-80a6,6,0,0,1,8.48,0l80,80A6,6,0,0,1,212.24,164.24Z"}))],["regular",a.createElement(a.Fragment,null,a.createElement("path",{d:"M213.66,165.66a8,8,0,0,1-11.32,0L128,91.31,53.66,165.66a8,8,0,0,1-11.32-11.32l80-80a8,8,0,0,1,11.32,0l80,80A8,8,0,0,1,213.66,165.66Z"}))],["thin",a.createElement(a.Fragment,null,a.createElement("path",{d:"M210.83,162.83a4,4,0,0,1-5.66,0L128,85.66,50.83,162.83a4,4,0,0,1-5.66-5.66l80-80a4,4,0,0,1,5.66,0l80,80A4,4,0,0,1,210.83,162.83Z"}))]]),O=a.forwardRef((l,c)=>a.createElement(Y,{ref:c,...l,weights:me}));O.displayName="CaretUpIcon";const he=O,k=["id","name","template","replacement","createdAt","updatedAt"],ue=new Set(k),pe=`query FetchPlaceholders(
|
|
2
2
|
$searchFilter: SearchFilterInput,
|
|
3
3
|
$pagination: PaginationInput
|
|
4
4
|
) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./note-vendor-B0t5F04o.js";import{$ as F,j as M,ar as Q,w as L,v as _,a5 as I,aC as K,q as i,af as E,aD as B,N as O,aE as W,P as N,F as $,T as d,as as G,B as j,a0 as H,aF as Y,i as l,W as z,d as U,ah as V,u as Z,aG as J,M as y}from"./index-
|
|
1
|
+
import{j as e}from"./note-vendor-B0t5F04o.js";import{$ as F,j as M,ar as Q,w as L,v as _,a5 as I,aC as K,q as i,af as E,aD as B,N as O,aE as W,P as N,F as $,T as d,as as G,B as j,a0 as H,aF as Y,i as l,W as z,d as U,ah as V,u as Z,aG as J,M as y}from"./index-B4l2UvuC.js";import{a as k}from"./graph-vendor-CUxe67Lr.js";import{S as C}from"./SurfaceCard-CHjcCuqZ.js";import"./note-core-GgFcksAF.js";const m=25,v=M(Q),S=30,R=`Deleted notes stay here for ${S} days before permanent removal`,g={title:"Permanently delete note?",description:"This note is referenced by the notes below. If you permanently delete it, those links will stay broken. Other notes will not be edited automatically.",confirmLabel:"Delete now",confirmVariant:"danger"},P=a=>U(a).format("YYYY-MM-DD HH:mm"),X=({note:a,onClose:o})=>{const s=a?.id??"",c=a?.title||"Untitled note",r=Z({queryKey:i.notes.trashDetail(s),enabled:!!a,queryFn:async()=>{const h=await J(s);if(h.type==="error")throw h;if(!h.trashedNote)throw new Error("Trashed note not found");return h.trashedNote}}),f=r.data?.contentAsMarkdown.trim()??"";return e.jsxs(y,{isOpen:!!a,onClose:o,variant:"inspect",children:[e.jsx(y.Header,{title:c,onClose:o}),e.jsx(y.Body,{children:e.jsxs("div",{className:"flex flex-col gap-3",children:[a&&e.jsxs(d,{as:"p",variant:"meta",tone:"secondary",children:["Deleted ",P(a.deletedAt)]}),r.isLoading&&e.jsx(d,{as:"p",variant:"meta",tone:"secondary",children:"Loading deleted note content..."}),r.isError&&e.jsx(d,{as:"p",variant:"meta",tone:"error",children:"Failed to load deleted note content."}),!r.isLoading&&!r.isError&&f&&e.jsx("pre",{className:"max-h-[60vh] overflow-auto whitespace-pre-wrap break-words rounded-[14px] border border-border-subtle bg-hover-subtle/50 px-4 py-3 text-sm leading-6 text-fg-secondary",children:f}),!r.isLoading&&!r.isError&&!f&&e.jsx(d,{as:"p",variant:"meta",tone:"secondary",className:"rounded-[14px] border border-border-subtle bg-hover-subtle/50 px-4 py-3",children:"No readable content was found for this deleted note."})]})}),e.jsx(y.Footer,{children:e.jsx(j,{variant:"ghost",size:"sm",onClick:o,children:"Close"})})]})},ee=()=>e.jsx(N,{title:"Trash",variant:"default",heading:e.jsx(l,{width:118,height:24,className:"rounded-full"}),description:e.jsx(l,{width:352,height:16,className:"rounded-full"}),children:e.jsx("div",{className:"grid gap-3",children:Array.from({length:3},(a,o)=>e.jsx(C,{padding:"compact",children:e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between",children:[e.jsxs("div",{className:"min-w-0 flex-1 space-y-2",children:[e.jsx(l,{width:"40%",height:18,className:"rounded-full"}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(l,{width:168,height:14,className:"rounded-full"}),e.jsx(l,{width:176,height:14,className:"rounded-full"})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(l,{width:56,height:24,className:"rounded-full"}),e.jsx(l,{width:72,height:24,className:"rounded-full"})]})]}),e.jsx(l,{width:92,height:32,className:"rounded-[12px]"})]})},o))})}),te=()=>{const{page:a}=v.useSearch(),o=v.useNavigate(),s=L(),c=z(),r=_(),[f,h]=k.useState(null),[x,b]=k.useState(null),{data:u}=I({queryKey:i.notes.trash({limit:m,offset:(a-1)*m}),queryFn:async()=>{const t=await K({limit:m,offset:(a-1)*m});if(t.type==="error")throw t;return t.trashedNotes}}),w=E({mutationFn:B,onSuccess:async t=>{if(t.type==="error")throw t;await Promise.all([s.invalidateQueries({queryKey:i.notes.all(),exact:!1}),s.invalidateQueries({queryKey:i.tags.all(),exact:!1}),s.invalidateQueries({queryKey:i.reminders.all(),exact:!1}),s.invalidateQueries({queryKey:i.images.all(),exact:!1}),s.invalidateQueries({queryKey:i.calendar.all(),exact:!1})]),c("The note has been restored."),o({to:O,params:{id:t.restoreTrashedNote.id}})},onError:()=>{c("Failed to restore the note.")}}),p=E({mutationFn:W,onSuccess:async t=>{if(t.type==="error")throw t;await s.invalidateQueries({queryKey:i.notes.trashAll(),exact:!1}),c("The note has been permanently deleted.")},onError:()=>{c("Failed to permanently delete the note.")}}),D=()=>{if(!x)return;const{id:t}=x;b(null),p.mutate(t)},q=async t=>{const n=await V(t);if(n.type==="error"){c("Failed to check linked notes before permanently deleting this note.");return}if(s.setQueryData(i.notes.backReferences(t),n.backReferences),n.backReferences.length>0){b({id:t,backReferences:n.backReferences});return}await r("Permanently delete this note? This cannot be undone.")&&p.mutate(t)},T=u.totalCount>0?`Trash (${u.totalCount})`:void 0,A=u.notes.find(t=>t.id===f)??null;return u.notes.length===0?e.jsx(N,{title:"Trash",variant:"default",heading:T,description:R,children:e.jsx($,{title:"Trash is empty",description:`Delete a note and you can restore it here for ${S} days before permanent removal`})}):e.jsxs(N,{title:"Trash",variant:"default",heading:T,description:R,children:[e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx("div",{className:"grid gap-3",children:u.notes.map(t=>e.jsx(C,{padding:"compact",children:e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex min-w-0 items-start gap-1.5",children:[e.jsx(d,{as:"h2",variant:"body",weight:"medium",className:"min-w-0 flex-1 break-words leading-[1.25]",children:t.title||"Untitled note"}),t.pinned&&e.jsx("span",{title:"Pinned",className:"inline-flex h-5 w-5 shrink-0 items-center justify-center text-fg-tertiary",children:e.jsx(G,{className:"h-3.5 w-3.5"})})]}),e.jsx("div",{className:"mt-1 flex flex-wrap items-center gap-x-3 gap-y-1",children:e.jsxs(d,{as:"div",variant:"meta",weight:"medium",tone:"secondary",children:["Deleted ",P(t.deletedAt)]})}),t.tagNames.length>0&&e.jsx("div",{className:"mt-2 flex flex-wrap gap-1.5",children:t.tagNames.map(n=>e.jsx(d,{as:"span",variant:"label",weight:"medium",tone:"tertiary",className:"rounded-full border border-border-subtle bg-hover-subtle px-2 py-0.5",children:n},`${t.id}-${n}`))}),t.contentPreview&&e.jsx("div",{className:"mt-3 rounded-[14px] border border-border-subtle bg-hover-subtle/50 px-3 py-2",children:e.jsx(d,{as:"p",variant:"meta",tone:"secondary",className:"line-clamp-3 whitespace-pre-wrap break-words",children:t.contentPreview})})]}),e.jsxs("div",{className:"flex shrink-0 flex-wrap gap-2 sm:justify-end",children:[e.jsx(j,{variant:"subtle",size:"sm",onClick:()=>h(t.id),children:"View content"}),e.jsx(j,{variant:"subtle",size:"sm",isLoading:w.isPending&&w.variables===t.id,onClick:()=>w.mutate(t.id),children:"Restore"}),e.jsx(j,{variant:"soft-danger",size:"sm",isLoading:p.isPending&&p.variables===t.id,onClick:()=>q(t.id),children:"Delete now"})]})]})},t.id))}),u.totalCount>m&&e.jsx(H,{page:a,last:Math.ceil(u.totalCount/m),onChange:t=>{o({search:n=>({...n,page:t})})}})]}),e.jsx(X,{note:A,onClose:()=>h(null)}),e.jsx(Y,{isOpen:!!x,title:g.title,description:g.description,references:x?.backReferences??[],confirmLabel:g.confirmLabel,confirmVariant:g.confirmVariant,onClose:()=>b(null),onConfirm:D})]})},oe=()=>{const{page:a}=v.useSearch();return e.jsx(F,{fallback:e.jsx(ee,{}),errorTitle:"Failed to load trash",errorDescription:"Retry loading deleted notes",resetKeys:[a],children:e.jsx(te,{})})};export{oe as default};
|
package/server/client/dist/assets/{useReminderMutate-Bkj-oIm4.js → useReminderMutate-v1EXqM90.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{j as y}from"./note-vendor-B0t5F04o.js";import{h as u,a5 as f,q as n,w as R,W as $}from"./index-
|
|
1
|
+
import{j as y}from"./note-vendor-B0t5F04o.js";import{h as u,a5 as f,q as n,w as R,W as $}from"./index-B4l2UvuC.js";import{a as l}from"./graph-vendor-CUxe67Lr.js";const g=(e={})=>({limit:e.limit??10,offset:e.offset??0}),D=async(e,t)=>u(`
|
|
2
2
|
query FetchNoteReminders($noteId: ID!, $pagination: PaginationInput) {
|
|
3
3
|
noteReminders(noteId: $noteId, pagination: $pagination) {
|
|
4
4
|
totalCount
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<link rel="icon" type="image/png" href="/icon.png" />
|
|
7
7
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
8
8
|
<title>Ocean Brain</title>
|
|
9
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
+
<script type="module" crossorigin src="/assets/index-B4l2UvuC.js"></script>
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/graph-vendor-CUxe67Lr.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/note-core-GgFcksAF.js">
|
|
12
12
|
<link rel="modulepreload" crossorigin href="/assets/note-vendor-B0t5F04o.js">
|
package/server/dist/app.js
CHANGED
|
@@ -2,7 +2,7 @@ import express from "express";
|
|
|
2
2
|
import { createMcpAdminService } from "./features/mcp-admin/service.js";
|
|
3
3
|
import { purgeExpiredNoteSnapshots } from "./features/note/services/snapshot.js";
|
|
4
4
|
import { purgeExpiredTrashedNotes } from "./features/note/services/trash.js";
|
|
5
|
-
import { createSessionMiddleware } from "./modules/auth-guard.js";
|
|
5
|
+
import { createCsrfProtection, createSessionMiddleware } from "./modules/auth-guard.js";
|
|
6
6
|
import { createErrorHandler } from "./modules/error-handler.js";
|
|
7
7
|
import logger from "./modules/logger.js";
|
|
8
8
|
import { createApiRouter, createAuthPagesRouter, createClientRouter, createGraphqlRouter } from "./routes/index.js";
|
|
@@ -18,7 +18,7 @@ const createAppWithMcpAuth = (authConfig, mcpAdminService) => {
|
|
|
18
18
|
process.stderr.write(`[recovery] Startup cleanup failed: ${message}
|
|
19
19
|
`);
|
|
20
20
|
});
|
|
21
|
-
app.use(logger).use(createSessionMiddleware(authConfig)).use(express.urlencoded({ extended: false })).use(express.json({ limit: "50mb" })).use("/api", createApiRouter(authConfig, mcpAdminService)).use(createAuthPagesRouter(authConfig)).use("/graphql", createGraphqlRouter(authConfig, mcpAdminService)).use(createClientRouter(authConfig)).use(createErrorHandler());
|
|
21
|
+
app.use(logger).use(createSessionMiddleware(authConfig)).use(express.urlencoded({ extended: false })).use(express.json({ limit: "50mb" })).use(createCsrfProtection(authConfig)).use("/api", createApiRouter(authConfig, mcpAdminService)).use(createAuthPagesRouter(authConfig)).use("/graphql", createGraphqlRouter(authConfig, mcpAdminService)).use(createClientRouter(authConfig)).use(createErrorHandler());
|
|
22
22
|
return app;
|
|
23
23
|
};
|
|
24
24
|
var app_default = createApp;
|
package/server/dist/app.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/app.ts"],"sourcesContent":["import express from 'express';\nimport { createMcpAdminService, type McpAdminService } from './features/mcp-admin/service.js';\nimport { purgeExpiredNoteSnapshots } from './features/note/services/snapshot.js';\nimport { purgeExpiredTrashedNotes } from './features/note/services/trash.js';\nimport { createSessionMiddleware } from './modules/auth-guard.js';\nimport type { AuthConfig } from './modules/auth-mode.js';\nimport { createErrorHandler } from './modules/error-handler.js';\nimport logger from './modules/logger.js';\nimport { createApiRouter, createAuthPagesRouter, createClientRouter, createGraphqlRouter } from './routes/index.js';\n\nexport const createApp = (authConfig: AuthConfig) => {\n const mcpAdminService = createMcpAdminService();\n return createAppWithMcpAuth(authConfig, mcpAdminService);\n};\n\nexport const createAppWithMcpAuth = (authConfig: AuthConfig, mcpAdminService: McpAdminService) => {\n const app = express();\n app.locals.authConfig = authConfig;\n\n void Promise.all([purgeExpiredNoteSnapshots(), purgeExpiredTrashedNotes()]).catch((error) => {\n const message = error instanceof Error ? error.message : 'Unknown recovery cleanup error';\n process.stderr.write(`[recovery] Startup cleanup failed: ${message}\\n`);\n });\n\n app.use(logger)\n .use(createSessionMiddleware(authConfig))\n .use(express.urlencoded({ extended: false }))\n .use(express.json({ limit: '50mb' }))\n .use('/api', createApiRouter(authConfig, mcpAdminService))\n .use(createAuthPagesRouter(authConfig))\n .use('/graphql', createGraphqlRouter(authConfig, mcpAdminService))\n .use(createClientRouter(authConfig))\n .use(createErrorHandler());\n\n return app;\n};\n\nexport default createApp;\n"],"mappings":"AAAA,OAAO,aAAa;AACpB,SAAS,6BAAmD;AAC5D,SAAS,iCAAiC;AAC1C,SAAS,gCAAgC;AACzC,SAAS,+BAA+B;
|
|
1
|
+
{"version":3,"sources":["../src/app.ts"],"sourcesContent":["import express from 'express';\nimport { createMcpAdminService, type McpAdminService } from './features/mcp-admin/service.js';\nimport { purgeExpiredNoteSnapshots } from './features/note/services/snapshot.js';\nimport { purgeExpiredTrashedNotes } from './features/note/services/trash.js';\nimport { createCsrfProtection, createSessionMiddleware } from './modules/auth-guard.js';\nimport type { AuthConfig } from './modules/auth-mode.js';\nimport { createErrorHandler } from './modules/error-handler.js';\nimport logger from './modules/logger.js';\nimport { createApiRouter, createAuthPagesRouter, createClientRouter, createGraphqlRouter } from './routes/index.js';\n\nexport const createApp = (authConfig: AuthConfig) => {\n const mcpAdminService = createMcpAdminService();\n return createAppWithMcpAuth(authConfig, mcpAdminService);\n};\n\nexport const createAppWithMcpAuth = (authConfig: AuthConfig, mcpAdminService: McpAdminService) => {\n const app = express();\n app.locals.authConfig = authConfig;\n\n void Promise.all([purgeExpiredNoteSnapshots(), purgeExpiredTrashedNotes()]).catch((error) => {\n const message = error instanceof Error ? error.message : 'Unknown recovery cleanup error';\n process.stderr.write(`[recovery] Startup cleanup failed: ${message}\\n`);\n });\n\n app.use(logger)\n .use(createSessionMiddleware(authConfig))\n .use(express.urlencoded({ extended: false }))\n .use(express.json({ limit: '50mb' }))\n .use(createCsrfProtection(authConfig))\n .use('/api', createApiRouter(authConfig, mcpAdminService))\n .use(createAuthPagesRouter(authConfig))\n .use('/graphql', createGraphqlRouter(authConfig, mcpAdminService))\n .use(createClientRouter(authConfig))\n .use(createErrorHandler());\n\n return app;\n};\n\nexport default createApp;\n"],"mappings":"AAAA,OAAO,aAAa;AACpB,SAAS,6BAAmD;AAC5D,SAAS,iCAAiC;AAC1C,SAAS,gCAAgC;AACzC,SAAS,sBAAsB,+BAA+B;AAE9D,SAAS,0BAA0B;AACnC,OAAO,YAAY;AACnB,SAAS,iBAAiB,uBAAuB,oBAAoB,2BAA2B;AAEzF,MAAM,YAAY,CAAC,eAA2B;AACjD,QAAM,kBAAkB,sBAAsB;AAC9C,SAAO,qBAAqB,YAAY,eAAe;AAC3D;AAEO,MAAM,uBAAuB,CAAC,YAAwB,oBAAqC;AAC9F,QAAM,MAAM,QAAQ;AACpB,MAAI,OAAO,aAAa;AAExB,OAAK,QAAQ,IAAI,CAAC,0BAA0B,GAAG,yBAAyB,CAAC,CAAC,EAAE,MAAM,CAAC,UAAU;AACzF,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,YAAQ,OAAO,MAAM,sCAAsC,OAAO;AAAA,CAAI;AAAA,EAC1E,CAAC;AAED,MAAI,IAAI,MAAM,EACT,IAAI,wBAAwB,UAAU,CAAC,EACvC,IAAI,QAAQ,WAAW,EAAE,UAAU,MAAM,CAAC,CAAC,EAC3C,IAAI,QAAQ,KAAK,EAAE,OAAO,OAAO,CAAC,CAAC,EACnC,IAAI,qBAAqB,UAAU,CAAC,EACpC,IAAI,QAAQ,gBAAgB,YAAY,eAAe,CAAC,EACxD,IAAI,sBAAsB,UAAU,CAAC,EACrC,IAAI,YAAY,oBAAoB,YAAY,eAAe,CAAC,EAChE,IAAI,mBAAmB,UAAU,CAAC,EAClC,IAAI,mBAAmB,CAAC;AAE7B,SAAO;AACX;AAEA,IAAO,cAAQ;","names":[]}
|
|
@@ -3,7 +3,7 @@ const LOGIN_ERROR_TOKEN = "<!-- OCEAN_BRAIN_LOGIN_ERROR -->";
|
|
|
3
3
|
const NEXT_PATH_TOKEN = "OCEAN_BRAIN_NEXT_PATH";
|
|
4
4
|
const readLoginPageTemplate = () => {
|
|
5
5
|
if (true) {
|
|
6
|
-
return '<!doctype html>\n<html lang="en">\n<head>\n <meta charset="utf-8" />\n <meta name="viewport" content="width=device-width, initial-scale=1" />\n <title>Ocean Brain Sign In</title>\n <style>\n :root {\n color-scheme: light dark;\n --surface: #f7f8fa;\n --elevated: #fbfcfd;\n --fg-default: #202631;\n --fg-secondary: #626d7c;\n --fg-tertiary: #8993a2;\n --fg-placeholder: #98a2b0;\n --fg-error: #a24545;\n --fg-on-filled: #f6f8fb;\n --border-subtle: #e5e9ee;\n --border-focus: #757f8d;\n --border-error: #d47777;\n --accent-soft-danger: rgba(214, 141, 135, 0.18);\n --accent-soft-primary: rgba(93, 102, 114, 0.12);\n --cta: #23272d;\n --cta-hover: #171a1f;\n --page-bg: #f2f5f8;\n font-family: "Pretendard Variable", "Pretendard", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;\n background: var(--page-bg);\n color: var(--fg-default);\n }\n @media (prefers-color-scheme: dark) {\n :root {\n --surface: #16191e;\n --elevated: #1d2229;\n --fg-default: #e6ebf2;\n --fg-secondary: #a9b3c2;\n --fg-tertiary: #7f8998;\n --fg-placeholder: #717b88;\n --fg-error: #efaaaa;\n --fg-on-filled: #12161c;\n --border-subtle: #29303a;\n --border-focus: #b4c0cf;\n --border-error: #efaaaa;\n --accent-soft-danger: rgba(215, 146, 139, 0.14);\n --accent-soft-primary: rgba(184, 192, 202, 0.12);\n --cta: #edf1f5;\n --cta-hover: #f8fafc;\n --page-bg: #101318;\n }\n }\n * {\n box-sizing: border-box;\n }\n body {\n margin: 0;\n min-height: 100vh;\n display: grid;\n place-items: center;\n background: var(--page-bg);\n padding: 24px;\n }\n .shell {\n width: min(392px, 100%);\n }\n .brand {\n margin-bottom: 14px;\n color: var(--fg-tertiary);\n font-size: 12px;\n font-weight: 700;\n line-height: 1.4;\n }\n .panel {\n padding: 24px;\n border: 1px solid var(--border-subtle);\n border-radius: 16px;\n background: var(--surface);\n box-shadow:\n inset 0 1px 0 rgba(255, 255, 255, 0.1),\n 0 1px 4px -2px rgba(23, 29, 38, 0.04);\n }\n h1 {\n margin: 0;\n color: var(--fg-default);\n font-size: 1.375rem;\n line-height: 1.3;\n font-weight: 700;\n }\n .lead {\n margin: 6px 0 22px;\n color: var(--fg-tertiary);\n font-size: 0.875rem;\n line-height: 1.5;\n font-weight: 500;\n }\n label {\n display: block;\n margin-bottom: 8px;\n color: var(--fg-secondary);\n font-size: 0.75rem;\n line-height: 1.4;\n font-weight: 600;\n }\n form {\n display: grid;\n gap: 16px;\n }\n .field {\n display: grid;\n }\n input {\n width: 100%;\n box-sizing: border-box;\n padding: 14px 16px;\n border: 1px solid var(--border-subtle);\n border-radius: 16px;\n background: var(--elevated);\n font-size: 16px;\n color: var(--fg-default);\n transition: border-color 0.18s ease, box-shadow 0.18s ease, background-color 0.18s ease;\n }\n input::placeholder {\n color: var(--fg-placeholder);\n }\n input:focus {\n outline: none;\n border-color: var(--border-focus);\n box-shadow: 0 0 0 4px var(--accent-soft-primary);\n }\n .hint {\n margin-top: 10px;\n color: var(--fg-tertiary);\n font-size: 0.75rem;\n line-height: 1.4;\n }\n button {\n width: 100%;\n border: 1px solid transparent;\n border-radius: 14px;\n background: var(--cta);\n color: var(--fg-on-filled);\n padding: 14px 18px;\n font-size: 16px;\n font-weight: 600;\n cursor: pointer;\n transition: transform 0.18s ease, box-shadow 0.18s ease, background-color 0.18s ease;\n }\n button:hover {\n background: var(--cta-hover);\n }\n button:active {\n transform: translateY(1px);\n }\n button:focus-visible {\n outline: none;\n box-shadow: 0 0 0 4px var(--accent-soft-primary);\n }\n .error {\n margin-bottom: 18px;\n padding: 13px 14px;\n border: 1px solid var(--border-error);\n border-radius: 14px;\n background: var(--accent-soft-danger);\n color: var(--fg-error);\n font-size: 14px;\n font-weight: 600;\n }\n @media (prefers-color-scheme: dark) {\n .panel {\n box-shadow:\n inset 0 1px 0 rgba(255, 255, 255, 0.03),\n 0 1px 4px -2px rgba(0, 0, 0, 0.18);\n }\n }\n @media (max-width: 640px) {\n body {\n place-items: stretch;\n padding: 18px;\n }\n .shell {\n width: 100%;\n margin: auto 0;\n }\n .panel {\n padding: 22px;\n }\n }\n </style>\n</head>\n<body>\n <main class="shell">\n <div class="brand">Ocean Brain</div>\n <section class="panel" aria-labelledby="login-title">\n <h1 id="login-title">Sign in</h1>\n <p class="lead">Enter the workspace password to continue.</p>\n <!-- OCEAN_BRAIN_LOGIN_ERROR -->\n <form method="post" action="/login">\n <input type="hidden" name="next" value="OCEAN_BRAIN_NEXT_PATH" />\n <div class="field">\n <label for="password">Password</label>\n <input id="password" name="password" type="password" autocomplete="current-password" required autofocus />\n </div>\n <button type="submit">Sign in</button>\n </form>\n <div class="hint">This session must be authenticated before the workspace loads.</div>\n </section>\n </main>\n</body>\n</html>\n';
|
|
6
|
+
return '<!doctype html>\n<html lang="en">\n<head>\n <meta charset="utf-8" />\n <meta name="viewport" content="width=device-width, initial-scale=1" />\n <title>Ocean Brain Sign In</title>\n <style>\n :root {\n color-scheme: light dark;\n --surface: #f7f8fa;\n --elevated: #fbfcfd;\n --fg-default: #202631;\n --fg-secondary: #626d7c;\n --fg-tertiary: #8993a2;\n --fg-placeholder: #98a2b0;\n --fg-error: #a24545;\n --fg-on-filled: #f6f8fb;\n --border-subtle: #e5e9ee;\n --border-focus: #757f8d;\n --border-error: #d47777;\n --accent-soft-danger: rgba(214, 141, 135, 0.18);\n --accent-soft-primary: rgba(93, 102, 114, 0.12);\n --cta: #23272d;\n --cta-hover: #171a1f;\n --page-bg: #f2f5f8;\n font-family: "Pretendard Variable", "Pretendard", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;\n background: var(--page-bg);\n color: var(--fg-default);\n }\n @media (prefers-color-scheme: dark) {\n :root {\n --surface: #16191e;\n --elevated: #1d2229;\n --fg-default: #e6ebf2;\n --fg-secondary: #a9b3c2;\n --fg-tertiary: #7f8998;\n --fg-placeholder: #717b88;\n --fg-error: #efaaaa;\n --fg-on-filled: #12161c;\n --border-subtle: #29303a;\n --border-focus: #b4c0cf;\n --border-error: #efaaaa;\n --accent-soft-danger: rgba(215, 146, 139, 0.14);\n --accent-soft-primary: rgba(184, 192, 202, 0.12);\n --cta: #edf1f5;\n --cta-hover: #f8fafc;\n --page-bg: #101318;\n }\n }\n * {\n box-sizing: border-box;\n }\n body {\n margin: 0;\n min-height: 100vh;\n display: grid;\n place-items: center;\n background: var(--page-bg);\n padding: 24px;\n }\n .shell {\n width: min(392px, 100%);\n }\n .brand {\n margin-bottom: 14px;\n color: var(--fg-tertiary);\n font-size: 12px;\n font-weight: 700;\n line-height: 1.4;\n }\n .panel {\n padding: 24px;\n border: 1px solid var(--border-subtle);\n border-radius: 16px;\n background: var(--surface);\n box-shadow:\n inset 0 1px 0 rgba(255, 255, 255, 0.1),\n 0 1px 4px -2px rgba(23, 29, 38, 0.04);\n }\n h1 {\n margin: 0;\n color: var(--fg-default);\n font-size: 1.375rem;\n line-height: 1.3;\n font-weight: 700;\n }\n .lead {\n margin: 6px 0 22px;\n color: var(--fg-tertiary);\n font-size: 0.875rem;\n line-height: 1.5;\n font-weight: 500;\n }\n label {\n display: block;\n margin-bottom: 8px;\n color: var(--fg-secondary);\n font-size: 0.75rem;\n line-height: 1.4;\n font-weight: 600;\n }\n form {\n display: grid;\n gap: 16px;\n }\n .field {\n display: grid;\n }\n input {\n width: 100%;\n box-sizing: border-box;\n padding: 14px 16px;\n border: 1px solid var(--border-subtle);\n border-radius: 16px;\n background: var(--elevated);\n font-size: 16px;\n color: var(--fg-default);\n transition: border-color 0.18s ease, box-shadow 0.18s ease, background-color 0.18s ease;\n }\n input::placeholder {\n color: var(--fg-placeholder);\n }\n input:focus {\n outline: none;\n border-color: var(--border-focus);\n box-shadow: 0 0 0 4px var(--accent-soft-primary);\n }\n .hint {\n margin-top: 10px;\n color: var(--fg-tertiary);\n font-size: 0.75rem;\n line-height: 1.4;\n }\n button {\n width: 100%;\n border: 1px solid transparent;\n border-radius: 14px;\n background: var(--cta);\n color: var(--fg-on-filled);\n padding: 14px 18px;\n font-size: 16px;\n font-weight: 600;\n cursor: pointer;\n transition: transform 0.18s ease, box-shadow 0.18s ease, background-color 0.18s ease;\n }\n button:hover {\n background: var(--cta-hover);\n }\n button:active {\n transform: translateY(1px);\n }\n button:focus-visible {\n outline: none;\n box-shadow: 0 0 0 4px var(--accent-soft-primary);\n }\n .error {\n margin-bottom: 18px;\n padding: 13px 14px;\n border: 1px solid var(--border-error);\n border-radius: 14px;\n background: var(--accent-soft-danger);\n color: var(--fg-error);\n font-size: 14px;\n font-weight: 600;\n }\n @media (prefers-color-scheme: dark) {\n .panel {\n box-shadow:\n inset 0 1px 0 rgba(255, 255, 255, 0.03),\n 0 1px 4px -2px rgba(0, 0, 0, 0.18);\n }\n }\n @media (max-width: 640px) {\n body {\n place-items: stretch;\n padding: 18px;\n }\n .shell {\n width: 100%;\n margin: auto 0;\n }\n .panel {\n padding: 22px;\n }\n }\n </style>\n</head>\n<body>\n <main class="shell">\n <div class="brand">Ocean Brain</div>\n <section class="panel" aria-labelledby="login-title">\n <h1 id="login-title">Sign in</h1>\n <p class="lead">Enter the workspace password to continue.</p>\n <!-- OCEAN_BRAIN_LOGIN_ERROR -->\n <form method="post" action="/login">\n <!-- OCEAN_BRAIN_CSRF_INPUT -->\n <input type="hidden" name="next" value="OCEAN_BRAIN_NEXT_PATH" />\n <div class="field">\n <label for="password">Password</label>\n <input id="password" name="password" type="password" autocomplete="current-password" required autofocus />\n </div>\n <button type="submit">Sign in</button>\n </form>\n <div class="hint">This session must be authenticated before the workspace loads.</div>\n </section>\n </main>\n</body>\n</html>\n';
|
|
7
7
|
}
|
|
8
8
|
return readFileSync(new URL("./login-page.html", import.meta.url), "utf8");
|
|
9
9
|
};
|
|
@@ -15,12 +15,19 @@ const renderLoginError = (errorMessage) => {
|
|
|
15
15
|
}
|
|
16
16
|
return `<div class="error" role="alert">${escapeHtml(errorMessage)}</div>`;
|
|
17
17
|
};
|
|
18
|
+
const renderCsrfInput = (csrfToken) => {
|
|
19
|
+
if (!csrfToken) {
|
|
20
|
+
return "";
|
|
21
|
+
}
|
|
22
|
+
return `<input type="hidden" name="_csrf" value="${escapeHtml(csrfToken)}" />`;
|
|
23
|
+
};
|
|
18
24
|
const renderLoginTemplate = (values) => {
|
|
19
|
-
return LOGIN_PAGE_TEMPLATE.replace(LOGIN_ERROR_TOKEN, values.errorBlock).replace(NEXT_PATH_TOKEN, values.nextPath);
|
|
25
|
+
return LOGIN_PAGE_TEMPLATE.replace(LOGIN_ERROR_TOKEN, values.errorBlock).replace(NEXT_PATH_TOKEN, values.nextPath).replace("<!-- OCEAN_BRAIN_CSRF_INPUT -->", values.csrfInput);
|
|
20
26
|
};
|
|
21
|
-
const renderLoginPage = ({ nextPath, errorMessage }) => renderLoginTemplate({
|
|
27
|
+
const renderLoginPage = ({ nextPath, errorMessage, csrfToken }) => renderLoginTemplate({
|
|
22
28
|
errorBlock: renderLoginError(errorMessage),
|
|
23
|
-
nextPath: escapeHtml(nextPath)
|
|
29
|
+
nextPath: escapeHtml(nextPath),
|
|
30
|
+
csrfInput: renderCsrfInput(csrfToken)
|
|
24
31
|
});
|
|
25
32
|
export {
|
|
26
33
|
renderLoginPage
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/auth/http/login-page.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\n\ndeclare const __LOGIN_PAGE_TEMPLATE__: string | undefined;\n\nconst LOGIN_ERROR_TOKEN = '<!-- OCEAN_BRAIN_LOGIN_ERROR -->';\nconst NEXT_PATH_TOKEN = 'OCEAN_BRAIN_NEXT_PATH';\n\nconst readLoginPageTemplate = () => {\n if (typeof __LOGIN_PAGE_TEMPLATE__ === 'string') {\n return __LOGIN_PAGE_TEMPLATE__;\n }\n\n return readFileSync(new URL('./login-page.html', import.meta.url), 'utf8');\n};\n\nconst LOGIN_PAGE_TEMPLATE = readLoginPageTemplate();\n\nconst escapeHtml = (value: string) =>\n value\n .replaceAll('&', '&')\n .replaceAll('<', '<')\n .replaceAll('>', '>')\n .replaceAll('\"', '"')\n .replaceAll(\"'\", ''');\n\ninterface LoginPageParams {\n nextPath: string;\n errorMessage?: string;\n}\n\nconst renderLoginError = (errorMessage?: string) => {\n if (!errorMessage) {\n return '';\n }\n\n return `<div class=\"error\" role=\"alert\">${escapeHtml(errorMessage)}</div>`;\n};\n\nconst renderLoginTemplate = (values: { errorBlock: string; nextPath: string }) => {\n return LOGIN_PAGE_TEMPLATE.replace(LOGIN_ERROR_TOKEN, values.errorBlock).replace(NEXT_PATH_TOKEN, values.nextPath);\n};\n\nexport const renderLoginPage = ({ nextPath, errorMessage }: LoginPageParams) =>\n renderLoginTemplate({\n errorBlock: renderLoginError(errorMessage),\n nextPath: escapeHtml(nextPath),\n });\n"],"mappings":"AAAA,SAAS,oBAAoB;AAI7B,MAAM,oBAAoB;AAC1B,MAAM,kBAAkB;AAExB,MAAM,wBAAwB,MAAM;AAChC,MAAI,MAA6C;AAC7C,WAAO;AAAA,EACX;AAEA,SAAO,aAAa,IAAI,IAAI,qBAAqB,YAAY,GAAG,GAAG,MAAM;AAC7E;AAEA,MAAM,sBAAsB,sBAAsB;AAElD,MAAM,aAAa,CAAC,UAChB,MACK,WAAW,KAAK,OAAO,EACvB,WAAW,KAAK,MAAM,EACtB,WAAW,KAAK,MAAM,EACtB,WAAW,KAAK,QAAQ,EACxB,WAAW,KAAK,OAAO;
|
|
1
|
+
{"version":3,"sources":["../../../../src/features/auth/http/login-page.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\n\ndeclare const __LOGIN_PAGE_TEMPLATE__: string | undefined;\n\nconst LOGIN_ERROR_TOKEN = '<!-- OCEAN_BRAIN_LOGIN_ERROR -->';\nconst NEXT_PATH_TOKEN = 'OCEAN_BRAIN_NEXT_PATH';\n\nconst readLoginPageTemplate = () => {\n if (typeof __LOGIN_PAGE_TEMPLATE__ === 'string') {\n return __LOGIN_PAGE_TEMPLATE__;\n }\n\n return readFileSync(new URL('./login-page.html', import.meta.url), 'utf8');\n};\n\nconst LOGIN_PAGE_TEMPLATE = readLoginPageTemplate();\n\nconst escapeHtml = (value: string) =>\n value\n .replaceAll('&', '&')\n .replaceAll('<', '<')\n .replaceAll('>', '>')\n .replaceAll('\"', '"')\n .replaceAll(\"'\", ''');\n\ninterface LoginPageParams {\n nextPath: string;\n errorMessage?: string;\n csrfToken?: string;\n}\n\nconst renderLoginError = (errorMessage?: string) => {\n if (!errorMessage) {\n return '';\n }\n\n return `<div class=\"error\" role=\"alert\">${escapeHtml(errorMessage)}</div>`;\n};\n\nconst renderCsrfInput = (csrfToken?: string) => {\n if (!csrfToken) {\n return '';\n }\n\n return `<input type=\"hidden\" name=\"_csrf\" value=\"${escapeHtml(csrfToken)}\" />`;\n};\n\nconst renderLoginTemplate = (values: { errorBlock: string; nextPath: string; csrfInput: string }) => {\n return LOGIN_PAGE_TEMPLATE.replace(LOGIN_ERROR_TOKEN, values.errorBlock)\n .replace(NEXT_PATH_TOKEN, values.nextPath)\n .replace('<!-- OCEAN_BRAIN_CSRF_INPUT -->', values.csrfInput);\n};\n\nexport const renderLoginPage = ({ nextPath, errorMessage, csrfToken }: LoginPageParams) =>\n renderLoginTemplate({\n errorBlock: renderLoginError(errorMessage),\n nextPath: escapeHtml(nextPath),\n csrfInput: renderCsrfInput(csrfToken),\n });\n"],"mappings":"AAAA,SAAS,oBAAoB;AAI7B,MAAM,oBAAoB;AAC1B,MAAM,kBAAkB;AAExB,MAAM,wBAAwB,MAAM;AAChC,MAAI,MAA6C;AAC7C,WAAO;AAAA,EACX;AAEA,SAAO,aAAa,IAAI,IAAI,qBAAqB,YAAY,GAAG,GAAG,MAAM;AAC7E;AAEA,MAAM,sBAAsB,sBAAsB;AAElD,MAAM,aAAa,CAAC,UAChB,MACK,WAAW,KAAK,OAAO,EACvB,WAAW,KAAK,MAAM,EACtB,WAAW,KAAK,MAAM,EACtB,WAAW,KAAK,QAAQ,EACxB,WAAW,KAAK,OAAO;AAQhC,MAAM,mBAAmB,CAAC,iBAA0B;AAChD,MAAI,CAAC,cAAc;AACf,WAAO;AAAA,EACX;AAEA,SAAO,mCAAmC,WAAW,YAAY,CAAC;AACtE;AAEA,MAAM,kBAAkB,CAAC,cAAuB;AAC5C,MAAI,CAAC,WAAW;AACZ,WAAO;AAAA,EACX;AAEA,SAAO,4CAA4C,WAAW,SAAS,CAAC;AAC5E;AAEA,MAAM,sBAAsB,CAAC,WAAwE;AACjG,SAAO,oBAAoB,QAAQ,mBAAmB,OAAO,UAAU,EAClE,QAAQ,iBAAiB,OAAO,QAAQ,EACxC,QAAQ,mCAAmC,OAAO,SAAS;AACpE;AAEO,MAAM,kBAAkB,CAAC,EAAE,UAAU,cAAc,UAAU,MAChE,oBAAoB;AAAA,EAChB,YAAY,iBAAiB,YAAY;AAAA,EACzC,UAAU,WAAW,QAAQ;AAAA,EAC7B,WAAW,gBAAgB,SAAS;AACxC,CAAC;","names":[]}
|
|
@@ -7,7 +7,7 @@ const createLoginPageHandler = (authConfig) => {
|
|
|
7
7
|
return;
|
|
8
8
|
}
|
|
9
9
|
const nextPath = sanitizeRedirectPath(req.query.next);
|
|
10
|
-
res.status(200).type("html").send(renderLoginPage({ nextPath })).end();
|
|
10
|
+
res.status(200).type("html").send(renderLoginPage({ nextPath, csrfToken: res.locals._csrf })).end();
|
|
11
11
|
};
|
|
12
12
|
};
|
|
13
13
|
const createLoginPageSubmitHandler = (authConfig) => {
|
|
@@ -22,7 +22,8 @@ const createLoginPageSubmitHandler = (authConfig) => {
|
|
|
22
22
|
res.status(401).type("html").send(
|
|
23
23
|
renderLoginPage({
|
|
24
24
|
nextPath,
|
|
25
|
-
errorMessage: "Invalid password"
|
|
25
|
+
errorMessage: "Invalid password",
|
|
26
|
+
csrfToken: res.locals._csrf
|
|
26
27
|
})
|
|
27
28
|
).end();
|
|
28
29
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/auth/http/pages.ts"],"sourcesContent":["import type { AuthConfig } from '~/modules/auth-mode.js';\nimport type { Controller } from '~/types/index.js';\nimport { compareSharedSecret, destroySession, regenerateSession, sanitizeRedirectPath } from '../service.js';\nimport { renderLoginPage } from './login-page.js';\n\nexport const createLoginPageHandler = (authConfig: AuthConfig): Controller => {\n return async (req, res) => {\n if (authConfig.mode !== 'password' || req.session?.authenticated) {\n res.redirect(303, sanitizeRedirectPath(req.query.next));\n return;\n }\n\n const nextPath = sanitizeRedirectPath(req.query.next);\n res.status(200).type('html').send(renderLoginPage({ nextPath })).end();\n };\n};\n\nexport const createLoginPageSubmitHandler = (authConfig: AuthConfig): Controller => {\n return async (req, res) => {\n const nextPath = sanitizeRedirectPath(req.body?.next);\n\n if (authConfig.mode !== 'password' || !authConfig.password) {\n res.redirect(303, nextPath);\n return;\n }\n\n const password = typeof req.body?.password === 'string' ? req.body.password : '';\n\n if (!password || !compareSharedSecret(authConfig.password, password)) {\n res.status(401)\n .type('html')\n .send(\n renderLoginPage({\n nextPath,\n errorMessage: 'Invalid password',\n }),\n )\n .end();\n return;\n }\n\n await regenerateSession(req);\n req.session.authenticated = true;\n\n res.redirect(303, nextPath);\n };\n};\n\nexport const createLogoutPageHandler = (authConfig: AuthConfig): Controller => {\n return async (req, res) => {\n if (authConfig.mode === 'password') {\n await destroySession(req);\n res.redirect(303, '/login');\n return;\n }\n\n res.redirect(303, '/');\n };\n};\n"],"mappings":"AAEA,SAAS,qBAAqB,gBAAgB,mBAAmB,4BAA4B;AAC7F,SAAS,uBAAuB;AAEzB,MAAM,yBAAyB,CAAC,eAAuC;AAC1E,SAAO,OAAO,KAAK,QAAQ;AACvB,QAAI,WAAW,SAAS,cAAc,IAAI,SAAS,eAAe;AAC9D,UAAI,SAAS,KAAK,qBAAqB,IAAI,MAAM,IAAI,CAAC;AACtD;AAAA,IACJ;AAEA,UAAM,WAAW,qBAAqB,IAAI,MAAM,IAAI;AACpD,QAAI,OAAO,GAAG,
|
|
1
|
+
{"version":3,"sources":["../../../../src/features/auth/http/pages.ts"],"sourcesContent":["import type { AuthConfig } from '~/modules/auth-mode.js';\nimport type { Controller } from '~/types/index.js';\nimport { compareSharedSecret, destroySession, regenerateSession, sanitizeRedirectPath } from '../service.js';\nimport { renderLoginPage } from './login-page.js';\n\nexport const createLoginPageHandler = (authConfig: AuthConfig): Controller => {\n return async (req, res) => {\n if (authConfig.mode !== 'password' || req.session?.authenticated) {\n res.redirect(303, sanitizeRedirectPath(req.query.next));\n return;\n }\n\n const nextPath = sanitizeRedirectPath(req.query.next);\n res.status(200)\n .type('html')\n .send(renderLoginPage({ nextPath, csrfToken: res.locals._csrf }))\n .end();\n };\n};\n\nexport const createLoginPageSubmitHandler = (authConfig: AuthConfig): Controller => {\n return async (req, res) => {\n const nextPath = sanitizeRedirectPath(req.body?.next);\n\n if (authConfig.mode !== 'password' || !authConfig.password) {\n res.redirect(303, nextPath);\n return;\n }\n\n const password = typeof req.body?.password === 'string' ? req.body.password : '';\n\n if (!password || !compareSharedSecret(authConfig.password, password)) {\n res.status(401)\n .type('html')\n .send(\n renderLoginPage({\n nextPath,\n errorMessage: 'Invalid password',\n csrfToken: res.locals._csrf,\n }),\n )\n .end();\n return;\n }\n\n await regenerateSession(req);\n req.session.authenticated = true;\n\n res.redirect(303, nextPath);\n };\n};\n\nexport const createLogoutPageHandler = (authConfig: AuthConfig): Controller => {\n return async (req, res) => {\n if (authConfig.mode === 'password') {\n await destroySession(req);\n res.redirect(303, '/login');\n return;\n }\n\n res.redirect(303, '/');\n };\n};\n"],"mappings":"AAEA,SAAS,qBAAqB,gBAAgB,mBAAmB,4BAA4B;AAC7F,SAAS,uBAAuB;AAEzB,MAAM,yBAAyB,CAAC,eAAuC;AAC1E,SAAO,OAAO,KAAK,QAAQ;AACvB,QAAI,WAAW,SAAS,cAAc,IAAI,SAAS,eAAe;AAC9D,UAAI,SAAS,KAAK,qBAAqB,IAAI,MAAM,IAAI,CAAC;AACtD;AAAA,IACJ;AAEA,UAAM,WAAW,qBAAqB,IAAI,MAAM,IAAI;AACpD,QAAI,OAAO,GAAG,EACT,KAAK,MAAM,EACX,KAAK,gBAAgB,EAAE,UAAU,WAAW,IAAI,OAAO,MAAM,CAAC,CAAC,EAC/D,IAAI;AAAA,EACb;AACJ;AAEO,MAAM,+BAA+B,CAAC,eAAuC;AAChF,SAAO,OAAO,KAAK,QAAQ;AACvB,UAAM,WAAW,qBAAqB,IAAI,MAAM,IAAI;AAEpD,QAAI,WAAW,SAAS,cAAc,CAAC,WAAW,UAAU;AACxD,UAAI,SAAS,KAAK,QAAQ;AAC1B;AAAA,IACJ;AAEA,UAAM,WAAW,OAAO,IAAI,MAAM,aAAa,WAAW,IAAI,KAAK,WAAW;AAE9E,QAAI,CAAC,YAAY,CAAC,oBAAoB,WAAW,UAAU,QAAQ,GAAG;AAClE,UAAI,OAAO,GAAG,EACT,KAAK,MAAM,EACX;AAAA,QACG,gBAAgB;AAAA,UACZ;AAAA,UACA,cAAc;AAAA,UACd,WAAW,IAAI,OAAO;AAAA,QAC1B,CAAC;AAAA,MACL,EACC,IAAI;AACT;AAAA,IACJ;AAEA,UAAM,kBAAkB,GAAG;AAC3B,QAAI,QAAQ,gBAAgB;AAE5B,QAAI,SAAS,KAAK,QAAQ;AAAA,EAC9B;AACJ;AAEO,MAAM,0BAA0B,CAAC,eAAuC;AAC3E,SAAO,OAAO,KAAK,QAAQ;AACvB,QAAI,WAAW,SAAS,YAAY;AAChC,YAAM,eAAe,GAAG;AACxB,UAAI,SAAS,KAAK,QAAQ;AAC1B;AAAA,IACJ;AAEA,QAAI,SAAS,KAAK,GAAG;AAAA,EACzB;AACJ;","names":[]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { buildUnauthorizedGraphqlPayload, buildUnauthorizedPayload } from "@baejino/auth";
|
|
2
2
|
import session from "express-session";
|
|
3
3
|
import { GraphQLError } from "graphql";
|
|
4
|
+
import lusca from "lusca";
|
|
4
5
|
const JSON_HEADERS = { "Content-Type": "application/json" };
|
|
5
6
|
const isAuthenticatedRequest = (req) => Boolean(req.session?.authenticated);
|
|
6
7
|
const createSessionMiddleware = (authConfig) => {
|
|
@@ -20,6 +21,22 @@ const createSessionMiddleware = (authConfig) => {
|
|
|
20
21
|
}
|
|
21
22
|
});
|
|
22
23
|
};
|
|
24
|
+
const createCsrfProtection = (authConfig) => {
|
|
25
|
+
if (authConfig.mode !== "password") {
|
|
26
|
+
return (_req, _res, next) => next();
|
|
27
|
+
}
|
|
28
|
+
return lusca.csrf({
|
|
29
|
+
angular: true,
|
|
30
|
+
cookie: {
|
|
31
|
+
options: {
|
|
32
|
+
path: "/",
|
|
33
|
+
sameSite: "lax",
|
|
34
|
+
secure: process.env.NODE_ENV === "production"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
blocklist: ["/api/mcp", "/graphql/mcp"]
|
|
38
|
+
});
|
|
39
|
+
};
|
|
23
40
|
const requireSessionForWrite = (authConfig) => {
|
|
24
41
|
return (req, res, next) => {
|
|
25
42
|
if (authConfig.mode === "open" || isAuthenticatedRequest(req)) {
|
|
@@ -59,6 +76,7 @@ const createMutationAuthValidationRule = () => {
|
|
|
59
76
|
};
|
|
60
77
|
};
|
|
61
78
|
export {
|
|
79
|
+
createCsrfProtection,
|
|
62
80
|
createMutationAuthValidationRule,
|
|
63
81
|
createSessionMiddleware,
|
|
64
82
|
isAuthenticatedRequest,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/modules/auth-guard.ts"],"sourcesContent":["import { buildUnauthorizedGraphqlPayload, buildUnauthorizedPayload } from '@baejino/auth';\nimport type { NextFunction, Request, RequestHandler, Response } from 'express';\nimport session from 'express-session';\nimport type { ValidationRule } from 'graphql';\nimport { GraphQLError } from 'graphql';\n\nimport type { AuthConfig } from './auth-mode.js';\n\nconst JSON_HEADERS = { 'Content-Type': 'application/json' };\n\nexport const isAuthenticatedRequest = (req: Request) => Boolean(req.session?.authenticated);\n\nexport const createSessionMiddleware = (authConfig: AuthConfig): RequestHandler => {\n if (authConfig.mode !== 'password') {\n return (_req, _res, next) => next();\n }\n\n return session({\n secret: authConfig.sessionSecret,\n name: authConfig.cookieName,\n resave: false,\n saveUninitialized: false,\n cookie: {\n httpOnly: true,\n sameSite: 'lax',\n secure: process.env.NODE_ENV === 'production',\n path: '/',\n },\n });\n};\n\nexport const requireSessionForWrite = (authConfig: AuthConfig): RequestHandler => {\n return (req: Request, res: Response, next: NextFunction) => {\n if (authConfig.mode === 'open' || isAuthenticatedRequest(req)) {\n next();\n return;\n }\n\n res.status(401).set(JSON_HEADERS).json(buildUnauthorizedPayload()).end();\n };\n};\n\nexport const requireSessionForGraphql = (authConfig: AuthConfig): RequestHandler => {\n return (req: Request, res: Response, next: NextFunction) => {\n if (authConfig.mode === 'open' || isAuthenticatedRequest(req)) {\n next();\n return;\n }\n\n res.status(401).set(JSON_HEADERS).json(buildUnauthorizedGraphqlPayload()).end();\n };\n};\n\nexport const createMutationAuthValidationRule = (): ValidationRule => {\n return (context) => {\n return {\n OperationDefinition(node) {\n if (node.operation !== 'mutation') {\n return;\n }\n\n const unauthorizedError = buildUnauthorizedGraphqlPayload().errors[0];\n\n context.reportError(\n new GraphQLError(unauthorizedError.message, {\n nodes: [node],\n extensions: {\n code: unauthorizedError.extensions.code,\n },\n }),\n );\n },\n };\n };\n};\n"],"mappings":"AAAA,SAAS,iCAAiC,gCAAgC;AAE1E,OAAO,aAAa;AAEpB,SAAS,oBAAoB;
|
|
1
|
+
{"version":3,"sources":["../../src/modules/auth-guard.ts"],"sourcesContent":["import { buildUnauthorizedGraphqlPayload, buildUnauthorizedPayload } from '@baejino/auth';\nimport type { NextFunction, Request, RequestHandler, Response } from 'express';\nimport session from 'express-session';\nimport type { ValidationRule } from 'graphql';\nimport { GraphQLError } from 'graphql';\nimport lusca from 'lusca';\n\nimport type { AuthConfig } from './auth-mode.js';\n\nconst JSON_HEADERS = { 'Content-Type': 'application/json' };\n\nexport const isAuthenticatedRequest = (req: Request) => Boolean(req.session?.authenticated);\n\nexport const createSessionMiddleware = (authConfig: AuthConfig): RequestHandler => {\n if (authConfig.mode !== 'password') {\n return (_req, _res, next) => next();\n }\n\n return session({\n secret: authConfig.sessionSecret,\n name: authConfig.cookieName,\n resave: false,\n saveUninitialized: false,\n cookie: {\n httpOnly: true,\n sameSite: 'lax',\n secure: process.env.NODE_ENV === 'production',\n path: '/',\n },\n });\n};\n\nexport const createCsrfProtection = (authConfig: AuthConfig): RequestHandler => {\n if (authConfig.mode !== 'password') {\n return (_req, _res, next) => next();\n }\n\n return lusca.csrf({\n angular: true,\n cookie: {\n options: {\n path: '/',\n sameSite: 'lax',\n secure: process.env.NODE_ENV === 'production',\n },\n },\n blocklist: ['/api/mcp', '/graphql/mcp'],\n });\n};\n\nexport const requireSessionForWrite = (authConfig: AuthConfig): RequestHandler => {\n return (req: Request, res: Response, next: NextFunction) => {\n if (authConfig.mode === 'open' || isAuthenticatedRequest(req)) {\n next();\n return;\n }\n\n res.status(401).set(JSON_HEADERS).json(buildUnauthorizedPayload()).end();\n };\n};\n\nexport const requireSessionForGraphql = (authConfig: AuthConfig): RequestHandler => {\n return (req: Request, res: Response, next: NextFunction) => {\n if (authConfig.mode === 'open' || isAuthenticatedRequest(req)) {\n next();\n return;\n }\n\n res.status(401).set(JSON_HEADERS).json(buildUnauthorizedGraphqlPayload()).end();\n };\n};\n\nexport const createMutationAuthValidationRule = (): ValidationRule => {\n return (context) => {\n return {\n OperationDefinition(node) {\n if (node.operation !== 'mutation') {\n return;\n }\n\n const unauthorizedError = buildUnauthorizedGraphqlPayload().errors[0];\n\n context.reportError(\n new GraphQLError(unauthorizedError.message, {\n nodes: [node],\n extensions: {\n code: unauthorizedError.extensions.code,\n },\n }),\n );\n },\n };\n };\n};\n"],"mappings":"AAAA,SAAS,iCAAiC,gCAAgC;AAE1E,OAAO,aAAa;AAEpB,SAAS,oBAAoB;AAC7B,OAAO,WAAW;AAIlB,MAAM,eAAe,EAAE,gBAAgB,mBAAmB;AAEnD,MAAM,yBAAyB,CAAC,QAAiB,QAAQ,IAAI,SAAS,aAAa;AAEnF,MAAM,0BAA0B,CAAC,eAA2C;AAC/E,MAAI,WAAW,SAAS,YAAY;AAChC,WAAO,CAAC,MAAM,MAAM,SAAS,KAAK;AAAA,EACtC;AAEA,SAAO,QAAQ;AAAA,IACX,QAAQ,WAAW;AAAA,IACnB,MAAM,WAAW;AAAA,IACjB,QAAQ;AAAA,IACR,mBAAmB;AAAA,IACnB,QAAQ;AAAA,MACJ,UAAU;AAAA,MACV,UAAU;AAAA,MACV,QAAQ,QAAQ,IAAI,aAAa;AAAA,MACjC,MAAM;AAAA,IACV;AAAA,EACJ,CAAC;AACL;AAEO,MAAM,uBAAuB,CAAC,eAA2C;AAC5E,MAAI,WAAW,SAAS,YAAY;AAChC,WAAO,CAAC,MAAM,MAAM,SAAS,KAAK;AAAA,EACtC;AAEA,SAAO,MAAM,KAAK;AAAA,IACd,SAAS;AAAA,IACT,QAAQ;AAAA,MACJ,SAAS;AAAA,QACL,MAAM;AAAA,QACN,UAAU;AAAA,QACV,QAAQ,QAAQ,IAAI,aAAa;AAAA,MACrC;AAAA,IACJ;AAAA,IACA,WAAW,CAAC,YAAY,cAAc;AAAA,EAC1C,CAAC;AACL;AAEO,MAAM,yBAAyB,CAAC,eAA2C;AAC9E,SAAO,CAAC,KAAc,KAAe,SAAuB;AACxD,QAAI,WAAW,SAAS,UAAU,uBAAuB,GAAG,GAAG;AAC3D,WAAK;AACL;AAAA,IACJ;AAEA,QAAI,OAAO,GAAG,EAAE,IAAI,YAAY,EAAE,KAAK,yBAAyB,CAAC,EAAE,IAAI;AAAA,EAC3E;AACJ;AAEO,MAAM,2BAA2B,CAAC,eAA2C;AAChF,SAAO,CAAC,KAAc,KAAe,SAAuB;AACxD,QAAI,WAAW,SAAS,UAAU,uBAAuB,GAAG,GAAG;AAC3D,WAAK;AACL;AAAA,IACJ;AAEA,QAAI,OAAO,GAAG,EAAE,IAAI,YAAY,EAAE,KAAK,gCAAgC,CAAC,EAAE,IAAI;AAAA,EAClF;AACJ;AAEO,MAAM,mCAAmC,MAAsB;AAClE,SAAO,CAAC,YAAY;AAChB,WAAO;AAAA,MACH,oBAAoB,MAAM;AACtB,YAAI,KAAK,cAAc,YAAY;AAC/B;AAAA,QACJ;AAEA,cAAM,oBAAoB,gCAAgC,EAAE,OAAO,CAAC;AAEpE,gBAAQ;AAAA,UACJ,IAAI,aAAa,kBAAkB,SAAS;AAAA,YACxC,OAAO,CAAC,IAAI;AAAA,YACZ,YAAY;AAAA,cACR,MAAM,kBAAkB,WAAW;AAAA,YACvC;AAAA,UACJ,CAAC;AAAA,QACL;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AACJ;","names":[]}
|
|
@@ -24,6 +24,13 @@ const createErrorHandler = () => {
|
|
|
24
24
|
}).end();
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
|
+
if (error instanceof Error && error.message.startsWith("CSRF token ")) {
|
|
28
|
+
res.status(403).json({
|
|
29
|
+
code: "CSRF_TOKEN_INVALID",
|
|
30
|
+
message: error.message
|
|
31
|
+
}).end();
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
27
34
|
const message = error instanceof Error ? error.stack || error.message : String(error);
|
|
28
35
|
process.stderr.write(`[error] ${message}
|
|
29
36
|
`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/modules/error-handler.ts"],"sourcesContent":["import type { ErrorRequestHandler } from 'express';\n\nexport class AppError extends Error {\n code: string;\n status: number;\n\n constructor(status: number, code: string, message: string) {\n super(message);\n this.name = 'AppError';\n this.status = status;\n this.code = code;\n }\n}\n\nexport const createAppError = (status: number, code: string, message: string) => {\n return new AppError(status, code, message);\n};\n\nexport const createErrorHandler = (): ErrorRequestHandler => {\n return (error, _req, res, next) => {\n if (res.headersSent) {\n next(error);\n return;\n }\n\n if (error instanceof AppError) {\n res.status(error.status)\n .json({\n code: error.code,\n message: error.message,\n })\n .end();\n return;\n }\n\n const message = error instanceof Error ? error.stack || error.message : String(error);\n process.stderr.write(`[error] ${message}\\n`);\n\n res.status(500)\n .json({\n code: 'INTERNAL_SERVER_ERROR',\n message: 'Internal Server Error',\n })\n .end();\n };\n};\n"],"mappings":"AAEO,MAAM,iBAAiB,MAAM;AAAA,EAChC;AAAA,EACA;AAAA,EAEA,YAAY,QAAgB,MAAc,SAAiB;AACvD,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,OAAO;AAAA,EAChB;AACJ;AAEO,MAAM,iBAAiB,CAAC,QAAgB,MAAc,YAAoB;AAC7E,SAAO,IAAI,SAAS,QAAQ,MAAM,OAAO;AAC7C;AAEO,MAAM,qBAAqB,MAA2B;AACzD,SAAO,CAAC,OAAO,MAAM,KAAK,SAAS;AAC/B,QAAI,IAAI,aAAa;AACjB,WAAK,KAAK;AACV;AAAA,IACJ;AAEA,QAAI,iBAAiB,UAAU;AAC3B,UAAI,OAAO,MAAM,MAAM,EAClB,KAAK;AAAA,QACF,MAAM,MAAM;AAAA,QACZ,SAAS,MAAM;AAAA,MACnB,CAAC,EACA,IAAI;AACT;AAAA,IACJ;AAEA,UAAM,UAAU,iBAAiB,QAAQ,MAAM,SAAS,MAAM,UAAU,OAAO,KAAK;AACpF,YAAQ,OAAO,MAAM,WAAW,OAAO;AAAA,CAAI;AAE3C,QAAI,OAAO,GAAG,EACT,KAAK;AAAA,MACF,MAAM;AAAA,MACN,SAAS;AAAA,IACb,CAAC,EACA,IAAI;AAAA,EACb;AACJ;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/modules/error-handler.ts"],"sourcesContent":["import type { ErrorRequestHandler } from 'express';\n\nexport class AppError extends Error {\n code: string;\n status: number;\n\n constructor(status: number, code: string, message: string) {\n super(message);\n this.name = 'AppError';\n this.status = status;\n this.code = code;\n }\n}\n\nexport const createAppError = (status: number, code: string, message: string) => {\n return new AppError(status, code, message);\n};\n\nexport const createErrorHandler = (): ErrorRequestHandler => {\n return (error, _req, res, next) => {\n if (res.headersSent) {\n next(error);\n return;\n }\n\n if (error instanceof AppError) {\n res.status(error.status)\n .json({\n code: error.code,\n message: error.message,\n })\n .end();\n return;\n }\n\n if (error instanceof Error && error.message.startsWith('CSRF token ')) {\n res.status(403)\n .json({\n code: 'CSRF_TOKEN_INVALID',\n message: error.message,\n })\n .end();\n return;\n }\n\n const message = error instanceof Error ? error.stack || error.message : String(error);\n process.stderr.write(`[error] ${message}\\n`);\n\n res.status(500)\n .json({\n code: 'INTERNAL_SERVER_ERROR',\n message: 'Internal Server Error',\n })\n .end();\n };\n};\n"],"mappings":"AAEO,MAAM,iBAAiB,MAAM;AAAA,EAChC;AAAA,EACA;AAAA,EAEA,YAAY,QAAgB,MAAc,SAAiB;AACvD,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,OAAO;AAAA,EAChB;AACJ;AAEO,MAAM,iBAAiB,CAAC,QAAgB,MAAc,YAAoB;AAC7E,SAAO,IAAI,SAAS,QAAQ,MAAM,OAAO;AAC7C;AAEO,MAAM,qBAAqB,MAA2B;AACzD,SAAO,CAAC,OAAO,MAAM,KAAK,SAAS;AAC/B,QAAI,IAAI,aAAa;AACjB,WAAK,KAAK;AACV;AAAA,IACJ;AAEA,QAAI,iBAAiB,UAAU;AAC3B,UAAI,OAAO,MAAM,MAAM,EAClB,KAAK;AAAA,QACF,MAAM,MAAM;AAAA,QACZ,SAAS,MAAM;AAAA,MACnB,CAAC,EACA,IAAI;AACT;AAAA,IACJ;AAEA,QAAI,iBAAiB,SAAS,MAAM,QAAQ,WAAW,aAAa,GAAG;AACnE,UAAI,OAAO,GAAG,EACT,KAAK;AAAA,QACF,MAAM;AAAA,QACN,SAAS,MAAM;AAAA,MACnB,CAAC,EACA,IAAI;AACT;AAAA,IACJ;AAEA,UAAM,UAAU,iBAAiB,QAAQ,MAAM,SAAS,MAAM,UAAU,OAAO,KAAK;AACpF,YAAQ,OAAO,MAAM,WAAW,OAAO;AAAA,CAAI;AAE3C,QAAI,OAAO,GAAG,EACT,KAAK;AAAA,MACF,MAAM;AAAA,MACN,SAAS;AAAA,IACb,CAAC,EACA,IAAI;AAAA,EACb;AACJ;","names":[]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { rateLimit } from "express-rate-limit";
|
|
2
|
+
const AUTH_RATE_LIMIT_MESSAGE = "Too many authentication attempts. Please try again later.";
|
|
3
|
+
const createAuthAttemptRateLimit = () => rateLimit({
|
|
4
|
+
windowMs: 15 * 60 * 1e3,
|
|
5
|
+
limit: 10,
|
|
6
|
+
standardHeaders: true,
|
|
7
|
+
legacyHeaders: false,
|
|
8
|
+
handler: (_req, res) => {
|
|
9
|
+
res.status(429).json({
|
|
10
|
+
code: "AUTH_RATE_LIMITED",
|
|
11
|
+
message: AUTH_RATE_LIMIT_MESSAGE
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
export {
|
|
16
|
+
createAuthAttemptRateLimit
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=rate-limit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/modules/rate-limit.ts"],"sourcesContent":["import { rateLimit } from 'express-rate-limit';\n\nconst AUTH_RATE_LIMIT_MESSAGE = 'Too many authentication attempts. Please try again later.';\n\nexport const createAuthAttemptRateLimit = () =>\n rateLimit({\n windowMs: 15 * 60 * 1000,\n limit: 10,\n standardHeaders: true,\n legacyHeaders: false,\n handler: (_req, res) => {\n res.status(429).json({\n code: 'AUTH_RATE_LIMITED',\n message: AUTH_RATE_LIMIT_MESSAGE,\n });\n },\n });\n"],"mappings":"AAAA,SAAS,iBAAiB;AAE1B,MAAM,0BAA0B;AAEzB,MAAM,6BAA6B,MACtC,UAAU;AAAA,EACN,UAAU,KAAK,KAAK;AAAA,EACpB,OAAO;AAAA,EACP,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,SAAS,CAAC,MAAM,QAAQ;AACpB,QAAI,OAAO,GAAG,EAAE,KAAK;AAAA,MACjB,MAAM;AAAA,MACN,SAAS;AAAA,IACb,CAAC;AAAA,EACL;AACJ,CAAC;","names":[]}
|
|
@@ -8,10 +8,11 @@ import {
|
|
|
8
8
|
createMcpAdminStatusHandler
|
|
9
9
|
} from "../features/mcp-admin/http/handlers.js";
|
|
10
10
|
import { requireSessionForWrite } from "../modules/auth-guard.js";
|
|
11
|
+
import { createAuthAttemptRateLimit } from "../modules/rate-limit.js";
|
|
11
12
|
import { createServerEventsHandler } from "../modules/server-events-handler.js";
|
|
12
13
|
import useAsync from "../modules/use-async.js";
|
|
13
14
|
import { createMcpRouter } from "./mcp.js";
|
|
14
|
-
const createApiRouter = (authConfig, mcpAdminService) => Router().use("/mcp", createMcpRouter(authConfig, mcpAdminService)).post("/auth/login", useAsync(createLoginHandler(authConfig))).post("/auth/logout", useAsync(createLogoutHandler(authConfig))).get("/auth/session", useAsync(createSessionStatusHandler(authConfig))).get(
|
|
15
|
+
const createApiRouter = (authConfig, mcpAdminService) => Router().use("/mcp", createMcpRouter(authConfig, mcpAdminService)).post("/auth/login", createAuthAttemptRateLimit(), useAsync(createLoginHandler(authConfig))).post("/auth/logout", useAsync(createLogoutHandler(authConfig))).get("/auth/session", useAsync(createSessionStatusHandler(authConfig))).get(
|
|
15
16
|
"/mcp-admin/status",
|
|
16
17
|
requireSessionForWrite(authConfig),
|
|
17
18
|
useAsync(createMcpAdminStatusHandler(mcpAdminService))
|