@juspay/shooter 1.18.0 → 1.20.0
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/build/client/_app/immutable/assets/{0.NV8k8wxG.css → 0.BwNtE8TX.css} +1 -1
- package/build/client/_app/immutable/assets/0.BwNtE8TX.css.br +0 -0
- package/build/client/_app/immutable/assets/{0.NV8k8wxG.css.gz → 0.BwNtE8TX.css.gz} +0 -0
- package/build/client/_app/immutable/assets/11.F10lvwyh.css +1 -0
- package/build/client/_app/immutable/assets/11.F10lvwyh.css.br +0 -0
- package/build/client/_app/immutable/assets/11.F10lvwyh.css.gz +0 -0
- package/build/client/_app/immutable/assets/8.BYgAX7hR.css +1 -0
- package/build/client/_app/immutable/assets/8.BYgAX7hR.css.br +0 -0
- package/build/client/_app/immutable/assets/8.BYgAX7hR.css.gz +0 -0
- package/build/client/_app/immutable/assets/9.DV6pZunn.css +1 -0
- package/build/client/_app/immutable/assets/9.DV6pZunn.css.br +0 -0
- package/build/client/_app/immutable/assets/9.DV6pZunn.css.gz +0 -0
- package/build/client/_app/immutable/chunks/{DZQMsHM5.js → 2rBV5OkJ.js} +1 -1
- package/build/client/_app/immutable/chunks/2rBV5OkJ.js.br +0 -0
- package/build/client/_app/immutable/chunks/2rBV5OkJ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{B9WQy_3X.js → BB2l8o4X.js} +1 -1
- package/build/client/_app/immutable/chunks/BB2l8o4X.js.br +0 -0
- package/build/client/_app/immutable/chunks/BB2l8o4X.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{Cg3dlX05.js → BPDiEZo0.js} +2 -2
- package/build/client/_app/immutable/chunks/BPDiEZo0.js.br +0 -0
- package/build/client/_app/immutable/chunks/BPDiEZo0.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{C_9BZILB.js → BcpydfqI.js} +1 -1
- package/build/client/_app/immutable/chunks/BcpydfqI.js.br +0 -0
- package/build/client/_app/immutable/chunks/BcpydfqI.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{BRqaaL5D.js → BvmdJful.js} +1 -1
- package/build/client/_app/immutable/chunks/BvmdJful.js.br +0 -0
- package/build/client/_app/immutable/chunks/BvmdJful.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C_YNQL8b.js +3 -0
- package/build/client/_app/immutable/chunks/C_YNQL8b.js.br +0 -0
- package/build/client/_app/immutable/chunks/C_YNQL8b.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{C5VOyQCG.js → ClIPTXf3.js} +1 -1
- package/build/client/_app/immutable/chunks/ClIPTXf3.js.br +0 -0
- package/build/client/_app/immutable/chunks/ClIPTXf3.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{8lO1IL7u.js → DIZ3Qst5.js} +1 -1
- package/build/client/_app/immutable/chunks/DIZ3Qst5.js.br +0 -0
- package/build/client/_app/immutable/chunks/{8lO1IL7u.js.gz → DIZ3Qst5.js.gz} +0 -0
- package/build/client/_app/immutable/chunks/{DJvX78LW.js → DT4H19pV.js} +1 -1
- package/build/client/_app/immutable/chunks/DT4H19pV.js.br +0 -0
- package/build/client/_app/immutable/chunks/DT4H19pV.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{DYuMZGL5.js → DWmC0QM7.js} +1 -1
- package/build/client/_app/immutable/chunks/DWmC0QM7.js.br +0 -0
- package/build/client/_app/immutable/chunks/DWmC0QM7.js.gz +0 -0
- package/build/client/_app/immutable/chunks/J5-Cr5oR.js +6 -0
- package/build/client/_app/immutable/chunks/J5-Cr5oR.js.br +0 -0
- package/build/client/_app/immutable/chunks/J5-Cr5oR.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{DZvnhU_8.js → ZS5XYDx_.js} +2 -2
- package/build/client/_app/immutable/chunks/ZS5XYDx_.js.br +0 -0
- package/build/client/_app/immutable/chunks/ZS5XYDx_.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.Bd-DfeJi.js +2 -0
- package/build/client/_app/immutable/entry/app.Bd-DfeJi.js.br +0 -0
- package/build/client/_app/immutable/entry/app.Bd-DfeJi.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.evvp4tX7.js +1 -0
- package/build/client/_app/immutable/entry/start.evvp4tX7.js.br +2 -0
- package/build/client/_app/immutable/entry/start.evvp4tX7.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.Bl-1LQWM.js +10 -0
- package/build/client/_app/immutable/nodes/0.Bl-1LQWM.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.Bl-1LQWM.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{1.C4eFlqSB.js → 1.DT4dq6Ay.js} +1 -1
- package/build/client/_app/immutable/nodes/1.DT4dq6Ay.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.DT4dq6Ay.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{8.Bs362gyb.js → 10.CF7RGXpe.js} +2 -2
- package/build/client/_app/immutable/nodes/10.CF7RGXpe.js.br +0 -0
- package/build/client/_app/immutable/nodes/10.CF7RGXpe.js.gz +0 -0
- package/build/client/_app/immutable/nodes/11.BV_G7yLI.js +2 -0
- package/build/client/_app/immutable/nodes/11.BV_G7yLI.js.br +0 -0
- package/build/client/_app/immutable/nodes/11.BV_G7yLI.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{2.CdC092Za.js → 2.DcRhsjYp.js} +2 -2
- package/build/client/_app/immutable/nodes/2.DcRhsjYp.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.DcRhsjYp.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{3.Dhf4ZWW0.js → 3.0MMe3oxR.js} +3 -3
- package/build/client/_app/immutable/nodes/3.0MMe3oxR.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.0MMe3oxR.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{4.BSVqdrrD.js → 4.CBX9A3ka.js} +2 -2
- package/build/client/_app/immutable/nodes/4.CBX9A3ka.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.CBX9A3ka.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{5.Cfj35gpY.js → 5.DIVKuZc9.js} +1 -1
- package/build/client/_app/immutable/nodes/5.DIVKuZc9.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.DIVKuZc9.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{6.B3SEB_li.js → 6.ComiWlV6.js} +1 -1
- package/build/client/_app/immutable/nodes/6.ComiWlV6.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.ComiWlV6.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{7.DV8cJ1lX.js → 7.vkPx1kVP.js} +1 -1
- package/build/client/_app/immutable/nodes/7.vkPx1kVP.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.vkPx1kVP.js.gz +0 -0
- package/build/client/_app/immutable/nodes/8.Bmr3sWbS.js +1 -0
- package/build/client/_app/immutable/nodes/8.Bmr3sWbS.js.br +0 -0
- package/build/client/_app/immutable/nodes/8.Bmr3sWbS.js.gz +0 -0
- package/build/client/_app/immutable/nodes/9.CAJucyeI.js +2 -0
- package/build/client/_app/immutable/nodes/9.CAJucyeI.js.br +0 -0
- package/build/client/_app/immutable/nodes/9.CAJucyeI.js.gz +0 -0
- package/build/client/_app/version.json +1 -1
- package/build/client/_app/version.json.br +0 -0
- package/build/client/_app/version.json.gz +0 -0
- package/build/server/chunks/{0-Cd7jY0a7.js → 0-DDGB6CRT.js} +4 -4
- package/build/server/chunks/{0-Cd7jY0a7.js.map → 0-DDGB6CRT.js.map} +1 -1
- package/build/server/chunks/1-DEjonQXD.js +9 -0
- package/build/server/chunks/{1-C4BOGoJY.js.map → 1-DEjonQXD.js.map} +1 -1
- package/build/server/chunks/10-BK1kiiiw.js +9 -0
- package/build/server/chunks/10-BK1kiiiw.js.map +1 -0
- package/build/server/chunks/11-CJPjkEF3.js +9 -0
- package/build/server/chunks/11-CJPjkEF3.js.map +1 -0
- package/build/server/chunks/{2-Ba0mNwJ6.js → 2-RLnhlWh5.js} +3 -3
- package/build/server/chunks/{2-Ba0mNwJ6.js.map → 2-RLnhlWh5.js.map} +1 -1
- package/build/server/chunks/{3-Pg8t1uJU.js → 3-Dd4pJBqZ.js} +3 -3
- package/build/server/chunks/{3-Pg8t1uJU.js.map → 3-Dd4pJBqZ.js.map} +1 -1
- package/build/server/chunks/{4-BtYdKCVW.js → 4-Bb5VFhsO.js} +3 -3
- package/build/server/chunks/{4-BtYdKCVW.js.map → 4-Bb5VFhsO.js.map} +1 -1
- package/build/server/chunks/{5-CvJK3PiH.js → 5-oNoWuIsn.js} +3 -3
- package/build/server/chunks/{5-CvJK3PiH.js.map → 5-oNoWuIsn.js.map} +1 -1
- package/build/server/chunks/6-DdRMnKNa.js +9 -0
- package/build/server/chunks/{6-D8xbnTSo.js.map → 6-DdRMnKNa.js.map} +1 -1
- package/build/server/chunks/7-vLOMMetm.js +9 -0
- package/build/server/chunks/{7-CkVK06S0.js.map → 7-vLOMMetm.js.map} +1 -1
- package/build/server/chunks/8-rJyiQLFs.js +9 -0
- package/build/server/chunks/8-rJyiQLFs.js.map +1 -0
- package/build/server/chunks/9-CVSNNYED.js +9 -0
- package/build/server/chunks/9-CVSNNYED.js.map +1 -0
- package/build/server/chunks/Banner-BgaAs1rs.js +90 -0
- package/build/server/chunks/Banner-BgaAs1rs.js.map +1 -0
- package/build/server/chunks/{Button-B5dU-ntz.js → Button-D0hZ7JYt.js} +2 -2
- package/build/server/chunks/Button-D0hZ7JYt.js.map +1 -0
- package/build/server/chunks/{Icon-C7Ml3GX6.js → Icon-D0GBnDcs.js} +3 -3
- package/build/server/chunks/Icon-D0GBnDcs.js.map +1 -0
- package/build/server/chunks/{Input-CPGO0sbS.js → Input-OmIiydSx.js} +2 -2
- package/build/server/chunks/Input-OmIiydSx.js.map +1 -0
- package/build/server/chunks/{Pill-CcrtCejm.js → Pill-4xJ-VhAA.js} +3 -3
- package/build/server/chunks/Pill-4xJ-VhAA.js.map +1 -0
- package/build/server/chunks/{Shimmer-C5jkvGr1.js → Shimmer-Dw2uvTC1.js} +2 -2
- package/build/server/chunks/Shimmer-Dw2uvTC1.js.map +1 -0
- package/build/server/chunks/{_error.svelte-CSIxs-ab.js → _error.svelte-CZnkxeLr.js} +8 -8
- package/build/server/chunks/_error.svelte-CZnkxeLr.js.map +1 -0
- package/build/server/chunks/{_layout.svelte-noB4j-v2.js → _layout.svelte-DfgNGGiM.js} +16 -11
- package/build/server/chunks/_layout.svelte-DfgNGGiM.js.map +1 -0
- package/build/server/chunks/{_page.svelte-DnTpPnPR.js → _page.svelte-BLo2v_8E.js} +7 -88
- package/build/server/chunks/_page.svelte-BLo2v_8E.js.map +1 -0
- package/build/server/chunks/_page.svelte-BTlfUsBp.js +43 -0
- package/build/server/chunks/_page.svelte-BTlfUsBp.js.map +1 -0
- package/build/server/chunks/{_page.svelte-BV0XyYJZ.js → _page.svelte-BX2FMgSg.js} +4 -4
- package/build/server/chunks/_page.svelte-BX2FMgSg.js.map +1 -0
- package/build/server/chunks/{_page.svelte-BUkm2304.js → _page.svelte-C7B0qdrC.js} +5 -5
- package/build/server/chunks/_page.svelte-C7B0qdrC.js.map +1 -0
- package/build/server/chunks/{_page.svelte-Dmg-RFCg.js → _page.svelte-CE7COWnF.js} +7 -7
- package/build/server/chunks/_page.svelte-CE7COWnF.js.map +1 -0
- package/build/server/chunks/{_page.svelte-BfB8maoc.js → _page.svelte-CWsjjd4l.js} +9 -9
- package/build/server/chunks/_page.svelte-CWsjjd4l.js.map +1 -0
- package/build/server/chunks/_page.svelte-D5S2hkBk.js +104 -0
- package/build/server/chunks/_page.svelte-D5S2hkBk.js.map +1 -0
- package/build/server/chunks/{_page.svelte-B6qyh-K-.js → _page.svelte-D_Ey8QRG.js} +11 -11
- package/build/server/chunks/_page.svelte-D_Ey8QRG.js.map +1 -0
- package/build/server/chunks/{_page.svelte-C60lAagP.js → _page.svelte-dabsQl9c.js} +210 -9
- package/build/server/chunks/_page.svelte-dabsQl9c.js.map +1 -0
- package/build/server/chunks/{_page.svelte-DuzZr5dA.js → _page.svelte-tBuIq8Pg.js} +11 -11
- package/build/server/chunks/_page.svelte-tBuIq8Pg.js.map +1 -0
- package/build/server/chunks/{_server.ts-CyjDrcZN.js → _server.ts-AnBXfZXh.js} +10 -2
- package/build/server/chunks/_server.ts-AnBXfZXh.js.map +1 -0
- package/build/server/chunks/_server.ts-B-evHL2q.js +13 -0
- package/build/server/chunks/_server.ts-B-evHL2q.js.map +1 -0
- package/build/server/chunks/_server.ts-B2wIgsW4.js +95 -0
- package/build/server/chunks/_server.ts-B2wIgsW4.js.map +1 -0
- package/build/server/chunks/_server.ts-BaaY7Z9D.js +77 -0
- package/build/server/chunks/_server.ts-BaaY7Z9D.js.map +1 -0
- package/build/server/chunks/_server.ts-C0317RBD.js +57 -0
- package/build/server/chunks/_server.ts-C0317RBD.js.map +1 -0
- package/build/server/chunks/{_server.ts-Bu3s5hfv.js → _server.ts-CJGyN8mw.js} +18 -10
- package/build/server/chunks/_server.ts-CJGyN8mw.js.map +1 -0
- package/build/server/chunks/_server.ts-CVPZOpiv.js +23 -0
- package/build/server/chunks/_server.ts-CVPZOpiv.js.map +1 -0
- package/build/server/chunks/{_server.ts-DZgfQKiH.js → _server.ts-D9ir7u24.js} +2 -2
- package/build/server/chunks/{_server.ts-DZgfQKiH.js.map → _server.ts-D9ir7u24.js.map} +1 -1
- package/build/server/chunks/{_server.ts-DZP2lhaY.js → _server.ts-DEx9-epI.js} +20 -8
- package/build/server/chunks/_server.ts-DEx9-epI.js.map +1 -0
- package/build/server/chunks/{_server.ts-BA_uWcPw.js → _server.ts-DKNIsQeH.js} +6 -4
- package/build/server/chunks/_server.ts-DKNIsQeH.js.map +1 -0
- package/build/server/chunks/_server.ts-DkZX_O9a.js +39 -0
- package/build/server/chunks/_server.ts-DkZX_O9a.js.map +1 -0
- package/build/server/chunks/_server.ts-DpRr0Tfh.js +68 -0
- package/build/server/chunks/_server.ts-DpRr0Tfh.js.map +1 -0
- package/build/server/chunks/{_server.ts-CwAjt91u.js → _server.ts-Dz9Jd9Jh.js} +6 -4
- package/build/server/chunks/{_server.ts-CwAjt91u.js.map → _server.ts-Dz9Jd9Jh.js.map} +1 -1
- package/build/server/chunks/_server.ts-Mttr0-Sl.js +48 -0
- package/build/server/chunks/_server.ts-Mttr0-Sl.js.map +1 -0
- package/build/server/chunks/{_server.ts-Bjbr7glm.js → _server.ts-QN-Bo5ql.js} +12 -5
- package/build/server/chunks/_server.ts-QN-Bo5ql.js.map +1 -0
- package/build/server/chunks/{_server.ts-BrqaMMAa.js → _server.ts-W6i3EnGX.js} +29 -6
- package/build/server/chunks/_server.ts-W6i3EnGX.js.map +1 -0
- package/build/server/chunks/{_server.ts-DZ5naqSL.js → _server.ts-bk_EeAdY.js} +6 -2
- package/build/server/chunks/_server.ts-bk_EeAdY.js.map +1 -0
- package/build/server/chunks/_server.ts-jtqWDWcf.js +45 -0
- package/build/server/chunks/_server.ts-jtqWDWcf.js.map +1 -0
- package/build/server/chunks/{cache-Me3zUAaD.js → cache-BlMaDsHi.js} +2 -2
- package/build/server/chunks/cache-BlMaDsHi.js.map +1 -0
- package/build/server/chunks/{client-CfNnl32g.js → client-Ds1brw-8.js} +4 -4
- package/build/server/chunks/{client-CfNnl32g.js.map → client-Ds1brw-8.js.map} +1 -1
- package/build/server/chunks/client2-DngLdcUc.js +7 -0
- package/build/server/chunks/{client2-DDP30_vY.js.map → client2-DngLdcUc.js.map} +1 -1
- package/build/server/chunks/coordinator-DMU_ADXf.js +530 -0
- package/build/server/chunks/coordinator-DMU_ADXf.js.map +1 -0
- package/build/server/chunks/guest-registry-t0-7Zv5q.js +39 -0
- package/build/server/chunks/guest-registry-t0-7Zv5q.js.map +1 -0
- package/build/server/chunks/{index-CJrGuxuM.js → index-CoYB03g7.js} +2 -2
- package/build/server/chunks/{index-CJrGuxuM.js.map → index-CoYB03g7.js.map} +1 -1
- package/build/server/chunks/{index-server--49oHtA0.js → index-server-Bq3cnK69.js} +2 -2
- package/build/server/chunks/{index-server--49oHtA0.js.map → index-server-Bq3cnK69.js.map} +1 -1
- package/build/server/chunks/{index2-MY7PXeAc.js → index2-dSGQ9Eaa.js} +2 -2
- package/build/server/chunks/{index2-MY7PXeAc.js.map → index2-dSGQ9Eaa.js.map} +1 -1
- package/build/server/chunks/{pty-manager-DmNSCKAr.js → pty-manager-CkZNoW1t.js} +7 -2
- package/build/server/chunks/pty-manager-CkZNoW1t.js.map +1 -0
- package/build/server/chunks/qwen-reader-DGfUbKaJ.js.map +1 -1
- package/build/server/chunks/{registry-Kcw2UCMv.js → registry-D4J_CuzW.js} +2 -2
- package/build/server/chunks/registry-D4J_CuzW.js.map +1 -0
- package/build/server/chunks/{root-xvQIR1Bt.js → root-D4IoFC8F.js} +2 -2
- package/build/server/chunks/root-D4IoFC8F.js.map +1 -0
- package/build/server/chunks/share-auth-BS7JuiHf.js +27 -0
- package/build/server/chunks/share-auth-BS7JuiHf.js.map +1 -0
- package/build/server/chunks/share-store-B9jMpVg0.js +127 -0
- package/build/server/chunks/share-store-B9jMpVg0.js.map +1 -0
- package/build/server/chunks/{state.svelte-RCtlkrNH.js → state.svelte-CmHqngc_.js} +3 -3
- package/build/server/chunks/{state.svelte-RCtlkrNH.js.map → state.svelte-CmHqngc_.js.map} +1 -1
- package/build/server/chunks/{stores-C-LqoonT.js → stores-CRYxfF0o.js} +4 -4
- package/build/server/chunks/stores-CRYxfF0o.js.map +1 -0
- package/build/server/chunks/super-session-handler-DPyxFgmz.js +22 -0
- package/build/server/chunks/super-session-handler-DPyxFgmz.js.map +1 -0
- package/build/server/index.js +4 -4
- package/build/server/index.js.map +1 -1
- package/build/server/manifest.js +101 -22
- package/build/server/manifest.js.map +1 -1
- package/package.json +2 -2
- package/scripts/e2e-all-features.sh +41 -2
- package/server.ts +33 -3
- package/src/lib/modules/client/terminal/ShareGate.svelte +96 -0
- package/src/lib/modules/client/terminal/ShareSheet.svelte +395 -0
- package/src/lib/modules/client/terminal/xterm-wrapper.ts +19 -2
- package/src/lib/modules/server/sos/coordinator.ts +492 -0
- package/src/lib/modules/server/sos/policy-gate.ts +56 -0
- package/src/lib/modules/server/sos/relay-store.ts +159 -0
- package/src/lib/modules/server/terminal/pty-input.ts +37 -0
- package/src/lib/modules/server/terminal/pty-manager.ts +6 -0
- package/src/lib/modules/server/terminal/share-auth.ts +37 -0
- package/src/lib/modules/server/terminal/share-store.ts +172 -0
- package/src/lib/modules/server/ws/guest-registry.ts +49 -0
- package/src/lib/modules/server/ws/server.ts +28 -4
- package/src/lib/modules/server/ws/session-handler.ts +24 -5
- package/src/lib/modules/server/ws/super-session-handler.ts +200 -0
- package/src/lib/modules/server/ws/terminal-handler.ts +21 -2
- package/src/lib/modules/server/ws/ticket-store.ts +18 -10
- package/src/lib/types/generated/Client.ts +25 -1
- package/src/lib/types/generated/Share.ts +404 -0
- package/src/lib/types/generated/WsProtocol.ts +73 -2
- package/src/lib/types/generated/index.ts +1 -0
- package/src/lib/types/index.ts +2 -1
- package/src/lib/types/sos.ts +134 -0
- package/src/lib/types/terminal-client.ts +19 -2
- package/src/lib/types/ws.ts +1 -0
- package/src/routes/+layout.svelte +9 -2
- package/src/routes/api/sos/+server.ts +36 -0
- package/src/routes/api/sos/[id]/+server.ts +55 -0
- package/src/routes/api/sos/[id]/inject/+server.ts +44 -0
- package/src/routes/api/sos/[id]/members/+server.ts +47 -0
- package/src/routes/api/sos/[id]/members/[mid]/+server.ts +17 -0
- package/src/routes/api/sos/[id]/rules/+server.ts +85 -0
- package/src/routes/api/terminals/[id]/+server.ts +14 -3
- package/src/routes/api/terminals/[id]/paste-image/+server.ts +8 -4
- package/src/routes/api/terminals/[id]/resize/+server.ts +8 -4
- package/src/routes/api/terminals/[id]/share/+server.ts +98 -0
- package/src/routes/api/terminals/[id]/share/auth/+server.ts +81 -0
- package/src/routes/api/terminals/[id]/share/status/+server.ts +11 -0
- package/src/routes/api/ws-ticket/+server.ts +26 -5
- package/src/routes/sos/+page.svelte +195 -0
- package/src/routes/sos/[id]/+page.svelte +677 -0
- package/src/routes/terminals/[id]/+page.svelte +184 -43
- package/build/client/_app/immutable/assets/0.NV8k8wxG.css.br +0 -0
- package/build/client/_app/immutable/assets/9.v5KA95xm.css +0 -1
- package/build/client/_app/immutable/assets/9.v5KA95xm.css.br +0 -0
- package/build/client/_app/immutable/assets/9.v5KA95xm.css.gz +0 -0
- package/build/client/_app/immutable/chunks/8lO1IL7u.js.br +0 -0
- package/build/client/_app/immutable/chunks/B9WQy_3X.js.br +0 -0
- package/build/client/_app/immutable/chunks/B9WQy_3X.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BRqaaL5D.js.br +0 -0
- package/build/client/_app/immutable/chunks/BRqaaL5D.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C5VOyQCG.js.br +0 -0
- package/build/client/_app/immutable/chunks/C5VOyQCG.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CR6bkGJW.js +0 -6
- package/build/client/_app/immutable/chunks/CR6bkGJW.js.br +0 -0
- package/build/client/_app/immutable/chunks/CR6bkGJW.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C_9BZILB.js.br +0 -0
- package/build/client/_app/immutable/chunks/C_9BZILB.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Cg3dlX05.js.br +0 -0
- package/build/client/_app/immutable/chunks/Cg3dlX05.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DJvX78LW.js.br +0 -0
- package/build/client/_app/immutable/chunks/DJvX78LW.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DYuMZGL5.js.br +0 -0
- package/build/client/_app/immutable/chunks/DYuMZGL5.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DZQMsHM5.js.br +0 -0
- package/build/client/_app/immutable/chunks/DZQMsHM5.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DZvnhU_8.js.br +0 -0
- package/build/client/_app/immutable/chunks/DZvnhU_8.js.gz +0 -0
- package/build/client/_app/immutable/chunks/nWG9RHyB.js +0 -3
- package/build/client/_app/immutable/chunks/nWG9RHyB.js.br +0 -0
- package/build/client/_app/immutable/chunks/nWG9RHyB.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.f46Ko1hu.js +0 -2
- package/build/client/_app/immutable/entry/app.f46Ko1hu.js.br +0 -0
- package/build/client/_app/immutable/entry/app.f46Ko1hu.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.BVDjNnXt.js +0 -1
- package/build/client/_app/immutable/entry/start.BVDjNnXt.js.br +0 -2
- package/build/client/_app/immutable/entry/start.BVDjNnXt.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.D_9EwVmq.js +0 -7
- package/build/client/_app/immutable/nodes/0.D_9EwVmq.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.D_9EwVmq.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.C4eFlqSB.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.C4eFlqSB.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.CdC092Za.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.CdC092Za.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.Dhf4ZWW0.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.Dhf4ZWW0.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.BSVqdrrD.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.BSVqdrrD.js.gz +0 -0
- package/build/client/_app/immutable/nodes/5.Cfj35gpY.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.Cfj35gpY.js.gz +0 -0
- package/build/client/_app/immutable/nodes/6.B3SEB_li.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.B3SEB_li.js.gz +0 -0
- package/build/client/_app/immutable/nodes/7.DV8cJ1lX.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.DV8cJ1lX.js.gz +0 -0
- package/build/client/_app/immutable/nodes/8.Bs362gyb.js.br +0 -0
- package/build/client/_app/immutable/nodes/8.Bs362gyb.js.gz +0 -0
- package/build/client/_app/immutable/nodes/9.Cf7_3uqT.js +0 -2
- package/build/client/_app/immutable/nodes/9.Cf7_3uqT.js.br +0 -0
- package/build/client/_app/immutable/nodes/9.Cf7_3uqT.js.gz +0 -0
- package/build/server/chunks/1-C4BOGoJY.js +0 -9
- package/build/server/chunks/6-D8xbnTSo.js +0 -9
- package/build/server/chunks/7-CkVK06S0.js +0 -9
- package/build/server/chunks/8-C8qVhrds.js +0 -9
- package/build/server/chunks/8-C8qVhrds.js.map +0 -1
- package/build/server/chunks/9-fL5zqN0T.js +0 -9
- package/build/server/chunks/9-fL5zqN0T.js.map +0 -1
- package/build/server/chunks/Button-B5dU-ntz.js.map +0 -1
- package/build/server/chunks/Icon-C7Ml3GX6.js.map +0 -1
- package/build/server/chunks/Input-CPGO0sbS.js.map +0 -1
- package/build/server/chunks/Pill-CcrtCejm.js.map +0 -1
- package/build/server/chunks/Shimmer-C5jkvGr1.js.map +0 -1
- package/build/server/chunks/_error.svelte-CSIxs-ab.js.map +0 -1
- package/build/server/chunks/_layout.svelte-noB4j-v2.js.map +0 -1
- package/build/server/chunks/_page.svelte-B6qyh-K-.js.map +0 -1
- package/build/server/chunks/_page.svelte-BUkm2304.js.map +0 -1
- package/build/server/chunks/_page.svelte-BV0XyYJZ.js.map +0 -1
- package/build/server/chunks/_page.svelte-BfB8maoc.js.map +0 -1
- package/build/server/chunks/_page.svelte-C60lAagP.js.map +0 -1
- package/build/server/chunks/_page.svelte-Dmg-RFCg.js.map +0 -1
- package/build/server/chunks/_page.svelte-DnTpPnPR.js.map +0 -1
- package/build/server/chunks/_page.svelte-DuzZr5dA.js.map +0 -1
- package/build/server/chunks/_server.ts-BA_uWcPw.js.map +0 -1
- package/build/server/chunks/_server.ts-Bjbr7glm.js.map +0 -1
- package/build/server/chunks/_server.ts-BrqaMMAa.js.map +0 -1
- package/build/server/chunks/_server.ts-Bu3s5hfv.js.map +0 -1
- package/build/server/chunks/_server.ts-CyjDrcZN.js.map +0 -1
- package/build/server/chunks/_server.ts-DZ5naqSL.js.map +0 -1
- package/build/server/chunks/_server.ts-DZP2lhaY.js.map +0 -1
- package/build/server/chunks/cache-Me3zUAaD.js.map +0 -1
- package/build/server/chunks/client2-DDP30_vY.js +0 -7
- package/build/server/chunks/events-handler-Dm1mNPQP.js +0 -20
- package/build/server/chunks/events-handler-Dm1mNPQP.js.map +0 -1
- package/build/server/chunks/pty-manager-DmNSCKAr.js.map +0 -1
- package/build/server/chunks/registry-Kcw2UCMv.js.map +0 -1
- package/build/server/chunks/root-xvQIR1Bt.js.map +0 -1
- package/build/server/chunks/stores-C-LqoonT.js.map +0 -1
- /package/build/client/_app/immutable/assets/{8.BhoBXADL.css → 10.BhoBXADL.css} +0 -0
- /package/build/client/_app/immutable/assets/{8.BhoBXADL.css.br → 10.BhoBXADL.css.br} +0 -0
- /package/build/client/_app/immutable/assets/{8.BhoBXADL.css.gz → 10.BhoBXADL.css.gz} +0 -0
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
TerminalPtyManagerLike as PtyManagerLike,
|
|
8
8
|
WireTerminalServerMessage as ServerMessage,
|
|
9
9
|
TerminalSignal,
|
|
10
|
+
TicketScope,
|
|
10
11
|
} from '$lib/types';
|
|
11
12
|
import type { WebSocket } from 'ws';
|
|
12
13
|
|
|
@@ -28,7 +29,11 @@ let _ptyManager: null | PtyManagerLike = null;
|
|
|
28
29
|
* Attaches the client to the terminal's viewer set, replays scrollback,
|
|
29
30
|
* and relays PTY I/O bidirectionally.
|
|
30
31
|
*/
|
|
31
|
-
export function handleTerminalConnection(
|
|
32
|
+
export function handleTerminalConnection(
|
|
33
|
+
ws: WebSocket,
|
|
34
|
+
terminalId: string,
|
|
35
|
+
scope?: TicketScope
|
|
36
|
+
): void {
|
|
32
37
|
// ── 1. Look up the terminal ──────────────────────────────────────
|
|
33
38
|
if (!_ptyManager) {
|
|
34
39
|
safeSend(ws, { message: 'PTY manager not initialised', type: 'error' });
|
|
@@ -62,6 +67,11 @@ export function handleTerminalConnection(ws: WebSocket, terminalId: string): voi
|
|
|
62
67
|
return; // Silently ignore malformed messages.
|
|
63
68
|
}
|
|
64
69
|
|
|
70
|
+
// View-only guests: every inbound frame type mutates the PTY — drop them all.
|
|
71
|
+
if (scope?.readOnly) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
65
75
|
// Don't allow input to exited terminals.
|
|
66
76
|
if (terminal.status === 'exited') {
|
|
67
77
|
safeSend(ws, { message: 'Terminal has exited', type: 'error' });
|
|
@@ -74,9 +84,18 @@ export function handleTerminalConnection(ws: WebSocket, terminalId: string): voi
|
|
|
74
84
|
terminal.pty.write(msg.data);
|
|
75
85
|
break;
|
|
76
86
|
|
|
77
|
-
case 'resize':
|
|
87
|
+
case 'resize': {
|
|
78
88
|
terminal.pty.resize(msg.cols, msg.rows);
|
|
89
|
+
// Broadcast the new PTY size to the other attached clients so
|
|
90
|
+
// view-only guests can follow the owner's terminal dimensions.
|
|
91
|
+
const resizeMsg: ServerMessage = { cols: msg.cols, rows: msg.rows, type: 'resize' };
|
|
92
|
+
for (const client of terminal.clients) {
|
|
93
|
+
if (client !== ws) {
|
|
94
|
+
safeSend(client, resizeMsg);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
79
97
|
break;
|
|
98
|
+
}
|
|
80
99
|
|
|
81
100
|
case 'signal': {
|
|
82
101
|
if (msg.signal === 'SIGINT') {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// This avoids putting the long-lived API_KEY in WebSocket URL query parameters,
|
|
6
6
|
// which would appear in proxy logs, Cloudflare access logs, and browser history.
|
|
7
7
|
|
|
8
|
-
import type { Ticket } from '$lib/types';
|
|
8
|
+
import type { Ticket, TicketScope } from '$lib/types';
|
|
9
9
|
|
|
10
10
|
import { randomBytes } from 'crypto';
|
|
11
11
|
|
|
@@ -21,32 +21,40 @@ const tickets: Map<string, Ticket> =
|
|
|
21
21
|
/**
|
|
22
22
|
* Generate a new single-use ticket (32-byte hex string).
|
|
23
23
|
* The ticket is valid for 30 seconds and can only be consumed once.
|
|
24
|
+
* An optional scope restricts the ticket to one terminal's channels
|
|
25
|
+
* (and optionally to read-only access).
|
|
24
26
|
*/
|
|
25
|
-
export function generateTicket(): string {
|
|
27
|
+
export function generateTicket(scope?: TicketScope): string {
|
|
26
28
|
const ticket = randomBytes(32).toString('hex');
|
|
27
|
-
tickets.set(ticket, {
|
|
29
|
+
tickets.set(ticket, {
|
|
30
|
+
createdAt: Date.now(),
|
|
31
|
+
readOnly: scope?.readOnly ?? null,
|
|
32
|
+
terminalId: scope?.terminalId ?? null,
|
|
33
|
+
used: false,
|
|
34
|
+
});
|
|
28
35
|
return ticket;
|
|
29
36
|
}
|
|
30
37
|
|
|
31
38
|
/**
|
|
32
39
|
* Validate and consume a ticket.
|
|
33
|
-
* Returns
|
|
34
|
-
* A valid ticket is marked as used
|
|
40
|
+
* Returns the consumed Ticket (including any scope) if it is valid, not yet
|
|
41
|
+
* used, and not expired; otherwise null. A valid ticket is marked as used
|
|
42
|
+
* (single-use) and cannot be reused.
|
|
35
43
|
*/
|
|
36
|
-
export function validateTicket(ticket: null | string):
|
|
44
|
+
export function validateTicket(ticket: null | string): null | Ticket {
|
|
37
45
|
if (!ticket) {
|
|
38
|
-
return
|
|
46
|
+
return null;
|
|
39
47
|
}
|
|
40
48
|
const entry = tickets.get(ticket);
|
|
41
49
|
if (!entry || entry.used) {
|
|
42
|
-
return
|
|
50
|
+
return null;
|
|
43
51
|
}
|
|
44
52
|
if (Date.now() - entry.createdAt > 30_000) {
|
|
45
53
|
tickets.delete(ticket);
|
|
46
|
-
return
|
|
54
|
+
return null;
|
|
47
55
|
}
|
|
48
56
|
entry.used = true;
|
|
49
|
-
return
|
|
57
|
+
return entry;
|
|
50
58
|
}
|
|
51
59
|
|
|
52
60
|
// Cleanup expired tickets every 30 seconds (matches ticket lifetime).
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type SessionSource, decodeSessionSource } from './index';
|
|
1
|
+
import { type ShareMode, decodeShareMode, type SessionSource, decodeSessionSource } from './index';
|
|
2
2
|
import {
|
|
3
3
|
isJSON,
|
|
4
4
|
decodeString,
|
|
@@ -307,6 +307,24 @@ export type TerminalDetailView = {
|
|
|
307
307
|
* @memberof TerminalDetailView
|
|
308
308
|
*/
|
|
309
309
|
sessionWs: string;
|
|
310
|
+
/**
|
|
311
|
+
* @description Current PTY width in columns (for fixed-size guest rendering)
|
|
312
|
+
* @type { number }
|
|
313
|
+
* @memberof TerminalDetailView
|
|
314
|
+
*/
|
|
315
|
+
cols: number | null;
|
|
316
|
+
/**
|
|
317
|
+
* @description Current PTY height in rows (for fixed-size guest rendering)
|
|
318
|
+
* @type { number }
|
|
319
|
+
* @memberof TerminalDetailView
|
|
320
|
+
*/
|
|
321
|
+
rows: number | null;
|
|
322
|
+
/**
|
|
323
|
+
* @description Present when fetched with a guest share token — the guest's access mode
|
|
324
|
+
* @type { ShareMode }
|
|
325
|
+
* @memberof TerminalDetailView
|
|
326
|
+
*/
|
|
327
|
+
shareMode: ShareMode | null;
|
|
310
328
|
};
|
|
311
329
|
|
|
312
330
|
export function decodeTerminalDetailView(rawInput: unknown): TerminalDetailView | null {
|
|
@@ -325,6 +343,9 @@ export function decodeTerminalDetailView(rawInput: unknown): TerminalDetailView
|
|
|
325
343
|
const decodedTimestamp = decodeString(rawInput['timestamp']);
|
|
326
344
|
const decodedWs = decodeString(rawInput['ws']);
|
|
327
345
|
const decodedSessionWs = decodeString(rawInput['sessionWs']);
|
|
346
|
+
const decodedCols = decodeNumber(rawInput['cols']);
|
|
347
|
+
const decodedRows = decodeNumber(rawInput['rows']);
|
|
348
|
+
const decodedShareMode = decodeShareMode(rawInput['shareMode']);
|
|
328
349
|
|
|
329
350
|
if (
|
|
330
351
|
decodedId === null ||
|
|
@@ -355,6 +376,9 @@ export function decodeTerminalDetailView(rawInput: unknown): TerminalDetailView
|
|
|
355
376
|
timestamp: decodedTimestamp,
|
|
356
377
|
ws: decodedWs,
|
|
357
378
|
sessionWs: decodedSessionWs,
|
|
379
|
+
cols: decodedCols,
|
|
380
|
+
rows: decodedRows,
|
|
381
|
+
shareMode: decodedShareMode,
|
|
358
382
|
};
|
|
359
383
|
}
|
|
360
384
|
return null;
|
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isJSON,
|
|
3
|
+
decodeString,
|
|
4
|
+
_decodeString,
|
|
5
|
+
decodeNumber,
|
|
6
|
+
_decodeNumber,
|
|
7
|
+
decodeBoolean,
|
|
8
|
+
_decodeBoolean,
|
|
9
|
+
} from 'type-decoder';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @type { ShareMode }
|
|
13
|
+
* @description What a share guest may do — watch only, or full input control
|
|
14
|
+
*/
|
|
15
|
+
export type ShareMode = 'view' | 'control';
|
|
16
|
+
|
|
17
|
+
export function decodeShareMode(rawInput: unknown): ShareMode | null {
|
|
18
|
+
switch (rawInput) {
|
|
19
|
+
case 'view':
|
|
20
|
+
case 'control':
|
|
21
|
+
return rawInput;
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function _decodeShareMode(rawInput: unknown): ShareMode | undefined {
|
|
27
|
+
switch (rawInput) {
|
|
28
|
+
case 'view':
|
|
29
|
+
case 'control':
|
|
30
|
+
return rawInput;
|
|
31
|
+
}
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @type { AccessLevel }
|
|
37
|
+
* @description Authorization level resolved for a terminal-scoped request
|
|
38
|
+
*/
|
|
39
|
+
export type AccessLevel = 'owner' | 'guest';
|
|
40
|
+
|
|
41
|
+
export function decodeAccessLevel(rawInput: unknown): AccessLevel | null {
|
|
42
|
+
switch (rawInput) {
|
|
43
|
+
case 'owner':
|
|
44
|
+
case 'guest':
|
|
45
|
+
return rawInput;
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function _decodeAccessLevel(rawInput: unknown): AccessLevel | undefined {
|
|
51
|
+
switch (rawInput) {
|
|
52
|
+
case 'owner':
|
|
53
|
+
case 'guest':
|
|
54
|
+
return rawInput;
|
|
55
|
+
}
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @type { AccessContext }
|
|
61
|
+
* @description Resolved authorization for a terminal-scoped API request
|
|
62
|
+
*/
|
|
63
|
+
export type AccessContext = {
|
|
64
|
+
/**
|
|
65
|
+
* @description owner (API key) or guest (share session token)
|
|
66
|
+
* @type { AccessLevel }
|
|
67
|
+
* @memberof AccessContext
|
|
68
|
+
*/
|
|
69
|
+
level: AccessLevel;
|
|
70
|
+
/**
|
|
71
|
+
* @description Guest access mode (present only when level is guest)
|
|
72
|
+
* @type { ShareMode }
|
|
73
|
+
* @memberof AccessContext
|
|
74
|
+
*/
|
|
75
|
+
mode: ShareMode | null;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export function decodeAccessContext(rawInput: unknown): AccessContext | null {
|
|
79
|
+
if (isJSON(rawInput)) {
|
|
80
|
+
const decodedLevel = decodeAccessLevel(rawInput['level']);
|
|
81
|
+
const decodedMode = decodeShareMode(rawInput['mode']);
|
|
82
|
+
|
|
83
|
+
if (decodedLevel === null) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
level: decodedLevel,
|
|
89
|
+
mode: decodedMode,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @type { TerminalShareRecord }
|
|
97
|
+
* @description Persisted share configuration for one terminal (terminal_shares table)
|
|
98
|
+
*/
|
|
99
|
+
export type TerminalShareRecord = {
|
|
100
|
+
/**
|
|
101
|
+
* @description Terminal this share belongs to (primary key)
|
|
102
|
+
* @type { string }
|
|
103
|
+
* @memberof TerminalShareRecord
|
|
104
|
+
*/
|
|
105
|
+
terminalId: string;
|
|
106
|
+
/**
|
|
107
|
+
* @description scrypt:<salt-hex>:<hash-hex> password hash
|
|
108
|
+
* @type { string }
|
|
109
|
+
* @memberof TerminalShareRecord
|
|
110
|
+
*/
|
|
111
|
+
passwordHash: string;
|
|
112
|
+
/**
|
|
113
|
+
* @description Access mode granted to guests
|
|
114
|
+
* @type { ShareMode }
|
|
115
|
+
* @memberof TerminalShareRecord
|
|
116
|
+
*/
|
|
117
|
+
mode: ShareMode;
|
|
118
|
+
/**
|
|
119
|
+
* @description Unix timestamp (ms) when the share was created
|
|
120
|
+
* @type { number }
|
|
121
|
+
* @memberof TerminalShareRecord
|
|
122
|
+
*/
|
|
123
|
+
createdAt: number;
|
|
124
|
+
/**
|
|
125
|
+
* @description Unix timestamp (ms) when the share was last updated
|
|
126
|
+
* @type { number }
|
|
127
|
+
* @memberof TerminalShareRecord
|
|
128
|
+
*/
|
|
129
|
+
updatedAt: number;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export function decodeTerminalShareRecord(rawInput: unknown): TerminalShareRecord | null {
|
|
133
|
+
if (isJSON(rawInput)) {
|
|
134
|
+
const decodedTerminalId = decodeString(rawInput['terminalId']);
|
|
135
|
+
const decodedPasswordHash = decodeString(rawInput['passwordHash']);
|
|
136
|
+
const decodedMode = decodeShareMode(rawInput['mode']);
|
|
137
|
+
const decodedCreatedAt = decodeNumber(rawInput['createdAt']);
|
|
138
|
+
const decodedUpdatedAt = decodeNumber(rawInput['updatedAt']);
|
|
139
|
+
|
|
140
|
+
if (
|
|
141
|
+
decodedTerminalId === null ||
|
|
142
|
+
decodedPasswordHash === null ||
|
|
143
|
+
decodedMode === null ||
|
|
144
|
+
decodedCreatedAt === null ||
|
|
145
|
+
decodedUpdatedAt === null
|
|
146
|
+
) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
terminalId: decodedTerminalId,
|
|
152
|
+
passwordHash: decodedPasswordHash,
|
|
153
|
+
mode: decodedMode,
|
|
154
|
+
createdAt: decodedCreatedAt,
|
|
155
|
+
updatedAt: decodedUpdatedAt,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* @type { ShareSessionRecord }
|
|
163
|
+
* @description Persisted guest session (share_sessions table); token stored as sha256 hash
|
|
164
|
+
*/
|
|
165
|
+
export type ShareSessionRecord = {
|
|
166
|
+
/**
|
|
167
|
+
* @description sha256 hex of the guest bearer token (primary key)
|
|
168
|
+
* @type { string }
|
|
169
|
+
* @memberof ShareSessionRecord
|
|
170
|
+
*/
|
|
171
|
+
tokenHash: string;
|
|
172
|
+
/**
|
|
173
|
+
* @description Terminal the session grants access to
|
|
174
|
+
* @type { string }
|
|
175
|
+
* @memberof ShareSessionRecord
|
|
176
|
+
*/
|
|
177
|
+
terminalId: string;
|
|
178
|
+
/**
|
|
179
|
+
* @description Unix timestamp (ms) when the session was created
|
|
180
|
+
* @type { number }
|
|
181
|
+
* @memberof ShareSessionRecord
|
|
182
|
+
*/
|
|
183
|
+
createdAt: number;
|
|
184
|
+
/**
|
|
185
|
+
* @description Unix timestamp (ms) when the session expires (created + 7 days)
|
|
186
|
+
* @type { number }
|
|
187
|
+
* @memberof ShareSessionRecord
|
|
188
|
+
*/
|
|
189
|
+
expiresAt: number;
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
export function decodeShareSessionRecord(rawInput: unknown): ShareSessionRecord | null {
|
|
193
|
+
if (isJSON(rawInput)) {
|
|
194
|
+
const decodedTokenHash = decodeString(rawInput['tokenHash']);
|
|
195
|
+
const decodedTerminalId = decodeString(rawInput['terminalId']);
|
|
196
|
+
const decodedCreatedAt = decodeNumber(rawInput['createdAt']);
|
|
197
|
+
const decodedExpiresAt = decodeNumber(rawInput['expiresAt']);
|
|
198
|
+
|
|
199
|
+
if (
|
|
200
|
+
decodedTokenHash === null ||
|
|
201
|
+
decodedTerminalId === null ||
|
|
202
|
+
decodedCreatedAt === null ||
|
|
203
|
+
decodedExpiresAt === null
|
|
204
|
+
) {
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
tokenHash: decodedTokenHash,
|
|
210
|
+
terminalId: decodedTerminalId,
|
|
211
|
+
createdAt: decodedCreatedAt,
|
|
212
|
+
expiresAt: decodedExpiresAt,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* @type { ShareInfoResponse }
|
|
220
|
+
* @description Owner view of a terminal's share state (GET /api/terminals/[id]/share)
|
|
221
|
+
*/
|
|
222
|
+
export type ShareInfoResponse = {
|
|
223
|
+
/**
|
|
224
|
+
* @description Whether sharing is currently enabled for this terminal
|
|
225
|
+
* @type { boolean }
|
|
226
|
+
* @memberof ShareInfoResponse
|
|
227
|
+
*/
|
|
228
|
+
active: boolean;
|
|
229
|
+
/**
|
|
230
|
+
* @description Current access mode (present when active)
|
|
231
|
+
* @type { ShareMode }
|
|
232
|
+
* @memberof ShareInfoResponse
|
|
233
|
+
*/
|
|
234
|
+
mode: ShareMode | null;
|
|
235
|
+
/**
|
|
236
|
+
* @description Unix timestamp (ms) when the share was created (present when active)
|
|
237
|
+
* @type { number }
|
|
238
|
+
* @memberof ShareInfoResponse
|
|
239
|
+
*/
|
|
240
|
+
createdAt: number | null;
|
|
241
|
+
/**
|
|
242
|
+
* @description Unix timestamp (ms) when the share was last updated (present when active)
|
|
243
|
+
* @type { number }
|
|
244
|
+
* @memberof ShareInfoResponse
|
|
245
|
+
*/
|
|
246
|
+
updatedAt: number | null;
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
export function decodeShareInfoResponse(rawInput: unknown): ShareInfoResponse | null {
|
|
250
|
+
if (isJSON(rawInput)) {
|
|
251
|
+
const decodedActive = decodeBoolean(rawInput['active']);
|
|
252
|
+
const decodedMode = decodeShareMode(rawInput['mode']);
|
|
253
|
+
const decodedCreatedAt = decodeNumber(rawInput['createdAt']);
|
|
254
|
+
const decodedUpdatedAt = decodeNumber(rawInput['updatedAt']);
|
|
255
|
+
|
|
256
|
+
if (decodedActive === null) {
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return {
|
|
261
|
+
active: decodedActive,
|
|
262
|
+
mode: decodedMode,
|
|
263
|
+
createdAt: decodedCreatedAt,
|
|
264
|
+
updatedAt: decodedUpdatedAt,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* @type { ShareStatusResponse }
|
|
272
|
+
* @description Public probe response (GET /api/terminals/[id]/share/status)
|
|
273
|
+
*/
|
|
274
|
+
export type ShareStatusResponse = {
|
|
275
|
+
/**
|
|
276
|
+
* @description Whether a share exists for this terminal
|
|
277
|
+
* @type { boolean }
|
|
278
|
+
* @memberof ShareStatusResponse
|
|
279
|
+
*/
|
|
280
|
+
shared: boolean;
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
export function decodeShareStatusResponse(rawInput: unknown): ShareStatusResponse | null {
|
|
284
|
+
if (isJSON(rawInput)) {
|
|
285
|
+
const decodedShared = decodeBoolean(rawInput['shared']);
|
|
286
|
+
|
|
287
|
+
if (decodedShared === null) {
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return {
|
|
292
|
+
shared: decodedShared,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* @type { ShareAuthRequest }
|
|
300
|
+
* @description Guest password exchange request (POST /api/terminals/[id]/share/auth)
|
|
301
|
+
*/
|
|
302
|
+
export type ShareAuthRequest = {
|
|
303
|
+
/**
|
|
304
|
+
* @description The share password
|
|
305
|
+
* @type { string }
|
|
306
|
+
* @memberof ShareAuthRequest
|
|
307
|
+
*/
|
|
308
|
+
password: string;
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
export function decodeShareAuthRequest(rawInput: unknown): ShareAuthRequest | null {
|
|
312
|
+
if (isJSON(rawInput)) {
|
|
313
|
+
const decodedPassword = decodeString(rawInput['password']);
|
|
314
|
+
|
|
315
|
+
if (decodedPassword === null) {
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
return {
|
|
320
|
+
password: decodedPassword,
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
return null;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* @type { ShareAuthResponse }
|
|
328
|
+
* @description Guest session issued after successful password exchange
|
|
329
|
+
*/
|
|
330
|
+
export type ShareAuthResponse = {
|
|
331
|
+
/**
|
|
332
|
+
* @description Guest bearer token (64-char hex, shown once)
|
|
333
|
+
* @type { string }
|
|
334
|
+
* @memberof ShareAuthResponse
|
|
335
|
+
*/
|
|
336
|
+
token: string;
|
|
337
|
+
/**
|
|
338
|
+
* @description Access mode granted by this session
|
|
339
|
+
* @type { ShareMode }
|
|
340
|
+
* @memberof ShareAuthResponse
|
|
341
|
+
*/
|
|
342
|
+
mode: ShareMode;
|
|
343
|
+
/**
|
|
344
|
+
* @description Unix timestamp (ms) when this session expires
|
|
345
|
+
* @type { number }
|
|
346
|
+
* @memberof ShareAuthResponse
|
|
347
|
+
*/
|
|
348
|
+
expiresAt: number;
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
export function decodeShareAuthResponse(rawInput: unknown): ShareAuthResponse | null {
|
|
352
|
+
if (isJSON(rawInput)) {
|
|
353
|
+
const decodedToken = decodeString(rawInput['token']);
|
|
354
|
+
const decodedMode = decodeShareMode(rawInput['mode']);
|
|
355
|
+
const decodedExpiresAt = decodeNumber(rawInput['expiresAt']);
|
|
356
|
+
|
|
357
|
+
if (decodedToken === null || decodedMode === null || decodedExpiresAt === null) {
|
|
358
|
+
return null;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return {
|
|
362
|
+
token: decodedToken,
|
|
363
|
+
mode: decodedMode,
|
|
364
|
+
expiresAt: decodedExpiresAt,
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
return null;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* @type { ShareConfigRequest }
|
|
372
|
+
* @description Owner create/update share request (PUT /api/terminals/[id]/share)
|
|
373
|
+
*/
|
|
374
|
+
export type ShareConfigRequest = {
|
|
375
|
+
/**
|
|
376
|
+
* @description New share password (min 6 chars; required on create, optional on update)
|
|
377
|
+
* @type { string }
|
|
378
|
+
* @memberof ShareConfigRequest
|
|
379
|
+
*/
|
|
380
|
+
password: string | null;
|
|
381
|
+
/**
|
|
382
|
+
* @description Access mode to grant guests
|
|
383
|
+
* @type { ShareMode }
|
|
384
|
+
* @memberof ShareConfigRequest
|
|
385
|
+
*/
|
|
386
|
+
mode: ShareMode;
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
export function decodeShareConfigRequest(rawInput: unknown): ShareConfigRequest | null {
|
|
390
|
+
if (isJSON(rawInput)) {
|
|
391
|
+
const decodedPassword = decodeString(rawInput['password']);
|
|
392
|
+
const decodedMode = decodeShareMode(rawInput['mode']);
|
|
393
|
+
|
|
394
|
+
if (decodedMode === null) {
|
|
395
|
+
return null;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
return {
|
|
399
|
+
password: decodedPassword,
|
|
400
|
+
mode: decodedMode,
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
return null;
|
|
404
|
+
}
|
|
@@ -435,7 +435,8 @@ export type TerminalServerMessage =
|
|
|
435
435
|
| CTerminalServerMessageTerminalOutputDroppedMessage
|
|
436
436
|
| CTerminalServerMessageTerminalScrollbackMessage
|
|
437
437
|
| CTerminalServerMessageTerminalExitMessage
|
|
438
|
-
| CTerminalServerMessageTerminalErrorMessage
|
|
438
|
+
| CTerminalServerMessageTerminalErrorMessage
|
|
439
|
+
| CTerminalServerMessageTerminalResizeMessage;
|
|
439
440
|
|
|
440
441
|
export function decodeTerminalServerMessage(rawInput: unknown): TerminalServerMessage | null {
|
|
441
442
|
const result: TerminalServerMessage | null =
|
|
@@ -443,7 +444,8 @@ export function decodeTerminalServerMessage(rawInput: unknown): TerminalServerMe
|
|
|
443
444
|
decodeCTerminalServerMessageTerminalOutputDroppedMessage(rawInput) ??
|
|
444
445
|
decodeCTerminalServerMessageTerminalScrollbackMessage(rawInput) ??
|
|
445
446
|
decodeCTerminalServerMessageTerminalExitMessage(rawInput) ??
|
|
446
|
-
decodeCTerminalServerMessageTerminalErrorMessage(rawInput)
|
|
447
|
+
decodeCTerminalServerMessageTerminalErrorMessage(rawInput) ??
|
|
448
|
+
decodeCTerminalServerMessageTerminalResizeMessage(rawInput);
|
|
447
449
|
|
|
448
450
|
return result;
|
|
449
451
|
}
|
|
@@ -533,6 +535,23 @@ export function decodeCTerminalServerMessageTerminalErrorMessage(
|
|
|
533
535
|
return new CTerminalServerMessageTerminalErrorMessage(result);
|
|
534
536
|
}
|
|
535
537
|
|
|
538
|
+
export class CTerminalServerMessageTerminalResizeMessage {
|
|
539
|
+
data: TerminalResizeMessage;
|
|
540
|
+
constructor(data: TerminalResizeMessage) {
|
|
541
|
+
this.data = data;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
export function decodeCTerminalServerMessageTerminalResizeMessage(
|
|
546
|
+
rawInput: unknown
|
|
547
|
+
): CTerminalServerMessageTerminalResizeMessage | null {
|
|
548
|
+
const result = decodeTerminalResizeMessage(rawInput);
|
|
549
|
+
if (result === null) {
|
|
550
|
+
return null;
|
|
551
|
+
}
|
|
552
|
+
return new CTerminalServerMessageTerminalResizeMessage(result);
|
|
553
|
+
}
|
|
554
|
+
|
|
536
555
|
/**
|
|
537
556
|
* @type { TextContentBlock }
|
|
538
557
|
* @description Content block in the live 'message' payload
|
|
@@ -2326,12 +2345,26 @@ export type Ticket = {
|
|
|
2326
2345
|
* @memberof Ticket
|
|
2327
2346
|
*/
|
|
2328
2347
|
used: boolean;
|
|
2348
|
+
/**
|
|
2349
|
+
* @description When set, the ticket may only open WS channels for this terminal
|
|
2350
|
+
* @type { string }
|
|
2351
|
+
* @memberof Ticket
|
|
2352
|
+
*/
|
|
2353
|
+
terminalId: string | null;
|
|
2354
|
+
/**
|
|
2355
|
+
* @description When true, input/resize/signal/send-input/cancel frames are dropped
|
|
2356
|
+
* @type { boolean }
|
|
2357
|
+
* @memberof Ticket
|
|
2358
|
+
*/
|
|
2359
|
+
readOnly: boolean | null;
|
|
2329
2360
|
};
|
|
2330
2361
|
|
|
2331
2362
|
export function decodeTicket(rawInput: unknown): Ticket | null {
|
|
2332
2363
|
if (isJSON(rawInput)) {
|
|
2333
2364
|
const decodedCreatedAt = decodeNumber(rawInput['createdAt']);
|
|
2334
2365
|
const decodedUsed = decodeBoolean(rawInput['used']);
|
|
2366
|
+
const decodedTerminalId = decodeString(rawInput['terminalId']);
|
|
2367
|
+
const decodedReadOnly = decodeBoolean(rawInput['readOnly']);
|
|
2335
2368
|
|
|
2336
2369
|
if (decodedCreatedAt === null || decodedUsed === null) {
|
|
2337
2370
|
return null;
|
|
@@ -2340,6 +2373,44 @@ export function decodeTicket(rawInput: unknown): Ticket | null {
|
|
|
2340
2373
|
return {
|
|
2341
2374
|
createdAt: decodedCreatedAt,
|
|
2342
2375
|
used: decodedUsed,
|
|
2376
|
+
terminalId: decodedTerminalId,
|
|
2377
|
+
readOnly: decodedReadOnly,
|
|
2378
|
+
};
|
|
2379
|
+
}
|
|
2380
|
+
return null;
|
|
2381
|
+
}
|
|
2382
|
+
|
|
2383
|
+
/**
|
|
2384
|
+
* @type { TicketScope }
|
|
2385
|
+
* @description Scope restriction carried by a guest WebSocket ticket
|
|
2386
|
+
*/
|
|
2387
|
+
export type TicketScope = {
|
|
2388
|
+
/**
|
|
2389
|
+
* @description Only WS channels for this terminal may be opened
|
|
2390
|
+
* @type { string }
|
|
2391
|
+
* @memberof TicketScope
|
|
2392
|
+
*/
|
|
2393
|
+
terminalId: string;
|
|
2394
|
+
/**
|
|
2395
|
+
* @description Whether the connection is view-only (input frames dropped)
|
|
2396
|
+
* @type { boolean }
|
|
2397
|
+
* @memberof TicketScope
|
|
2398
|
+
*/
|
|
2399
|
+
readOnly: boolean;
|
|
2400
|
+
};
|
|
2401
|
+
|
|
2402
|
+
export function decodeTicketScope(rawInput: unknown): TicketScope | null {
|
|
2403
|
+
if (isJSON(rawInput)) {
|
|
2404
|
+
const decodedTerminalId = decodeString(rawInput['terminalId']);
|
|
2405
|
+
const decodedReadOnly = decodeBoolean(rawInput['readOnly']);
|
|
2406
|
+
|
|
2407
|
+
if (decodedTerminalId === null || decodedReadOnly === null) {
|
|
2408
|
+
return null;
|
|
2409
|
+
}
|
|
2410
|
+
|
|
2411
|
+
return {
|
|
2412
|
+
terminalId: decodedTerminalId,
|
|
2413
|
+
readOnly: decodedReadOnly,
|
|
2343
2414
|
};
|
|
2344
2415
|
}
|
|
2345
2416
|
return null;
|
package/src/lib/types/index.ts
CHANGED
|
@@ -12,8 +12,8 @@ export type * from './gemini';
|
|
|
12
12
|
export * from './generated';
|
|
13
13
|
export type * from './neurolink';
|
|
14
14
|
export type * from './server';
|
|
15
|
-
|
|
16
15
|
export type * from './sessions';
|
|
16
|
+
|
|
17
17
|
// Explicit re-exports to resolve conflicts between generated types and the
|
|
18
18
|
// hand-written sessions.ts versions. The generated Sessions module exports
|
|
19
19
|
// wrapper-class variants (CMessagePartTextPart, etc.) with `type: string`
|
|
@@ -27,5 +27,6 @@ export type {
|
|
|
27
27
|
ToolResultPart,
|
|
28
28
|
ToolUsePart,
|
|
29
29
|
} from './sessions';
|
|
30
|
+
export type * from './sos';
|
|
30
31
|
export type * from './terminal-client';
|
|
31
32
|
export type * from './ws';
|