ocean-brain 0.8.0 → 0.8.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/README.md +113 -0
- package/dist/mcp.js +230 -291
- package/package.json +6 -5
- package/server/client/dist/assets/ArrowRight.es-g2YZTklZ.js +1 -0
- package/server/client/dist/assets/Calendar-BP6HTuSn.js +25 -0
- package/server/client/dist/assets/Callout-B_IPSF_5.js +1 -0
- package/server/client/dist/assets/Copy.es-CNxe4ujr.js +1 -0
- package/server/client/dist/assets/Graph-D9GeO71k.js +1 -0
- package/server/client/dist/assets/Graph-Xha3fwhp.js +46 -0
- package/server/client/dist/assets/Image-BLEjLUqd.js +1 -0
- package/server/client/dist/assets/Image.es-DnON8cv2.js +1 -0
- package/server/client/dist/assets/Note-DjrCYtat.js +24 -0
- package/server/client/dist/assets/NotePropertiesPanel-2DgXEM4B.js +2 -0
- package/server/client/dist/assets/Plus.es-CQ8wn2is.js +1 -0
- package/server/client/dist/assets/Reminders-B4l3KdlK.js +1 -0
- package/server/client/dist/assets/Search-BN5sf7bE.js +1 -0
- package/server/client/dist/assets/SurfaceCard-BZm73nyS.js +1 -0
- package/server/client/dist/assets/Tag-oSnmViVp.js +1 -0
- package/server/client/dist/assets/TagNotes-BDTCcJcL.js +1 -0
- package/server/client/dist/assets/Trash.es-0aPpA-3S.js +1 -0
- package/server/client/dist/assets/ViewNotes-CiZtGJNE.js +1 -0
- package/server/client/dist/assets/{ViewSectionDialog-CzskgmMF.js → ViewSectionDialog-Ctl_694Y.js} +17 -17
- package/server/client/dist/assets/Views-D-zlatYD.js +1 -0
- package/server/client/dist/assets/app-DmqIOMWF.css +1 -0
- package/server/client/dist/assets/app-cTRcKMGc.js +26 -0
- package/server/client/dist/assets/floating-ui.react-dom-wWLZ1CdM.js +1 -0
- package/server/client/dist/assets/{image.api-8dlMwzMd.js → image.api-CVuuvTBk.js} +1 -1
- package/server/client/dist/assets/index-DKJChPr4.js +1 -0
- package/server/client/dist/assets/manage-image-BZjaxp-f.js +1 -0
- package/server/client/dist/assets/manage-image-detail-DPv0FQ2m.js +1 -0
- package/server/client/dist/assets/{mcp-EDurbggR.js → mcp-CT_9IV2c.js} +2 -2
- package/server/client/dist/assets/mcp-admin-adapter-xAuyZc_M.js +1 -0
- package/server/client/dist/assets/note-core-Buwzyxi7.js +13 -0
- package/server/client/dist/assets/note-runtime-CPDVOFEo.js +168 -0
- package/server/client/dist/assets/note-ui-CHI-tzj-.js +2 -0
- package/server/client/dist/assets/{index-BEUqDuAZ.css → note-ui-DL8owV-U.css} +1 -1
- package/server/client/dist/assets/note.api-D_00ZzJC.js +356 -0
- package/server/client/dist/assets/{placeholder-DeKgSBnC.js → placeholder-DbdGiYGL.js} +4 -4
- package/server/client/dist/assets/preload-helper-BXl3LOEh.js +1 -0
- package/server/client/dist/assets/properties-D447wsWk.js +1 -0
- package/server/client/dist/assets/route-preload.js +2 -0
- package/server/client/dist/assets/{tag.api-Dl8DQd0m.js → tag.api-CX0SE06J.js} +1 -1
- package/server/client/dist/assets/time-B3pt8vt4.js +9 -0
- package/server/client/dist/assets/trash-8sH7EZgc.js +1 -0
- package/server/client/dist/assets/url-BSnWpmJx.js +1 -0
- package/server/client/dist/assets/{useReminderMutate-CoXXqJY2.js → useReminderMutate-CLK1tHvT.js} +4 -4
- package/server/client/dist/index.html +10 -5
- package/server/dist/app.js +1 -2
- package/server/dist/features/auth/http/api.js +0 -1
- package/server/dist/features/auth/http/login-page.js +272 -5
- package/server/dist/features/auth/http/pages.js +20 -3
- package/server/dist/features/auth/service.js +3 -2
- package/server/dist/features/cache/graphql/cache.field.resolver.js +0 -1
- package/server/dist/features/cache/graphql/cache.mutation.resolver.js +0 -1
- package/server/dist/features/cache/graphql/cache.query.resolver.js +0 -1
- package/server/dist/features/cache/graphql/cache.resolver.js +0 -1
- package/server/dist/features/cache/graphql/cache.type-defs.js +0 -1
- package/server/dist/features/cache/graphql/index.js +0 -1
- package/server/dist/features/image/graphql/image.field.resolver.js +0 -1
- package/server/dist/features/image/graphql/image.mutation.resolver.js +0 -1
- package/server/dist/features/image/graphql/image.query.resolver.js +0 -1
- package/server/dist/features/image/graphql/image.resolver.js +0 -1
- package/server/dist/features/image/graphql/image.type-defs.js +0 -1
- package/server/dist/features/image/graphql/index.js +0 -1
- package/server/dist/features/image/http/upload.js +0 -1
- package/server/dist/features/image/services/delete.js +0 -1
- package/server/dist/features/image/services/upload.js +0 -1
- package/server/dist/features/image/services/validation.js +0 -1
- package/server/dist/features/mcp-admin/http/handlers.js +0 -1
- package/server/dist/features/mcp-admin/service.js +0 -1
- package/server/dist/features/note/graphql/index.js +0 -1
- package/server/dist/features/note/graphql/note.field.resolver.js +0 -1
- package/server/dist/features/note/graphql/note.mutation.resolver.js +0 -1
- package/server/dist/features/note/graphql/note.query.resolver.js +0 -1
- package/server/dist/features/note/graphql/note.resolver.js +0 -1
- package/server/dist/features/note/graphql/note.type-defs.js +0 -1
- package/server/dist/features/note/http/mcp.js +0 -1
- package/server/dist/features/note/services/authoring.js +0 -1
- package/server/dist/features/note/services/cleanup.js +0 -1
- package/server/dist/features/note/services/content-blocks.js +0 -1
- package/server/dist/features/note/services/markdown-intent-write.js +0 -1
- package/server/dist/features/note/services/markdown-patch.js +0 -1
- package/server/dist/features/note/services/properties.js +0 -1
- package/server/dist/features/note/services/search-backfill.js +0 -1
- package/server/dist/features/note/services/search.js +0 -1
- package/server/dist/features/note/services/snapshot.js +0 -1
- package/server/dist/features/note/services/tag-filter.js +0 -1
- package/server/dist/features/note/services/trash.js +0 -1
- package/server/dist/features/note/services/write-conflict.js +0 -1
- package/server/dist/features/note/services/write.js +0 -1
- package/server/dist/features/placeholder/graphql/index.js +0 -1
- package/server/dist/features/placeholder/graphql/placeholder.field.resolver.js +0 -1
- package/server/dist/features/placeholder/graphql/placeholder.mutation.resolver.js +0 -1
- package/server/dist/features/placeholder/graphql/placeholder.query.resolver.js +0 -1
- package/server/dist/features/placeholder/graphql/placeholder.resolver.js +0 -1
- package/server/dist/features/placeholder/graphql/placeholder.type-defs.js +0 -1
- package/server/dist/features/reminder/graphql/index.js +0 -1
- package/server/dist/features/reminder/graphql/reminder.field.resolver.js +0 -1
- package/server/dist/features/reminder/graphql/reminder.mutation.resolver.js +0 -1
- package/server/dist/features/reminder/graphql/reminder.query.resolver.js +0 -1
- package/server/dist/features/reminder/graphql/reminder.resolver.js +0 -1
- package/server/dist/features/reminder/graphql/reminder.type-defs.js +0 -1
- package/server/dist/features/tag/graphql/index.js +0 -1
- package/server/dist/features/tag/graphql/tag.field.resolver.js +0 -1
- package/server/dist/features/tag/graphql/tag.mutation.resolver.js +0 -1
- package/server/dist/features/tag/graphql/tag.query.resolver.js +0 -1
- package/server/dist/features/tag/graphql/tag.resolver.js +0 -1
- package/server/dist/features/tag/graphql/tag.type-defs.js +0 -1
- package/server/dist/features/tag/http/mcp.js +0 -1
- package/server/dist/features/tag/services/organization.js +0 -1
- package/server/dist/features/view/graphql/index.js +0 -1
- package/server/dist/features/view/graphql/view.mutation.resolver.js +0 -1
- package/server/dist/features/view/graphql/view.query.resolver.js +0 -1
- package/server/dist/features/view/graphql/view.resolver.js +0 -1
- package/server/dist/features/view/graphql/view.type-defs.js +0 -1
- package/server/dist/features/view/services/workspace.js +0 -1
- package/server/dist/main.js +0 -1
- package/server/dist/models.js +0 -1
- package/server/dist/modules/app-version.js +0 -1
- package/server/dist/modules/auth-guard.js +0 -1
- package/server/dist/modules/auth-mode.js +0 -1
- package/server/dist/modules/auth-redirect.js +0 -1
- package/server/dist/modules/blocknote-markdown-editor.js +53 -0
- package/server/dist/modules/blocknote-tree.js +0 -1
- package/server/dist/modules/blocknote.js +272 -79
- package/server/dist/modules/data-maintenance.js +0 -1
- package/server/dist/modules/error-handler.js +8 -1
- package/server/dist/modules/graphql.js +0 -1
- package/server/dist/modules/logger.js +0 -1
- package/server/dist/modules/mcp-auth.js +0 -1
- package/server/dist/modules/mcp-token.js +0 -1
- package/server/dist/modules/prisma-runtime.js +0 -1
- package/server/dist/modules/rate-limit.js +0 -1
- package/server/dist/modules/recovery-retention.js +0 -1
- package/server/dist/modules/server-events-handler.js +0 -1
- package/server/dist/modules/server-events.js +0 -1
- package/server/dist/modules/session-store.js +0 -1
- package/server/dist/modules/use-async.js +0 -1
- package/server/dist/paths.js +0 -1
- package/server/dist/routes/api.js +0 -1
- package/server/dist/routes/auth-pages.js +0 -1
- package/server/dist/routes/client.js +0 -1
- package/server/dist/routes/graphql.js +0 -1
- package/server/dist/routes/index.js +0 -1
- package/server/dist/routes/mcp.js +0 -1
- package/server/dist/schema/index.js +0 -1
- package/server/dist/start.js +0 -1
- package/server/dist/types/index.js +0 -1
- package/server/dist/types/input.js +0 -1
- package/server/client/dist/assets/ArrowRight.es-C4zlc54Z.js +0 -1
- package/server/client/dist/assets/Calendar-COrN6Hjv.js +0 -25
- package/server/client/dist/assets/Callout-BK0K9E74.js +0 -1
- package/server/client/dist/assets/Copy.es-zm8f_XXX.js +0 -1
- package/server/client/dist/assets/Graph-BH1fzhue.js +0 -1
- package/server/client/dist/assets/Image-KXuHOG4b.js +0 -1
- package/server/client/dist/assets/Image.es-BKahRbIm.js +0 -1
- package/server/client/dist/assets/Note-C143cKKw.js +0 -12
- package/server/client/dist/assets/Plus.es-BqeC8T8h.js +0 -1
- package/server/client/dist/assets/Reminders-BYG5rz1M.js +0 -1
- package/server/client/dist/assets/Search-DBWsIMDP.js +0 -1
- package/server/client/dist/assets/SurfaceCard-CNSQfYfM.js +0 -1
- package/server/client/dist/assets/Tag-5aCfSO8Y.js +0 -1
- package/server/client/dist/assets/TagNotes-BPZjN-6l.js +0 -1
- package/server/client/dist/assets/Trash.es-CRQkTnXZ.js +0 -1
- package/server/client/dist/assets/ViewNotes-DGLNF96x.js +0 -1
- package/server/client/dist/assets/Views-DR5jT23G.js +0 -1
- package/server/client/dist/assets/graph-vendor-UTvF2NS_.js +0 -46
- package/server/client/dist/assets/index-DGIAh3ZY.js +0 -1
- package/server/client/dist/assets/index-VHp17GQX.js +0 -342
- package/server/client/dist/assets/manage-image-RqtWKas2.js +0 -1
- package/server/client/dist/assets/manage-image-detail-BTSIbLlQ.js +0 -1
- package/server/client/dist/assets/mcp-admin-adapter-DmGUo5G8.js +0 -1
- package/server/client/dist/assets/note-core-BklwyZHk.js +0 -180
- package/server/client/dist/assets/note-vendor-DkYKUmLo.js +0 -54
- package/server/client/dist/assets/properties-BjrZvOYn.js +0 -1
- package/server/client/dist/assets/trash-C5ntddLu.js +0 -1
- package/server/client/dist/fonts/Pretendard-Bold.woff +0 -0
- package/server/client/dist/fonts/Pretendard-Regular.woff +0 -0
- package/server/dist/app.js.map +0 -1
- package/server/dist/features/auth/http/api.js.map +0 -1
- package/server/dist/features/auth/http/login-page.js.map +0 -1
- package/server/dist/features/auth/http/pages.js.map +0 -1
- package/server/dist/features/auth/service.js.map +0 -1
- package/server/dist/features/cache/graphql/cache.field.resolver.js.map +0 -1
- package/server/dist/features/cache/graphql/cache.mutation.resolver.js.map +0 -1
- package/server/dist/features/cache/graphql/cache.query.resolver.js.map +0 -1
- package/server/dist/features/cache/graphql/cache.resolver.js.map +0 -1
- package/server/dist/features/cache/graphql/cache.type-defs.js.map +0 -1
- package/server/dist/features/cache/graphql/index.js.map +0 -1
- package/server/dist/features/image/graphql/image.field.resolver.js.map +0 -1
- package/server/dist/features/image/graphql/image.mutation.resolver.js.map +0 -1
- package/server/dist/features/image/graphql/image.query.resolver.js.map +0 -1
- package/server/dist/features/image/graphql/image.resolver.js.map +0 -1
- package/server/dist/features/image/graphql/image.type-defs.js.map +0 -1
- package/server/dist/features/image/graphql/index.js.map +0 -1
- package/server/dist/features/image/http/upload.js.map +0 -1
- package/server/dist/features/image/services/delete.js.map +0 -1
- package/server/dist/features/image/services/upload.js.map +0 -1
- package/server/dist/features/image/services/validation.js.map +0 -1
- package/server/dist/features/mcp-admin/http/handlers.js.map +0 -1
- package/server/dist/features/mcp-admin/service.js.map +0 -1
- package/server/dist/features/note/graphql/index.js.map +0 -1
- package/server/dist/features/note/graphql/note.field.resolver.js.map +0 -1
- package/server/dist/features/note/graphql/note.mutation.resolver.js.map +0 -1
- package/server/dist/features/note/graphql/note.query.resolver.js.map +0 -1
- package/server/dist/features/note/graphql/note.resolver.js.map +0 -1
- package/server/dist/features/note/graphql/note.type-defs.js.map +0 -1
- package/server/dist/features/note/http/mcp.js.map +0 -1
- package/server/dist/features/note/services/authoring.js.map +0 -1
- package/server/dist/features/note/services/cleanup.js.map +0 -1
- package/server/dist/features/note/services/content-blocks.js.map +0 -1
- package/server/dist/features/note/services/markdown-intent-write.js.map +0 -1
- package/server/dist/features/note/services/markdown-patch.js.map +0 -1
- package/server/dist/features/note/services/properties.js.map +0 -1
- package/server/dist/features/note/services/search-backfill.js.map +0 -1
- package/server/dist/features/note/services/search.js.map +0 -1
- package/server/dist/features/note/services/snapshot.js.map +0 -1
- package/server/dist/features/note/services/tag-filter.js.map +0 -1
- package/server/dist/features/note/services/trash.js.map +0 -1
- package/server/dist/features/note/services/write-conflict.js.map +0 -1
- package/server/dist/features/note/services/write.js.map +0 -1
- package/server/dist/features/placeholder/graphql/index.js.map +0 -1
- package/server/dist/features/placeholder/graphql/placeholder.field.resolver.js.map +0 -1
- package/server/dist/features/placeholder/graphql/placeholder.mutation.resolver.js.map +0 -1
- package/server/dist/features/placeholder/graphql/placeholder.query.resolver.js.map +0 -1
- package/server/dist/features/placeholder/graphql/placeholder.resolver.js.map +0 -1
- package/server/dist/features/placeholder/graphql/placeholder.type-defs.js.map +0 -1
- package/server/dist/features/reminder/graphql/index.js.map +0 -1
- package/server/dist/features/reminder/graphql/reminder.field.resolver.js.map +0 -1
- package/server/dist/features/reminder/graphql/reminder.mutation.resolver.js.map +0 -1
- package/server/dist/features/reminder/graphql/reminder.query.resolver.js.map +0 -1
- package/server/dist/features/reminder/graphql/reminder.resolver.js.map +0 -1
- package/server/dist/features/reminder/graphql/reminder.type-defs.js.map +0 -1
- package/server/dist/features/tag/graphql/index.js.map +0 -1
- package/server/dist/features/tag/graphql/tag.field.resolver.js.map +0 -1
- package/server/dist/features/tag/graphql/tag.mutation.resolver.js.map +0 -1
- package/server/dist/features/tag/graphql/tag.query.resolver.js.map +0 -1
- package/server/dist/features/tag/graphql/tag.resolver.js.map +0 -1
- package/server/dist/features/tag/graphql/tag.type-defs.js.map +0 -1
- package/server/dist/features/tag/http/mcp.js.map +0 -1
- package/server/dist/features/tag/services/organization.js.map +0 -1
- package/server/dist/features/view/graphql/index.js.map +0 -1
- package/server/dist/features/view/graphql/view.mutation.resolver.js.map +0 -1
- package/server/dist/features/view/graphql/view.query.resolver.js.map +0 -1
- package/server/dist/features/view/graphql/view.resolver.js.map +0 -1
- package/server/dist/features/view/graphql/view.type-defs.js.map +0 -1
- package/server/dist/features/view/services/workspace.js.map +0 -1
- package/server/dist/main.js.map +0 -1
- package/server/dist/models.js.map +0 -1
- package/server/dist/modules/app-version.js.map +0 -1
- package/server/dist/modules/auth-guard.js.map +0 -1
- package/server/dist/modules/auth-mode.js.map +0 -1
- package/server/dist/modules/auth-redirect.js.map +0 -1
- package/server/dist/modules/blocknote-tree.js.map +0 -1
- package/server/dist/modules/blocknote.js.map +0 -1
- package/server/dist/modules/data-maintenance.js.map +0 -1
- package/server/dist/modules/error-handler.js.map +0 -1
- package/server/dist/modules/graphql.js.map +0 -1
- package/server/dist/modules/logger.js.map +0 -1
- package/server/dist/modules/mcp-auth.js.map +0 -1
- package/server/dist/modules/mcp-token.js.map +0 -1
- package/server/dist/modules/prisma-runtime.js.map +0 -1
- package/server/dist/modules/rate-limit.js.map +0 -1
- package/server/dist/modules/recovery-retention.js.map +0 -1
- package/server/dist/modules/server-events-handler.js.map +0 -1
- package/server/dist/modules/server-events.js.map +0 -1
- package/server/dist/modules/session-store.js.map +0 -1
- package/server/dist/modules/use-async.js.map +0 -1
- package/server/dist/paths.js.map +0 -1
- package/server/dist/routes/api.js.map +0 -1
- package/server/dist/routes/auth-pages.js.map +0 -1
- package/server/dist/routes/client.js.map +0 -1
- package/server/dist/routes/graphql.js.map +0 -1
- package/server/dist/routes/index.js.map +0 -1
- package/server/dist/routes/mcp.js.map +0 -1
- package/server/dist/schema/index.js.map +0 -1
- package/server/dist/start.js.map +0 -1
- package/server/dist/types/index.js.map +0 -1
- package/server/dist/types/input.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as e,r as E}from"./floating-ui.react-dom-wWLZ1CdM.js";import{u as Q,e as k,m as F,q as L,i as M,d as _}from"./time-B3pt8vt4.js";import{aa as I,ai as K,U as O,a9 as B,b1 as H,T as i,b2 as U,b3 as W,aj as w,al as Y,Z as d,au as b,ak as $,ac as l,a8 as z,aA as G,b4 as V,at as y}from"./note.api-D_00ZzJC.js";import{S as C}from"./SurfaceCard-BZm73nyS.js";import{e as Z,N as J}from"./url-BSnWpmJx.js";import"./NotePropertiesPanel-2DgXEM4B.js";import"./Plus.es-CQ8wn2is.js";const m=25,v=K(Z),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=>M(a).format("YYYY-MM-DD HH:mm"),X=({note:a,onClose:o})=>{const s=a?.id??"",c=a?.title||"Untitled note",r=_({queryKey:i.notes.trashDetail(s),enabled:!!a,queryFn:async()=>{const h=await V(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(b,{variant:"ghost",size:"sm",onClick:o,children:"Close"})})]})},ee=()=>e.jsx(w,{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=O(),c=z(),r=Q(),[f,h]=E.useState(null),[x,j]=E.useState(null),{data:u}=B({queryKey:i.notes.trash({limit:m,offset:(a-1)*m}),queryFn:async()=>{const t=await H({limit:m,offset:(a-1)*m});if(t.type==="error")throw t;return t.trashedNotes}}),N=k({mutationFn:U,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:J,params:{id:t.restoreTrashedNote.id}})},onError:()=>{c("Failed to restore the note.")}}),p=k({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;j(null),p.mutate(t)},A=async t=>{const n=await G(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){j({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,q=u.notes.find(t=>t.id===f)??null;return u.notes.length===0?e.jsx(w,{title:"Trash",variant:"default",heading:T,description:R,children:e.jsx(Y,{title:"Trash is empty",description:`Delete a note and you can restore it here for ${S} days before permanent removal`})}):e.jsxs(w,{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(F,{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(b,{variant:"subtle",size:"sm",onClick:()=>h(t.id),children:"View content"}),e.jsx(b,{variant:"subtle",size:"sm",isLoading:N.isPending&&N.variables===t.id,onClick:()=>N.mutate(t.id),children:"Restore"}),e.jsx(b,{variant:"soft-danger",size:"sm",isLoading:p.isPending&&p.variables===t.id,onClick:()=>A(t.id),children:"Delete now"})]})]})},t.id))}),u.totalCount>m&&e.jsx($,{page:a,last:Math.ceil(u.totalCount/m),onChange:t=>{o({search:n=>({...n,page:t})})}})]}),e.jsx(X,{note:q,onClose:()=>h(null)}),e.jsx(L,{isOpen:!!x,title:g.title,description:g.description,references:x?.backReferences??[],confirmLabel:g.confirmLabel,confirmVariant:g.confirmVariant,onClose:()=>j(null),onConfirm:D})]})},de=()=>{const{page:a}=v.useSearch();return e.jsx(I,{fallback:e.jsx(ee,{}),errorTitle:"Failed to load trash",errorDescription:"Retry loading deleted notes",resetKeys:[a],children:e.jsx(te,{})})};export{de as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const E={HOME_ROUTE:"/",VIEWS_ROUTE:"/views",VIEW_NOTES_ROUTE:"/views/notes",CALENDAR_ROUTE:"/calendar",REMINDERS_ROUTE:"/reminders",GRAPH_ROUTE:"/graph",SEARCH_ROUTE:"/search",TAG_ROUTE:"/tag",NOTE_ROUTE:"/$id",TAG_NOTES_ROUTE:"/tag/$id",SETTINGS_ROUTE:"/setting",SETTINGS_MCP_ROUTE:"/setting/mcp",SETTINGS_TRASH_ROUTE:"/setting/trash",SETTINGS_MANAGE_IMAGE_ROUTE:"/setting/manage-image",SETTINGS_MANAGE_IMAGE_DETAIL_ROUTE:"/setting/manage-image/$id",SETTINGS_PLACEHOLDER_ROUTE:"/setting/placeholder",SETTINGS_PROPERTIES_ROUTE:"/setting/properties"},{HOME_ROUTE:T,VIEWS_ROUTE:_,VIEW_NOTES_ROUTE:R,CALENDAR_ROUTE:O,REMINDERS_ROUTE:S,GRAPH_ROUTE:U,SEARCH_ROUTE:s,TAG_ROUTE:a,NOTE_ROUTE:A,TAG_NOTES_ROUTE:G,SETTINGS_ROUTE:N,SETTINGS_MCP_ROUTE:I,SETTINGS_TRASH_ROUTE:e,SETTINGS_MANAGE_IMAGE_ROUTE:t,SETTINGS_MANAGE_IMAGE_DETAIL_ROUTE:i,SETTINGS_PLACEHOLDER_ROUTE:g,SETTINGS_PROPERTIES_ROUTE:n}=E;export{E as A,O as C,U as G,T as H,A as N,S as R,s as S,a as T,_ as V,N as a,G as b,R as c,I as d,e,t as f,i as g,g as h,n as i};
|
package/server/client/dist/assets/{useReminderMutate-CoXXqJY2.js → useReminderMutate-CLK1tHvT.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{j as y}from"./
|
|
1
|
+
import{j as y,r as l}from"./floating-ui.react-dom-wWLZ1CdM.js";import{a6 as u,a9 as f,T as n,U as R,a8 as $}from"./note.api-D_00ZzJC.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
|
|
@@ -34,7 +34,7 @@ import{j as y}from"./note-vendor-DkYKUmLo.js";import{h as u,a5 as f,q as n,k as
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
-
`,{pagination:g(e)}),
|
|
37
|
+
`,{pagination:g(e)}),I=async e=>{const{noteId:t,reminderDate:a,priority:o="medium",content:i}=e;return u(`
|
|
38
38
|
mutation CreateReminder($noteId: ID!, $reminderDate: String!, $priority: ReminderPriority, $content: String) {
|
|
39
39
|
createReminder(
|
|
40
40
|
noteId: $noteId,
|
|
@@ -51,7 +51,7 @@ import{j as y}from"./note-vendor-DkYKUmLo.js";import{h as u,a5 as f,q as n,k as
|
|
|
51
51
|
updatedAt
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
|
-
`,{noteId:t,reminderDate:a.toISOString(),priority:o,content:i})},
|
|
54
|
+
`,{noteId:t,reminderDate:a.toISOString(),priority:o,content:i})},q=async({id:e,reminderDate:t,completed:a,priority:o,content:i})=>{const r={id:e};return t&&(r.reminderDate=t.toISOString()),a!==void 0&&(r.completed=a),o&&(r.priority=o),i!==void 0&&(r.content=i),u(`
|
|
55
55
|
mutation UpdateReminder(
|
|
56
56
|
$id: ID!,
|
|
57
57
|
$reminderDate: String,
|
|
@@ -79,4 +79,4 @@ import{j as y}from"./note-vendor-DkYKUmLo.js";import{h as u,a5 as f,q as n,k as
|
|
|
79
79
|
mutation DeleteReminder($id: ID!) {
|
|
80
80
|
deleteReminder(id: $id)
|
|
81
81
|
}
|
|
82
|
-
`,{id:e});function
|
|
82
|
+
`,{id:e});function K({noteId:e,searchParams:t,render:a}){const{data:o}=f({queryKey:e?n.reminders.note(e,t):n.reminders.upcoming(t),queryFn:async()=>{if(e){const r=await D(e,t);if(r.type==="error")throw r;return r.noteReminders}const i=await A(t);if(i.type==="error")throw i;return i.upcomingReminders}});return y.jsx(y.Fragment,{children:a(o)})}function P(){const e=$(),t=R(),a=l.useCallback(async(r,m,d="medium",s,c)=>{const p=await I({noteId:r,reminderDate:m,priority:d,content:c});if(p.type==="error"){e(p.errors[0].message);return}await Promise.all([t.invalidateQueries({queryKey:n.reminders.noteAllPages(r),exact:!1}),t.invalidateQueries({queryKey:n.reminders.upcomingAllPages(),exact:!1}),t.invalidateQueries({queryKey:n.reminders.inDateRangeAll(),exact:!1})]),s&&s()},[t,e]),o=l.useCallback(async(r,m,d,s)=>{const c=await q({id:r,...d});if(c.type==="error"){e(c.errors[0].message);return}await Promise.all([t.invalidateQueries({queryKey:n.reminders.noteAllPages(m),exact:!1}),t.invalidateQueries({queryKey:n.reminders.upcomingAllPages(),exact:!1}),t.invalidateQueries({queryKey:n.reminders.inDateRangeAll(),exact:!1})]),s&&s()},[t,e]),i=l.useCallback(async(r,m,d)=>{const s=await x(r);if(s.type==="error"){e(s.errors[0].message);return}await Promise.all([t.invalidateQueries({queryKey:n.reminders.noteAllPages(m),exact:!1}),t.invalidateQueries({queryKey:n.reminders.upcomingAllPages(),exact:!1}),t.invalidateQueries({queryKey:n.reminders.inDateRangeAll(),exact:!1})]),d&&d()},[t,e]);return{onCreate:a,onUpdate:o,onDelete:i}}export{K as R,P as u};
|
|
@@ -2,15 +2,20 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
|
|
4
4
|
<head>
|
|
5
|
+
<script type="module" src="/assets/route-preload.js"></script>
|
|
6
|
+
|
|
5
7
|
<meta charset="UTF-8" />
|
|
6
8
|
<link rel="icon" type="image/png" href="/icon.png" />
|
|
7
9
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
8
10
|
<title>Ocean Brain</title>
|
|
9
|
-
<script type="module" crossorigin src="/assets/
|
|
10
|
-
<link rel="modulepreload" crossorigin href="/assets/
|
|
11
|
-
<link rel="modulepreload" crossorigin href="/assets/
|
|
12
|
-
<link rel="modulepreload" crossorigin href="/assets/note-
|
|
13
|
-
<link rel="
|
|
11
|
+
<script type="module" crossorigin src="/assets/app-cTRcKMGc.js"></script>
|
|
12
|
+
<link rel="modulepreload" crossorigin href="/assets/floating-ui.react-dom-wWLZ1CdM.js">
|
|
13
|
+
<link rel="modulepreload" crossorigin href="/assets/url-BSnWpmJx.js">
|
|
14
|
+
<link rel="modulepreload" crossorigin href="/assets/note.api-D_00ZzJC.js">
|
|
15
|
+
<link rel="modulepreload" crossorigin href="/assets/time-B3pt8vt4.js">
|
|
16
|
+
<link rel="modulepreload" crossorigin href="/assets/preload-helper-BXl3LOEh.js">
|
|
17
|
+
<link rel="modulepreload" crossorigin href="/assets/Graph-D9GeO71k.js">
|
|
18
|
+
<link rel="stylesheet" crossorigin href="/assets/app-DmqIOMWF.css">
|
|
14
19
|
</head>
|
|
15
20
|
|
|
16
21
|
<body>
|
package/server/dist/app.js
CHANGED
|
@@ -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, inflate: false })).use(express.json({ limit: "50mb", inflate: false })).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;
|
|
@@ -27,4 +27,3 @@ export {
|
|
|
27
27
|
createAppWithMcpAuth,
|
|
28
28
|
app_default as default
|
|
29
29
|
};
|
|
30
|
-
//# sourceMappingURL=app.js.map
|
|
@@ -1,9 +1,276 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
const LOGIN_ERROR_TOKEN = "<!-- OCEAN_BRAIN_LOGIN_ERROR -->";
|
|
3
3
|
const NEXT_PATH_TOKEN = "OCEAN_BRAIN_NEXT_PATH";
|
|
4
|
+
const SESSION_GENERATION_TOKEN = "OCEAN_BRAIN_SESSION_GENERATION";
|
|
4
5
|
const readLoginPageTemplate = () => {
|
|
5
6
|
if (true) {
|
|
6
|
-
return
|
|
7
|
+
return `<!doctype html>
|
|
8
|
+
<html lang="en">
|
|
9
|
+
<head>
|
|
10
|
+
<meta charset="utf-8" />
|
|
11
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
12
|
+
<meta name="ocean-brain-session-generation" content="OCEAN_BRAIN_SESSION_GENERATION" />
|
|
13
|
+
<title>Ocean Brain Sign In</title>
|
|
14
|
+
<style>
|
|
15
|
+
:root {
|
|
16
|
+
color-scheme: light dark;
|
|
17
|
+
--surface: #f7f8fa;
|
|
18
|
+
--elevated: #fbfcfd;
|
|
19
|
+
--fg-default: #202631;
|
|
20
|
+
--fg-secondary: #626d7c;
|
|
21
|
+
--fg-tertiary: #8993a2;
|
|
22
|
+
--fg-placeholder: #98a2b0;
|
|
23
|
+
--fg-error: #a24545;
|
|
24
|
+
--fg-on-filled: #f6f8fb;
|
|
25
|
+
--border-subtle: #e5e9ee;
|
|
26
|
+
--border-focus: #757f8d;
|
|
27
|
+
--border-error: #d47777;
|
|
28
|
+
--accent-soft-danger: rgba(214, 141, 135, 0.18);
|
|
29
|
+
--accent-soft-primary: rgba(93, 102, 114, 0.12);
|
|
30
|
+
--cta: #23272d;
|
|
31
|
+
--cta-hover: #171a1f;
|
|
32
|
+
--page-bg: #f2f5f8;
|
|
33
|
+
font-family: "Pretendard Variable", "Pretendard", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
34
|
+
background: var(--page-bg);
|
|
35
|
+
color: var(--fg-default);
|
|
36
|
+
}
|
|
37
|
+
@media (prefers-color-scheme: dark) {
|
|
38
|
+
:root {
|
|
39
|
+
--surface: #16191e;
|
|
40
|
+
--elevated: #1d2229;
|
|
41
|
+
--fg-default: #e6ebf2;
|
|
42
|
+
--fg-secondary: #a9b3c2;
|
|
43
|
+
--fg-tertiary: #7f8998;
|
|
44
|
+
--fg-placeholder: #717b88;
|
|
45
|
+
--fg-error: #efaaaa;
|
|
46
|
+
--fg-on-filled: #12161c;
|
|
47
|
+
--border-subtle: #29303a;
|
|
48
|
+
--border-focus: #b4c0cf;
|
|
49
|
+
--border-error: #efaaaa;
|
|
50
|
+
--accent-soft-danger: rgba(215, 146, 139, 0.14);
|
|
51
|
+
--accent-soft-primary: rgba(184, 192, 202, 0.12);
|
|
52
|
+
--cta: #edf1f5;
|
|
53
|
+
--cta-hover: #f8fafc;
|
|
54
|
+
--page-bg: #101318;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
* {
|
|
58
|
+
box-sizing: border-box;
|
|
59
|
+
}
|
|
60
|
+
body {
|
|
61
|
+
margin: 0;
|
|
62
|
+
min-height: 100vh;
|
|
63
|
+
display: grid;
|
|
64
|
+
place-items: center;
|
|
65
|
+
background: var(--page-bg);
|
|
66
|
+
padding: 24px;
|
|
67
|
+
}
|
|
68
|
+
.shell {
|
|
69
|
+
width: min(392px, 100%);
|
|
70
|
+
}
|
|
71
|
+
.brand {
|
|
72
|
+
display: flex;
|
|
73
|
+
align-items: center;
|
|
74
|
+
gap: 10px;
|
|
75
|
+
margin-bottom: 14px;
|
|
76
|
+
color: var(--fg-tertiary);
|
|
77
|
+
font-size: 12px;
|
|
78
|
+
font-weight: 700;
|
|
79
|
+
line-height: 1.4;
|
|
80
|
+
}
|
|
81
|
+
.brand img {
|
|
82
|
+
width: 28px;
|
|
83
|
+
height: 28px;
|
|
84
|
+
border-radius: 8px;
|
|
85
|
+
}
|
|
86
|
+
.panel {
|
|
87
|
+
padding: 24px;
|
|
88
|
+
border: 1px solid var(--border-subtle);
|
|
89
|
+
border-radius: 16px;
|
|
90
|
+
background: var(--surface);
|
|
91
|
+
box-shadow:
|
|
92
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.1),
|
|
93
|
+
0 1px 4px -2px rgba(23, 29, 38, 0.04);
|
|
94
|
+
}
|
|
95
|
+
.sr-only {
|
|
96
|
+
position: absolute;
|
|
97
|
+
width: 1px;
|
|
98
|
+
height: 1px;
|
|
99
|
+
padding: 0;
|
|
100
|
+
margin: -1px;
|
|
101
|
+
overflow: hidden;
|
|
102
|
+
clip: rect(0, 0, 0, 0);
|
|
103
|
+
white-space: nowrap;
|
|
104
|
+
border: 0;
|
|
105
|
+
}
|
|
106
|
+
label {
|
|
107
|
+
display: block;
|
|
108
|
+
margin-bottom: 8px;
|
|
109
|
+
color: var(--fg-secondary);
|
|
110
|
+
font-size: 0.75rem;
|
|
111
|
+
line-height: 1.4;
|
|
112
|
+
font-weight: 600;
|
|
113
|
+
}
|
|
114
|
+
form {
|
|
115
|
+
display: grid;
|
|
116
|
+
gap: 16px;
|
|
117
|
+
}
|
|
118
|
+
.field {
|
|
119
|
+
display: grid;
|
|
120
|
+
}
|
|
121
|
+
input {
|
|
122
|
+
width: 100%;
|
|
123
|
+
box-sizing: border-box;
|
|
124
|
+
padding: 14px 16px;
|
|
125
|
+
border: 1px solid var(--border-subtle);
|
|
126
|
+
border-radius: 16px;
|
|
127
|
+
background: var(--elevated);
|
|
128
|
+
font-size: 16px;
|
|
129
|
+
color: var(--fg-default);
|
|
130
|
+
transition: border-color 0.18s ease, box-shadow 0.18s ease, background-color 0.18s ease;
|
|
131
|
+
}
|
|
132
|
+
input::placeholder {
|
|
133
|
+
color: var(--fg-placeholder);
|
|
134
|
+
}
|
|
135
|
+
input:focus {
|
|
136
|
+
outline: none;
|
|
137
|
+
border-color: var(--border-focus);
|
|
138
|
+
box-shadow: 0 0 0 4px var(--accent-soft-primary);
|
|
139
|
+
}
|
|
140
|
+
button {
|
|
141
|
+
width: 100%;
|
|
142
|
+
border: 1px solid transparent;
|
|
143
|
+
border-radius: 14px;
|
|
144
|
+
background: var(--cta);
|
|
145
|
+
color: var(--fg-on-filled);
|
|
146
|
+
padding: 14px 18px;
|
|
147
|
+
font-size: 16px;
|
|
148
|
+
font-weight: 600;
|
|
149
|
+
cursor: pointer;
|
|
150
|
+
transition: transform 0.18s ease, box-shadow 0.18s ease, background-color 0.18s ease;
|
|
151
|
+
}
|
|
152
|
+
button:hover {
|
|
153
|
+
background: var(--cta-hover);
|
|
154
|
+
}
|
|
155
|
+
button:active {
|
|
156
|
+
transform: translateY(1px);
|
|
157
|
+
}
|
|
158
|
+
button:focus-visible {
|
|
159
|
+
outline: none;
|
|
160
|
+
box-shadow: 0 0 0 4px var(--accent-soft-primary);
|
|
161
|
+
}
|
|
162
|
+
.error {
|
|
163
|
+
margin-bottom: 18px;
|
|
164
|
+
padding: 13px 14px;
|
|
165
|
+
border: 1px solid var(--border-error);
|
|
166
|
+
border-radius: 14px;
|
|
167
|
+
background: var(--accent-soft-danger);
|
|
168
|
+
color: var(--fg-error);
|
|
169
|
+
font-size: 14px;
|
|
170
|
+
font-weight: 600;
|
|
171
|
+
}
|
|
172
|
+
@media (prefers-color-scheme: dark) {
|
|
173
|
+
.panel {
|
|
174
|
+
box-shadow:
|
|
175
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.03),
|
|
176
|
+
0 1px 4px -2px rgba(0, 0, 0, 0.18);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
@media (max-width: 640px) {
|
|
180
|
+
body {
|
|
181
|
+
place-items: stretch;
|
|
182
|
+
padding: 18px;
|
|
183
|
+
}
|
|
184
|
+
.shell {
|
|
185
|
+
width: 100%;
|
|
186
|
+
margin: auto 0;
|
|
187
|
+
}
|
|
188
|
+
.panel {
|
|
189
|
+
padding: 22px;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
</style>
|
|
193
|
+
</head>
|
|
194
|
+
<body>
|
|
195
|
+
<main class="shell">
|
|
196
|
+
<div class="brand"><img src="/icon.png" alt="" aria-hidden="true" />Ocean Brain</div>
|
|
197
|
+
<section class="panel" aria-labelledby="login-title">
|
|
198
|
+
<h1 id="login-title" class="sr-only">Sign in</h1>
|
|
199
|
+
<!-- OCEAN_BRAIN_LOGIN_ERROR -->
|
|
200
|
+
<form method="post" action="/login">
|
|
201
|
+
<!-- OCEAN_BRAIN_CSRF_INPUT -->
|
|
202
|
+
<input type="hidden" name="next" value="OCEAN_BRAIN_NEXT_PATH" />
|
|
203
|
+
<div class="field">
|
|
204
|
+
<label for="password">Password</label>
|
|
205
|
+
<input id="password" name="password" type="password" autocomplete="current-password" required autofocus />
|
|
206
|
+
</div>
|
|
207
|
+
<button type="submit">Sign in</button>
|
|
208
|
+
</form>
|
|
209
|
+
</section>
|
|
210
|
+
</main>
|
|
211
|
+
<script>
|
|
212
|
+
(() => {
|
|
213
|
+
const generationMeta = document.querySelector('meta[name="ocean-brain-session-generation"]');
|
|
214
|
+
const pageGeneration = generationMeta?.getAttribute('content');
|
|
215
|
+
const generationHeader = 'X-Ocean-Brain-Session-Generation';
|
|
216
|
+
const sessionEndpoint = '/api/auth/session';
|
|
217
|
+
const form = document.querySelector('form');
|
|
218
|
+
let checkPromise;
|
|
219
|
+
let submitting = false;
|
|
220
|
+
|
|
221
|
+
const checkForStaleLoginPage = async () => {
|
|
222
|
+
if (!pageGeneration) {
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
checkPromise ??= fetch(sessionEndpoint, {
|
|
227
|
+
cache: 'no-store',
|
|
228
|
+
credentials: 'same-origin',
|
|
229
|
+
})
|
|
230
|
+
.then((response) => {
|
|
231
|
+
const currentGeneration = response.headers.get(generationHeader);
|
|
232
|
+
const isStale = Boolean(currentGeneration && currentGeneration !== pageGeneration);
|
|
233
|
+
|
|
234
|
+
if (isStale) {
|
|
235
|
+
window.location.reload();
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return isStale;
|
|
239
|
+
})
|
|
240
|
+
.catch(() => false)
|
|
241
|
+
.finally(() => {
|
|
242
|
+
checkPromise = undefined;
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
return checkPromise;
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
void checkForStaleLoginPage();
|
|
249
|
+
window.addEventListener('pageshow', () => {
|
|
250
|
+
void checkForStaleLoginPage();
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
form?.addEventListener('submit', async (event) => {
|
|
254
|
+
event.preventDefault();
|
|
255
|
+
|
|
256
|
+
if (submitting) {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
submitting = true;
|
|
261
|
+
|
|
262
|
+
const isStale = await checkForStaleLoginPage();
|
|
263
|
+
if (isStale) {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
form.submit();
|
|
268
|
+
});
|
|
269
|
+
})();
|
|
270
|
+
</script>
|
|
271
|
+
</body>
|
|
272
|
+
</html>
|
|
273
|
+
`;
|
|
7
274
|
}
|
|
8
275
|
return readFileSync(new URL("./login-page.html", import.meta.url), "utf8");
|
|
9
276
|
};
|
|
@@ -22,14 +289,14 @@ const renderCsrfInput = (csrfToken) => {
|
|
|
22
289
|
return `<input type="hidden" name="_csrf" value="${escapeHtml(csrfToken)}" />`;
|
|
23
290
|
};
|
|
24
291
|
const renderLoginTemplate = (values) => {
|
|
25
|
-
return LOGIN_PAGE_TEMPLATE.replace(LOGIN_ERROR_TOKEN, values.errorBlock).replace(NEXT_PATH_TOKEN, values.nextPath).replace("<!-- OCEAN_BRAIN_CSRF_INPUT -->", values.csrfInput);
|
|
292
|
+
return LOGIN_PAGE_TEMPLATE.replace(LOGIN_ERROR_TOKEN, values.errorBlock).replace(SESSION_GENERATION_TOKEN, values.sessionGeneration).replace(NEXT_PATH_TOKEN, values.nextPath).replace("<!-- OCEAN_BRAIN_CSRF_INPUT -->", values.csrfInput);
|
|
26
293
|
};
|
|
27
|
-
const renderLoginPage = ({ nextPath, errorMessage, csrfToken }) => renderLoginTemplate({
|
|
294
|
+
const renderLoginPage = ({ nextPath, errorMessage, csrfToken, sessionGeneration }) => renderLoginTemplate({
|
|
28
295
|
errorBlock: renderLoginError(errorMessage),
|
|
29
296
|
nextPath: escapeHtml(nextPath),
|
|
30
|
-
csrfInput: renderCsrfInput(csrfToken)
|
|
297
|
+
csrfInput: renderCsrfInput(csrfToken),
|
|
298
|
+
sessionGeneration: escapeHtml(sessionGeneration ?? "")
|
|
31
299
|
});
|
|
32
300
|
export {
|
|
33
301
|
renderLoginPage
|
|
34
302
|
};
|
|
35
|
-
//# sourceMappingURL=login-page.js.map
|
|
@@ -1,35 +1,50 @@
|
|
|
1
1
|
import {
|
|
2
2
|
compareSharedSecret,
|
|
3
3
|
destroySession,
|
|
4
|
+
getSessionGeneration,
|
|
4
5
|
refreshCsrfToken,
|
|
5
6
|
regenerateSession,
|
|
6
7
|
sanitizeRedirectPath
|
|
7
8
|
} from "../service.js";
|
|
8
9
|
import { renderLoginPage } from "./login-page.js";
|
|
10
|
+
const setLoginPageHeaders = (res) => {
|
|
11
|
+
res.set("Cache-Control", "no-store");
|
|
12
|
+
};
|
|
9
13
|
const createLoginPageHandler = (authConfig) => {
|
|
10
14
|
return async (req, res) => {
|
|
11
15
|
if (authConfig.mode !== "password" || req.session?.authenticated) {
|
|
16
|
+
setLoginPageHeaders(res);
|
|
12
17
|
res.redirect(303, sanitizeRedirectPath(req.query.next));
|
|
13
18
|
return;
|
|
14
19
|
}
|
|
15
20
|
const nextPath = sanitizeRedirectPath(req.query.next);
|
|
16
|
-
|
|
21
|
+
setLoginPageHeaders(res);
|
|
22
|
+
res.status(200).type("html").send(
|
|
23
|
+
renderLoginPage({
|
|
24
|
+
nextPath,
|
|
25
|
+
csrfToken: res.locals._csrf,
|
|
26
|
+
sessionGeneration: getSessionGeneration()
|
|
27
|
+
})
|
|
28
|
+
).end();
|
|
17
29
|
};
|
|
18
30
|
};
|
|
19
31
|
const createLoginPageSubmitHandler = (authConfig) => {
|
|
20
32
|
return async (req, res) => {
|
|
21
33
|
const nextPath = sanitizeRedirectPath(req.body?.next);
|
|
22
34
|
if (authConfig.mode !== "password" || !authConfig.password) {
|
|
35
|
+
setLoginPageHeaders(res);
|
|
23
36
|
res.redirect(303, nextPath);
|
|
24
37
|
return;
|
|
25
38
|
}
|
|
26
39
|
const password = typeof req.body?.password === "string" ? req.body.password : "";
|
|
27
40
|
if (!password || !compareSharedSecret(authConfig.password, password)) {
|
|
41
|
+
setLoginPageHeaders(res);
|
|
28
42
|
res.status(401).type("html").send(
|
|
29
43
|
renderLoginPage({
|
|
30
44
|
nextPath,
|
|
31
45
|
errorMessage: "Invalid password",
|
|
32
|
-
csrfToken: res.locals._csrf
|
|
46
|
+
csrfToken: res.locals._csrf,
|
|
47
|
+
sessionGeneration: getSessionGeneration()
|
|
33
48
|
})
|
|
34
49
|
).end();
|
|
35
50
|
return;
|
|
@@ -37,6 +52,7 @@ const createLoginPageSubmitHandler = (authConfig) => {
|
|
|
37
52
|
await regenerateSession(req);
|
|
38
53
|
req.session.authenticated = true;
|
|
39
54
|
refreshCsrfToken(req);
|
|
55
|
+
setLoginPageHeaders(res);
|
|
40
56
|
res.redirect(303, nextPath);
|
|
41
57
|
};
|
|
42
58
|
};
|
|
@@ -44,9 +60,11 @@ const createLogoutPageHandler = (authConfig) => {
|
|
|
44
60
|
return async (req, res) => {
|
|
45
61
|
if (authConfig.mode === "password") {
|
|
46
62
|
await destroySession(req);
|
|
63
|
+
setLoginPageHeaders(res);
|
|
47
64
|
res.redirect(303, "/login");
|
|
48
65
|
return;
|
|
49
66
|
}
|
|
67
|
+
setLoginPageHeaders(res);
|
|
50
68
|
res.redirect(303, "/");
|
|
51
69
|
};
|
|
52
70
|
};
|
|
@@ -55,4 +73,3 @@ export {
|
|
|
55
73
|
createLoginPageSubmitHandler,
|
|
56
74
|
createLogoutPageHandler
|
|
57
75
|
};
|
|
58
|
-
//# sourceMappingURL=pages.js.map
|
|
@@ -5,6 +5,7 @@ import { sanitizeRedirectPath } from "../../modules/auth-redirect.js";
|
|
|
5
5
|
import { createAppError } from "../../modules/error-handler.js";
|
|
6
6
|
const AUTH_SESSION_GENERATION_HEADER = "X-Ocean-Brain-Session-Generation";
|
|
7
7
|
const AUTH_SESSION_GENERATION = crypto.randomUUID();
|
|
8
|
+
const getSessionGeneration = () => AUTH_SESSION_GENERATION;
|
|
8
9
|
const createPasswordHash = async (password) => {
|
|
9
10
|
const salt = crypto.randomBytes(16).toString("hex");
|
|
10
11
|
const hash = crypto.pbkdf2Sync(password, salt, 1e3, 64, "sha512").toString("hex");
|
|
@@ -18,7 +19,7 @@ const comparePassword = async (password, storedHash) => {
|
|
|
18
19
|
const compareSharedSecret = compareCommonSharedSecret;
|
|
19
20
|
const buildSessionResponse = (authConfig, req) => buildAuthSessionResponse(authConfig, Boolean(req.session?.authenticated));
|
|
20
21
|
const setSessionStatusHeaders = (res) => {
|
|
21
|
-
res.set(AUTH_SESSION_GENERATION_HEADER,
|
|
22
|
+
res.set(AUTH_SESSION_GENERATION_HEADER, getSessionGeneration());
|
|
22
23
|
res.set("Cache-Control", "no-store");
|
|
23
24
|
};
|
|
24
25
|
const refreshCsrfToken = (req) => {
|
|
@@ -64,9 +65,9 @@ export {
|
|
|
64
65
|
compareSharedSecret,
|
|
65
66
|
createPasswordHash,
|
|
66
67
|
destroySession,
|
|
68
|
+
getSessionGeneration,
|
|
67
69
|
refreshCsrfToken,
|
|
68
70
|
regenerateSession,
|
|
69
71
|
sanitizeRedirectPath,
|
|
70
72
|
setSessionStatusHeaders
|
|
71
73
|
};
|
|
72
|
-
//# sourceMappingURL=service.js.map
|